我正在尝试将Highrise Api与.NET 4.5 wrapper by scottschluer一起使用,以便将新人发布到我们的Highrise帐户以及他们输入的任何自定义数据。
我遇到的问题是自定义数据。人物对象发布得很好,但主题数据字段未包含在帖子中。
我确实遇到过这篇文章:Highrise Custom Fields。看起来缺少的是type="array"
字段中的subject_datas
属性。我通过使用我试图发布的对象的序列化值手动创建请求来测试此假设。此测试的结果是成功发布到服务器,并填充了所有自定义数据字段。
我已经尝试从包装程序集扩展类以将该缺少的属性添加到列表中,但这似乎仍然无效。 Person对象具有SubjectData对象List的属性,我在子类中覆盖该属性以改为使用自定义类。这样我就可以添加一个属性来用作属性。这个自定义类似乎仍然不起作用。
在查看RestSharp's XmlSerializer的代码之后,它似乎只会在该对象实现IList时添加项列表。这不是问题,我能够让它工作,但代码似乎不允许添加属性到列表元素。它只查看列表类的子节点,并忽略该对象上的任何其他属性。
所以我的问题是:
是否可以将属性应用于RestSharp中的list属性,或者在发送请求之前是否有另一种方法将type="array"
属性添加到data_subjects
xml节点?
答案 0 :(得分: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<SubjectData>
的包装。
SubjectDataList
实现了一个名为ISerializeList<SubjectData>
的接口
其定义为:
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);
}
将ProcessIList
和ProcessISerializeList
定义为:
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);
}
}
我希望这个答案能够帮助其他人解决这个问题。