高层 Api,主题数据未使用 RestSharp 发布

Highrise Api, Subject data not posting with RestSharp

我正在尝试使用 Highrise Api with the .NET 4.5 wrapper by scottschluer 以便 post 一个新人加入我们的 Highrise 帐户以及他们输入的任何自定义数据。

我 运行 遇到的问题是自定义数据。人物对象 post 编辑得很好,但主题数据字段未包含在 post.

我确实遇到过这个 post:。看起来缺少的东西是 subject_datas 字段中的 type="array" 属性。我通过使用我尝试 post 的对象的序列化值手动创建请求来测试这个假设。此测试的结果是成功 post 到服务器并填充了所有自定义数据字段。

我已经尝试从包装程序集扩展 classes 以将缺少的属性添加到列表中,但这似乎仍然不起作用。 Person 对象有一个 属性 用于 SubjectData 对象列表,我在子 class 中覆盖了 属性 以使用自定义 class 代替。这样我就可以添加一个 属性 用作属性。这个习惯 class 似乎仍然没有用。

查看 RestSharp's XmlSerializer 的代码后,它似乎只会在该对象实现 IList 时添加项目列表。那不是问题,我能够让它工作,但代码似乎不允许向列表元素添加属性。它只查看列表的子项 class 并忽略对象的任何其他属性。

所以我的问题是:

是否可以将属性应用于 RestSharp 中的列表 属性,或者是否有另一种方法可以将 type="array" 属性添加到 data_subjects xml 之前的节点请求已发送?

我最终通过创建一个新请求 class 解决了这个问题,该请求将使用自定义 XmlSerializer 创建一个 RestRequest。

然后我扩展了 Person class 并将 属性 隐藏在自定义列表对象 属性

后面

之前:

[SerializeAs(Name = "subject_datas")]
public List<SubjectData> SubjectDatas { get; set; }

之后:

[SerializeAs(Name = "subject_datas")]
public new SubjectDataList SubjectDatas { get; set; }

SubjectDataList class 只是 List<SubjectData>.

的包装

SubjectDataList 实现了一个名为 ISerializeList<SubjectData> 的接口 定义为:

interface ISerializeList : IEnumerable {}
interface ISerializeList<T> :IEnumerable<T>, ISerializeList {}

SubjectDataList 也有一个类型 属性 将类型属性渲染到其余请求的 subjectdatas 节点上。

[SerializeAs(Name = "type", Attribute = true)]
public string Type { get; set; } = "array";

然后我制作了一个名为 XmlListSerializer 的 class,它实现了 ISerializer。我复制了 XmlSerializer 的实现,但做了一些修改。在 Map 方法中,有一部分检查变量 rawValue 是否为 IList。我稍微更改了这部分,并为我的 XmlListSerializer class.

添加了一个子句

现在看起来像这样:

if (propType.IsPrimitive || propType.IsValueType || propType == typeof(string)) {
    //...
} else if (rawValue is IList) {
    ProcessIList((IList) rawValue, element);
} else if (rawValue is ISerializeList) {
    ProcessISerializeList((ISerializeList) rawValue, element);
} else {
    Map(element, rawValue);
}

其中 ProcessIListProcessISerializeList 定义为:

private void ProcessIList(IList list, XElement element) {
    ProcessIEnumerable(list, element);
}
private void ProcessISerializeList(ISerializeList list, XElement element) {
    ProcessIEnumerable(list, element);
    Map(element, list);
}
private void ProcessIEnumerable(IEnumerable list, XElement element) {
    var itemTypeName = "";
    foreach (var item in list) {
        if (itemTypeName == "") {
            var type = item.GetType();
            var setting = type.GetAttribute<SerializeAsAttribute>();

            itemTypeName = setting != null && setting.Name.HasValue() ? setting.Name : type.Name;
        }

        var instance = new XElement(itemTypeName.AsNamespaced(Namespace));

        Map(instance, item);
        element.Add(instance);
    }
}

我希望这个答案能够帮助遇到此问题的其他人。