WCF web service Data Members defaulting to null

筅森魡賤 提交于 2019-12-04 20:35:12

I figured this out (apparently at around the same time James did).

The issue is with the DataContractSerializer, and here is a test case that reproduces it:

class Program
{
    static void Main(string[] args)
    {
        XNamespace ns = "http://tempuri.org/";
        XElement element =
            new XElement(ns + "MyRequest",
                new XElement(ns + "ID", 5),
                new XElement(ns + "Name", "Test"),
                new XElement(ns + "Description", "This is a test"));

        DataContractSerializer serializer = new
            DataContractSerializer(typeof(MyRequest));
        using (XmlReader reader = element.CreateReader())
        {
            MyRequest request = (MyRequest)serializer.ReadObject(reader);
            Console.WriteLine("ID: {0}, Name: {1}, Description: {2}",
                request.ID, request.Name, request.Description);
        }
        Console.ReadLine();
    }

    [DataContract(Name = "MyRequest", Namespace = "http://tempuri.org/")]
    public class MyRequest
    {
        [DataMember]
        public int ID { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string Description { get; set; }
    }
}

If you run this, you'll see that it comes up empty for the Description property.

This happens because the DataContractSerializer expects members to be in alphabetical order. This works fine when you are using the DataContractSerializer for both the client and service... not so great when you're manually generating XML.

If you add Order properties to the DataMember attributes, it works:

    [DataContract(Name = "MyRequest", Namespace = "http://tempuri.org/")]
    public class MyRequest
    {
        [DataMember(Order = 0)]
        public int ID { get; set; }

        [DataMember(Order = 1)]
        public string Name { get; set; }

        [DataMember(Order = 2)]
        public string Description { get; set; }
    }

This time it finds the Description and all other fields.

So to resolve the issue, you can do either of the following:

  • Add Order arguments to the DataMember attributes to match the order in which you actually plan to generate XML; or

  • Make sure you add elements in alphabetical order (by element name) on the client side.

I'm not particularly fond of either of these workarounds. They seem hackish and easy to break. I think for POX services I'd prefer to use the XmlSerializer instead of the DataContractSerializer since it's less finicky about things like that, but it doesn't quite seem to work out of the box with webHttpBinding. Something worth investigating when there's more time.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!