REST-ful WCF service: Deserializing C# List of Str

2020-07-27 06:17发布

问题:

I've got a REST-ful WCF service that returns back an XML response. It is comprised of objects that are serializing and de-serializing correctly, with the one exception that my List property on a node is not deserializing correctly. The XML looks like:

<ShippingGroups>
<ShippingGroup>
  <ShippingGroupId>
  b0b4d8a4-ff1f-4f02-a47c-263ef8ac861b</ShippingGroupId>
  <ShippingAddressId>
  63c0b52c-b784-4c27-a3e8-8adafba36add</ShippingAddressId>
  <LineItemIds xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <a:string>ccc0f986-52d5-453e-adca-8ff4513c1d84</a:string>
  </LineItemIds>
</ShippingGroup>

The problem arises because my C# class to deserialize this XML is expecting a List LineItemIds. I can get around this by manually removing that namespace and removing the .

Is there another way around this, such that it would look like:

<ShippingGroups>
<ShippingGroup>
  <ShippingGroupId>
  b0b4d8a4-ff1f-4f02-a47c-263ef8ac861b</ShippingGroupId>
  <ShippingAddressId>
  63c0b52c-b784-4c27-a3e8-8adafba36add</ShippingAddressId>
  <LineItemIds>
    <string>ccc0f986-52d5-453e-adca-8ff4513c1d84</string>
  </LineItemIds>
</ShippingGroup>

回答1:

I think I have an answer for you. Without seeing your DataContracts, I'm kind of guessing as to what you're using and how your data is structured. But here goes...

I am using VS2010, C#, WCF REST and .NET 4 for this.

By default, your collection or array is using a default namespace in order to maintain interoperability when it gets serialized. So, your serialization is behaving as designed.

You can get around this if you create a custom collection and use the CollectionDataContract attribute on it. You then have more control over how it gets serialized, including its namespace. Here's a detailed explanation about this from MSDN.

So I created a custom collection and used the CollectionDataContract namespace as such:

[CollectionDataContract(Namespace="")]
public class StringItem2 : Collection<string>
{
}

There are no properties since this collection will just hold strings.

I then have my DataContract that contains my custom string collection:

[DataContract(Namespace="", IsReference=false)]
public class SampleItem
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string StringValue { get; set; }
    [DataMember]
    public StringItem2 StringItems2 { get; set; }
}

Now that I've done that, I have my simple WCF RESTful service (GET):

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1
{

    [WebGet(UriTemplate = "{id}")]
    public SampleItem Get(string id)
    {
        SampleItem si = new SampleItem()
        {
            Id = 10,
            StringValue = "foo",
            StringItems2 = new StringItem2() { "Hola", "como", "esta", "usted" }
        };
        return si;
    }

}

When I request this service (http://localhost:xxxx/Service1/10), I get the following XML as a response:

<SampleItem xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
 <Id>10</Id> 
 <StringItems2>
  <string>Hola</string> 
  <string>como</string> 
  <string>esta</string> 
  <string>usted</string> 
 </StringItems2>
 <StringValue>foo</StringValue> 
</SampleItem>

Hopefully this helps. Please let me know if there are additional details that I missed or if there's more to the question. I'll update my answer accordingly.