【问题标题】:Highrise Api, Subject data not posting with RestSharpHighrise Api,主题数据未使用 RestSharp 发布
【发布时间】:2018-06-09 20:48:40
【问题描述】:

我正在尝试使用 Highrise Api.NET 4.5 wrapper by scottschluer 来向我们的 Highrise 帐户发布一个新人员以及他们输入的任何自定义数据。

我遇到的问题是自定义数据。个人对象可以正常发布,但主题数据字段未包含在帖子中。

我确实遇到过这个帖子:Highrise Custom Fields。看起来缺少的是 subject_datas 字段中的 type="array" 属性。我通过使用我试图发布的对象的序列化值手动创建请求来测试这个假设。该测试的结果是成功发布到服务器,并填写了所有自定义数据字段。

我尝试从包装程序集扩展类以将缺少的属性添加到列表中,但这似乎仍然不起作用。 Person 对象具有 SubjectData 对象列表的属性,我在子类中覆盖了该属性以使用自定义类。这样我可以添加一个属性作为属性。这个自定义类似乎仍然不起作用。

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

所以我的问题是:

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

【问题讨论】:

    标签: c# restsharp highrise


    【解决方案1】:

    我最终自己解决了这个问题,方法是创建一个新的请求类,该类将使用自定义 XmlSerializer 创建一个 RestRequest。

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

    之前:

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

    之后:

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

    SubjectDataList 类只是 List&lt;SubjectData&gt; 的包装器。

    SubjectDataList 实现了一个名为ISerializeList&lt;SubjectData&gt; 的接口 定义为:

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

    SubjectDataList 还有一个 type 属性,用于将 type 属性渲染到 rest 请求的 subjectdatas 节点上。

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

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

    所以它现在看起来像这样:

    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);
        }
    }
    

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

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2019-08-14
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      相关资源
      最近更新 更多