我最终通过创建一个新的请求类自己解决了这个问题,该类将使用自定义 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
which implements的类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);
}
}
我希望这个答案能够帮助其他遇到此问题的人。