Deserializing Entity & WCF

Posts   
 
    
Antonio avatar
Antonio
User
Posts: 67
Joined: 09-Oct-2007
# Posted on: 10-Oct-2007 10:01:45   

When I try to obtain an Entity or a Collection via WCF Method, if the Entity contains a DateTime field, the following error occurs

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetArticlesResult. The InnerException message was 'There was an error deserializing the object of type SD.LLBLGen.Pro.ORMSupportClasses.IEntityCollection2. The string '2007-10-10T00.00.00.0000000+02:00' is not a valid AllXsd value.'. Please see InnerException for more details.

stacktrace:


   at System.Xml.Schema.XsdDateTime..ctor(String text, XsdDateTimeFlags kinds)
   at System.Xml.XmlConvert.ToDateTime(String s, XmlDateTimeSerializationMode dateTimeOption)
   at SD.LLBLGen.Pro.ORMSupportClasses.XmlHelper.XmlValueToObject(String typeName, String xmlValue) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\XmlHelper.cs:line 461
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.Xml2Entity(XmlReader reader, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\EntityBase2.cs:line 1291
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.Xml2EntityCollection(XmlReader reader, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\EntityCollectionBase2.cs:line 1023
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.ReadXml(XmlReader reader, XmlFormatAspect format) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\EntityCollectionBase2.cs:line 701
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v2.0\RuntimeLibraries 2.5 .NET 2.x\ORMSupportClasses\EntityCollectionBase2.cs:line 1858
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadIXmlSerializable(XmlSerializableReader xmlSerializableReader, XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, Boolean isMemberType)
   at System.Runtime.Serialization.XmlDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, DataContract& dataContract)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
   at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)

We using: Runtime version 2.5.0.0.10052007 Designer version 24 sept 2007

I return the Entity or Collection from this WCF Service:


[ServiceKnownType(typeof(ArticoliEntity))]
[ServiceKnownType(typeof(EntityCollection))]
public interface IService1
{
        [OperationContract]
        IEntity2 GetArticolo(int id);

        [OperationContract]
        IEntityCollection2 GetArticles();
    }

the class ArticoliEntity has a DateTime field.

Overriding the WriteXml method for ArticoliEntity:


public override void WriteXml(System.Xml.XmlWriter writer)
{
WriteXml(writer, XmlFormatAspect.Compact25 | XmlFormatAspect.MLTextInCDataBlocks);
}

excluding XmlFormatAspect.DatesInXmlDataType, it works!

Can someone help me?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 10-Oct-2007 11:32:00   

I think a simsilar question was posted here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=8715

If the above thread doesn't help you, please post back here.

Antonio avatar
Antonio
User
Posts: 67
Joined: 09-Oct-2007
# Posted on: 10-Oct-2007 11:36:31   

Walaa wrote:

I think a simsilar question was posted here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=8715

If the above thread doesn't help you, please post back here.

I've already search in this forum, and read the thread above. The issue is still unresolved for me.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 11-Oct-2007 10:54:59   

Do you have a custom field in an entity of type DateTime ?

The thing is this: the string in the XML is indeed not of the right format. The string in the error message looks like: 2007-10-10T00.00.00.0000000+02:00

However, the strings produced by LLBLGen Pro XML serialization look like: 2007-10-10T00:00:00.0000000+02:00

This is done in XmlHelper.PropertyValueToString, which uses the format string: "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz" So I did a little testing:


string dateString = "2007-10-10T00.00.00.0000000+02:00";
DateTime testDate = new DateTime(2007, 10, 10);
string dateString2 = testDate.ToString( "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz" );
string dateString3 = XmlConvert.ToString(testDate);
Console.WriteLine(dateString);
Console.WriteLine(dateString2);
Console.WriteLine(dateString3);
Debug.Assert(dateString3 == dateString2);
DateTime date = XmlConvert.ToDateTime(XmlConvert.ToString(new DateTime(2007, 10, 10)), XmlDateTimeSerializationMode.Unspecified);
Debug.Assert(date.Equals(testDate));
DateTime date2 = XmlConvert.ToDateTime(dateString2);
Debug.Assert(date2.Equals(testDate));
DateTime date3 = XmlConvert.ToDateTime(dateString3);
Debug.Assert(date3.Equals(testDate));
DateTime date4 = XmlConvert.ToDateTime(dateString2, XmlDateTimeSerializationMode.Unspecified);
Debug.Assert(date4.Equals(testDate));

They all work. So I wondered, what's wrong with the string, then I saw that the string didn't have ':' between hours and minutes.

I have no idea why the string you ran into has '.' instead of ':' in the date string. Therefore I need more specifics from you. As you posted a stacktrace with line numbers, did you use the debug build of the runtime lib or did you build your own lib?

Frans Bouma | Lead developer LLBLGen Pro
Antonio avatar
Antonio
User
Posts: 67
Joined: 09-Oct-2007
# Posted on: 11-Oct-2007 11:44:04   

Otis wrote:

Do you have a custom field in an entity of type DateTime ?

The thing is this: the string in the XML is indeed not of the right format. The string in the error message looks like: 2007-10-10T00.00.00.0000000+02:00

However, the strings produced by LLBLGen Pro XML serialization look like: 2007-10-10T00:00:00.0000000+02:00

This is done in XmlHelper.PropertyValueToString, which uses the format string: "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz" So I did a little testing:


string dateString = "2007-10-10T00.00.00.0000000+02:00";
DateTime testDate = new DateTime(2007, 10, 10);
string dateString2 = testDate.ToString( "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz" );
string dateString3 = XmlConvert.ToString(testDate);
Console.WriteLine(dateString);
Console.WriteLine(dateString2);
Console.WriteLine(dateString3);
Debug.Assert(dateString3 == dateString2);
DateTime date = XmlConvert.ToDateTime(XmlConvert.ToString(new DateTime(2007, 10, 10)), XmlDateTimeSerializationMode.Unspecified);
Debug.Assert(date.Equals(testDate));
DateTime date2 = XmlConvert.ToDateTime(dateString2);
Debug.Assert(date2.Equals(testDate));
DateTime date3 = XmlConvert.ToDateTime(dateString3);
Debug.Assert(date3.Equals(testDate));
DateTime date4 = XmlConvert.ToDateTime(dateString2, XmlDateTimeSerializationMode.Unspecified);
Debug.Assert(date4.Equals(testDate));

They all work. So I wondered, what's wrong with the string, then I saw that the string didn't have ':' between hours and minutes.

I have no idea why the string you ran into has '.' instead of ':' in the date string. Therefore I need more specifics from you. As you posted a stacktrace with line numbers, did you use the debug build of the runtime lib or did you build your own lib?

Yes, I use the debug build of the runtime library. Executing your testing code, the first Assert fails. In effect I obtain the following values:


dateString2="2007-10-10T00.00.00.0000000+02:00";
dateString3 ="2007-10-10T00:00:00.0000000+02:00";

Therefore the methods DateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz") and XmlConvert.ToString(testDate) returns different values.

In my opinion the problem is exactly the following call in XMLHelper.cs


valueAsString = ((DateTime)propertyValue).ToString( "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz" );

As remarked in the .NET Framework documentation, the DateTime.ToString(string) method, uses formatting information derived from the current culture. In our case the culture is it-IT While XmlConvert.ToString(DateTime) returns string representation of the DateTime in the format yyyy-MM-ddTHH:mm:ss where 'T' is a constant literal.

For now, I resolved setting the english CultureInfo in the service constructor, i.e:

public MyService()
{
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
}

I hope this helps.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 11-Oct-2007 12:17:18   

What I find strange is that the culture has any influence, as the format string is specific: it specifies ':' as delimiters, it doesn't rely on the delimiter of the culture... So even though there are ':' in the format string, they're apparently ignored.

Will check if the XmlConvert.ToString() method is better in this case.

Frans Bouma | Lead developer LLBLGen Pro
Antonio avatar
Antonio
User
Posts: 67
Joined: 09-Oct-2007
# Posted on: 11-Oct-2007 12:28:09   

Otis wrote:

What I find strange is that the culture has any influence, as the format string is specific: it specifies ':' as delimiters, it doesn't rely on the delimiter of the culture... So even though there are ':' in the format string, they're apparently ignored.

Will check if the XmlConvert.ToString() method is better in this case.

Probably the culture influences the format because the method DateTime.ToString(string), internally calls:

public string ToString(string format)
{
    return DateTimeFormat.Format(this, format, DateTimeFormatInfo.CurrentInfo);
}


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 11-Oct-2007 12:53:51   

Peeking into XmlConvert.ToString, I see I forgot the DateTimeFormatInfo.InvariantInfo.

Anyway, XmlConvert.ToString(date, serializationmode) does the same thing. I'll replace the code with that call to avoid this issue. Fixed in next build (10112007)

Frans Bouma | Lead developer LLBLGen Pro