我有一个C#WCF REST服务,允许添加书签,方法是发送带有以XML格式序列化的书签的HTTP POST请求。我已经为服务指定了操作契约,它获取了xml并自动为我反序列化了对象。我的问题是,如果请求中的XML元素按字母顺序给出,则反序列化只能正常工作,并且不会填充任何无序元素的值。
This behaviour has been reported elsewhere
我觉得这很令人不满意;我认为以特定顺序构造XML的要求是不必要的,并且是一个令人头疼的问题。这是添加到服务的所有客户端的主要要求,也是调试可能存在的难题的来源。
是否可以指示WCF与XML元素顺序无关?
为澄清目的提供了一些进一步的细节:
我的操作合同如下:
[OperationContract]
[WebInvoke(Method="POST", UriTemplate = "/{username}/bookmarks", ResponseFormat = WebMessageFormat.Xml)]
public void PostBookmark(string username, RestBookmark newBookmark);
RestMessage如下所示:
[DataContract(Name = "Bookmark", Namespace = "")]
public class RestBookmark
{
[DataMember]
public string BookmarkMd5 { get; set; }
[DataMember]
public string Url { get; set; }
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Description { get; set; }
}
如果我发送以下XML消息,那么当调用PostBookmark()时,将只填充RestMessage对象的UserName属性:
<?xml version="1.0"?><Bookmark><UserName>nick.street</UserName><Url>http://www.stackoverflow.com</Url><BookmarkMd5>f184eb3347cf94f6ce5f5fc2844e3bdd</BookmarkMd5><Description>Developer Forum</Description><Title>Stack Overflow</Title></Bookmark>
答案 0 :(得分:1)
出于版本控制和性能原因,DataContractSerializer需要严格排序元素。
我可以想到一些选择,
编写一个消息检查器,在DataRegiteSerializer对其进行反序列化之前,重新排序AfterReceivedRequest中的原始XML元素。
使用XmlSerializer为您的服务。
开发HTTP原始XML消息进程 而不是服务。
将对象作为字典传递(不是 推荐)
答案 1 :(得分:0)
我自己没有尝试过,但我会猜测。
在DataContract上创建一个在反序列化之前触发的[OnDeserializing]事件会有帮助吗?在那一点上,你可以重新排序xml,但是需要对它进行排序,以便反序列化能够正常工作。
如果您有Juval Lowy的编程WCF服务第2版,请参阅第107页开始。
答案 2 :(得分:0)
如果您不打算在Order
属性中指定DataMember
以反映节点的顺序,则必须按字母顺序排列xml中的节点。
答案 3 :(得分:-1)
尝试在DataMember属性中将Order设置为0(对于所有成员):
[DataMember(Name =“Title”,Order = 0)]