I have a problem with DataContractSerializer
. I use it to create class instances from XML returned by ASP.NET Web Service. But actually the source of data is not important here. To make the whole case easier to debug I've created a simple test project with just the serialization and problem still occurs.
Here is my XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<GetTestURL p1:type="MyApp.GetTestUrlInfo" xmlns:p1="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">
<TestURL>http://bing.com</TestURL>
<UserCount p1:type="Edm.Int32">1</UserCount>
<InitialCount p1:type="Edm.Int32">1</InitialCount>
<AverageExecutionTime p1:type="Edm.Int32">43</AverageExecutionTime>
</GetTestURL>
The class I'm trying to deserialize XML to:
[DataContract(Name = "GetTestURL", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
public class TestInfo
{
[DataMember(Name = "TestURL")]
public Uri TestUri { get; private set; }
[DataMember(Name = "UserCount")]
public int UserCount { get; private set; }
[DataMember(Name = "InitialCount")]
public int InitialCount { get; private set; }
[DataMember(Name = "AverageExecutionTime")]
public int AverageExecutionTime { get; private set; }
}
And my serialization helper class:
public static class SerializationHelper<T>
{
private static DataContractSerializer _serializer = new DataContractSerializer(typeof(T));
public static T Deserialize(Stream source)
{
return (T)_serializer.ReadObject(source);
}
}
Test code:
// Test program
public static void Main()
{
TestInfo info = null;
using (var stream = File.Open("Input.xml", FileMode.Open, FileAccess.Read))
{
info = SerializationHelper<TestInfo>.Deserialize(stream);
}
}
After setting brakepoint at the end of the method I see following:
As you can see, both AverageExecutionTime
and InitialCount
are not deserialized and have int
default value. They should to set to 43
and 1
, because these values are in the XML.
It's even more strange to me, that UserCount
property is done right, but actually it does not differ at all from the two which doesn't work at all. The only thing is different is element name.
This code constructs an instance of the DataContractSerializer that can be used only to serialize or deserialize instances of the Person class. DataContractSerializer dcs = new DataContractSerializer(typeof(Person)); // This can now be used to serialize/deserialize Person but not PurchaseOrder.
By default WCF uses the DataContractSerializer class to serialize data types.
The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.
Most important, the DataContractSerializer is used to serialize and deserialize data sent in Windows Communication Foundation (WCF) messages. Apply the DataContractAttribute attribute to classes, and the DataMemberAttribute attribute to class members to specify properties and fields that are serialized.
I managed to get it to work by updating the data contract. Something to do with the order. When I made Uri a required property it threw an exception, so it may be something to do with the load order.
[DataContract(Name = "GetTestURL", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
public class TestInfo
{
public TestInfo() { }
public TestInfo(Uri uri, int userCount, int initialCount, int averageExecutionTime)
{
TestUri = uri;
UserCount = userCount;
InitialCount = initialCount;
AverageExecutionTime = averageExecutionTime;
}
[DataMember(Name = "TestURL", IsRequired=true, Order=1)]
public Uri TestUri { get; private set; }
[DataMember(Name = "UserCount", IsRequired=true, Order=2)]
public int UserCount { get; private set; }
[DataMember(Name = "InitialCount", IsRequired=true, Order=3)]
public int InitialCount { get; private set; }
[DataMember(Name = "AverageExecutionTime", IsRequired=true, Order=4)]
public int AverageExecutionTime { get; private set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With