WCF services & LLBLGen deserialization

Posts   
1  /  2
 
    
Chaos
User
Posts: 33
Joined: 13-Jul-2006
# Posted on: 26-Oct-2006 11:08:39   

Mmm ... g'mornin' sunshine (mm, lunch time?) and support team,

I am using LLBLGen 2.0 pro, 23 october, with SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll version 2.0.0.061023 and SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll, version 2.0.0.060722.

I've llblgen based asset layer (SQL2005 beneath) and WCF transport layer. Everything works perfect except the transfer of EntityCollection and polymorphic types. I'll explain myself - when I want to transfer an EntityCollection, from the server to the client, containing some entities - I get an empty collection. I've downloaded the sourcecode (commited on 25th of october, downloadable from the customer's area), debugged the xml, the EntityCollection is deserialized (say at the client side) from, and I see nothing's wrong there. Then i see


if(entityFactoryElement==null)
{
    // serious problem, abort
    return;
}

which, yes, is very nice, clean and tidy. disappointed I realized that after all there IS something wrong with xml, it was not parsed correctly. The

node.SelectSingleNode(nsprefix + "EntityFactoryToUse", nsmgr);

did not return the EntityFactoryToUse in despite of the Node.InnerText contains the correct xml, with all the items in the entitycollection and the proper EntityFactories with the proper assembly references. Something is not correct, cause the XmlNode does not contain any children at all, only text element, which IS wrong. Anyways, I guess it turns out that the problem is some sh*t with "<" and ">" which after the XmlReader is passed to the document is "&lt" and "&gt". Node.InnerXml is empty, FirstChild is null, it seems the node is not parsed correctly. I don't know why all other entitis are transferred ok. Could it be the encoding?

And if possible, please do log all the problems, i mean like "console" them or something, cause it's not very convenient to browse through the src and and seek for comments.

For now I've just workarounded that problem, by using a simple List<MyEntity> which is transferred ok.

The other is the subtype design. When I have a BaseEntity with, say, two subtype entities, a lot of problems crawl out. One is the "abstract"-ion of the BaseEntity. It can't be deserialized cause it's constructors are internal. If you set it not abstract it passes ok, but at some late point it crashes on

currentField.ForcedCurrentValueWrite(null);

where the currentField is null. It turned out that this is caused by the deserialization(again) details. When a subtype entities is deserialized, which have it's own fields, a BaseEntity is created the fields xml deserializer tries to set all the fields. The subtype's fields are, by design, not in the BaseEntity. So I'm hanged, I needed to map all the fields in the BaseEntity to allow the proper deserialization, but that, I think, is not the idea, I mean it *ucked up the design after all.

So, can you point me for the EntityCollection xml deserialization issue and the subtypes? And if there is something that I totally misused, please excuse my harsh haste and correct me.

Thanx in advance.

Have a nice day. Chaos.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 26-Oct-2006 12:02:56   

XML webservices and generics aren't supported, because it's not a feature supported by xml webservices. The reason is that the type exposed by the webservice is used to create the methods in the generated stub classes, e.g. EntityCollection<CustomerEntity>, which is done by wsdl.exe

If you then return a collection with a subtype of CustomerEntity in a collection, you can't get that deserialized into an EntityCollection<CustomerEntity> because co-variance isn't supported by C#/VB.NET and also not by xmlwebservices. Therefore you've to expose non-generic entitycollections, e.g. EntityCollection the non-generic one.

Frans Bouma | Lead developer LLBLGen Pro
Chaos
User
Posts: 33
Joined: 13-Jul-2006
# Posted on: 26-Oct-2006 12:45:37   

Nope, it's not webservice, the client&server are using shared contract interface. The wsdl tool is not needed at all. Obviously i didn't make myself clear enough.

The client and server, both, ARE, in fact, working with the same types, e.g entites and entity collections. The wcf does this through ISerializable. So on client I have ChannelFactory, from which the client receives the shared interface, say ISharedContract.

So by ISharedContract methods the client gets the entities and all he needs.

Everything is working, except, as I posted before, EntityCollection (the generic one)

Here's the sample code:


[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ISubscriber))]
IAssetManagerProvider
{
     [OperationContract]
     VerboseResult FetchMasterCollection(Guid clientToken, out EntityCollection masterChannels);
}

The client then connects, makes the call contract.FetchMasterCollection(clientToken, out collection). On the server side, the implementation says just one:


EntityCollection masters = new EntityCollection(new MasterChannelEntityFactory());
... 
Adapter.fetch_the_masters_into_the_masters_collection;

The masters are fetched ok, the collection is filled properly, serialized properly (at least the xml contains all the deserialization needs), with the items inside and the factories. The problem is with the xml itself, something's not right with it, it's encoding, format or something. The entitycollection fails to deserialize from the xml (but doesn't say anything at all to notify an error occured.) My question is - do you have any idea why the xml is broken (why these &lt and &gt appear instead of < and >, because i think that is the exact problem)? If the xml wasn't broken the EntityFactory is retrieved and it's all ok.

Thanks, Chaos

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 26-Oct-2006 13:02:51   

Please stay with me, as I've never used WCF: - you mention XML. If you're using remoting channels, no xml is produced. - if the data is in xml, you're not using remoting and the data is serialized using different code.

Inside llblgen pro's classes two ways of serialization code is implemented: for remoting and for webservices (using IXmlSerializable). One produces whatever the formatter puts out, and the other produces xml.

So what I'm puzzled about is: where does the xml come from? If you're using remoting, the generic types should work without a problem, UNLESS you're using SOAP formatter. SOAP formatter doesn't support generics, this is because Microsoft says the SOAP formatter is deprecated and is planned to be phased out, so they didn't add generic support.

So if you're using remoting, use binary formatter, (or whatever is defined in WCF as its equivalent), and if you're using SOAP / XML, generics are out of the question.

Frans Bouma | Lead developer LLBLGen Pro
Chaos
User
Posts: 33
Joined: 13-Jul-2006
# Posted on: 26-Oct-2006 14:16:09   

Yes, I suppose you're right. The thing is if you set the binding to netTcp (as i did) you should get by default binary encoding. I think that maybe the err transfer environment (damn, what's the expression?) IS in fact binary encoded, but at the end all of the transferred objects are deserialized by IXmlSerializer. And yes, I am using remoting like mechanism, and I don't know why all of the transferred object are de/serialized by the IXmlSerializer. But they are. All of them sigh except that EntityCollection. Why the hell the xml is blurted out like that? Could it be possible that EntityCollection's xml de/serialization is implemented differenlty? The damnest thing is that all of the other entities are working fine (except the subtyped, and for now I can't find a solution to that other than redesign and NOT using subtyping), the only one not working is the sigh EntityCollection. I found http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=276126&SiteID=1 The same problem, and a blurred solution. ("All I did is rebuild and suddenly it's working now" haha. I've rebuild it a thousand times and the same beep keeps smashing into my monitor)

I just can't see a reason why only this xml should be parsed badly. Anyway, I'll keep searching for an answer and will post right after I get one. And if something comes into your mind, please, you're more than welcome to share it.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 26-Oct-2006 15:15:21   

Chaos wrote:

Yes, I suppose you're right. The thing is if you set the binding to netTcp (as i did) you should get by default binary encoding. I think that maybe the err transfer environment (damn, what's the expression?) IS in fact binary encoded, but at the end all of the transferred objects are deserialized by IXmlSerializer. And yes, I am using remoting like mechanism, and I don't know why all of the transferred object are de/serialized by the IXmlSerializer. But they are.

Then there's something setup to use SOAP or xml I think. I do know for a fact that some customers use llblgen pro WCF with remoting and it works OK, so it's probably something small. I'm sorry to tell you we have little to no experience with W*F techniques so far, so I can't help you with details.

All of them sigh except that EntityCollection. Why the hell the xml is blurted out like that? Could it be possible that EntityCollection's xml de/serialization is implemented differenlty? The damnest thing is that all of the other entities are working fine (except the subtyped, and for now I can't find a solution to that other than redesign and NOT using subtyping), the only one not working is the sigh EntityCollection. I found http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=276126&SiteID=1 The same problem, and a blurred solution. ("All I did is rebuild and suddenly it's working now" haha. I've rebuild it a thousand times and the same beep keeps smashing into my monitor)

I just can't see a reason why only this xml should be parsed badly. Anyway, I'll keep searching for an answer and will post right after I get one. And if something comes into your mind, please, you're more than welcome to share it.

I share your frustration, it was a shock to me to learn that Soap formatters can't handle generics nor webservices can. disappointed All the xml serialization code in the entitycollection does is produce data tags and tags for the factory for example.

I'm not entirely sure how WCF builds objects on the client side if the data is send in xml format, as it needs type specifications.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 14-Dec-2006 16:04:48   

Hi Otis,

I've got the same problem as Chaos. When I try to transfert an EntityCollection using WCF and a netTcpBinding, I get an empty entity at the client end.

The fact that we see embedded XML in the message doesn't really surprise me, since WCF uses XML serialization with a higher priority as standard serialization. So with an object (like the EntityCollectionBase2<TEntity>) having a [Serializable] flag and implementing IXmlSerializable, the lastest is chosen.

The thing is that it still should be working if the IXmlSerializable is implemented properly. I already used objects implementing it in WCF and it worked fine.

I was wondering if the IXmlSerializable interface you implemented make assumptions that would be true for remoting but not for WCF (like for instance assumming that other objects are serialized using XML as well in the same message).

I guess the easiest way around all that is to implement the serialization in the WCF framework directly using [DataContract].

Franck

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 14-Dec-2006 17:14:06   

The IXmlSerializable implementation is actually simply calling WriteXml() on the entitycollection and also calling ReadXml() on the other end. (the overloads which accept an XmlWriter/Reader)

Do you see any xml in the message which is embedded in <EntityCollection> elements? The IXmlSerializable implementation does work properly over webservices where an entity with an embedded collection is returned for example. Does your collection contain entities in an inheritance hierarchy perhaps?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 15-Dec-2006 12:11:22   

Hi Otis,

Actually, I looked a bit deeper into the XmlSerialization of that collection and I figured out that the entity I used wasn't deserialized properly if I send only the entity. I get a nullexception.

I think it's coming from the fact I used custom enum types for one of the fields (I set that in the designer before generating the classes). The actual serialization of the object gives me that xml string (If I call WriteXml direcly) :

<LayerDataEntity LayerDataID="1" Assembly="ConceptWare.FIDES.Database.Adapter, Version=1.0.2540.21583, 
Culture=neutral, PublicKeyToken=null" Type="ConceptWare.FIDES.Database.Adapter.EntityClasses.LayerDataEntity"
><EntityReference PropertyName="UserLog" /><IsNew Type="System.Boolean">False</IsNew><ConcurrencyPredicateFactory 
Assembly="Unknown" /><EntityReference PropertyName="TextTranslationKey" /><EntityReference PropertyName="LayerKey" 
/><Validator Assembly="Unknown" /><ObjectID Type="System.Guid">5316ef0a-272a-4721-acf2-5957f4541487
</ObjectID><Fields><LayerDataID><CurrentValue Type="System.Int32">1</CurrentValue><DbValue Type="System.Int32">1
</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></LayerDataID><LayerID><CurrentValue Type="System.Int32">0</CurrentValue><DbValue Type="System.Int32">0
</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></LayerID><TextID><CurrentValue Type="System.Int32">853</CurrentValue><DbValue Type="System.Int32">853
</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></TextID><IsHidden><CurrentValue Type="System.Boolean">False</CurrentValue><DbValue Type="System.Boolean">
False</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></IsHidden><ValidFrom><CurrentValue Type="System.DateTime">631769760000000000</CurrentValue><DbValue Type=
"System.DateTime">631769760000000000</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type=
"System.Boolean">False</IsNull></ValidFrom><ValidTo><CurrentValue Type="System.DateTime">3155063616000000000
</CurrentValue><DbValue Type="System.DateTime">3155063616000000000</DbValue><IsChanged Type="System.Boolean">False
</IsChanged><IsNull Type="System.Boolean">False</IsNull></ValidTo><ActiveFrom><CurrentValue Type="System.DateTime">
633010851454990000</CurrentValue><DbValue Type="System.DateTime">633010851454990000</DbValue><IsChanged Type=
"System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False</IsNull></ActiveFrom><ActiveTo><CurrentValue 
Type="System.DateTime">3155063616000000000</CurrentValue><DbValue Type="System.DateTime">3155063616000000000
</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></ActiveTo><ModificationDate><CurrentValue Type="System.DateTime">633010851454990000
</CurrentValue><DbValue Type="System.DateTime">633010851454990000</DbValue><IsChanged Type="System.Boolean">False
</IsChanged><IsNull Type="System.Boolean">False</IsNull></ModificationDate><CommandDate><CurrentValue Type=
"System.DateTime">633010851454990000</CurrentValue><DbValue Type="System.DateTime">633010851454990000
</DbValue><IsChanged Type="System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False
</IsNull></CommandDate><Command><CurrentValue Type="LLBLGenCustomTypes.Types.TemporalDatabaseCommand">Creation
</CurrentValue><DbValue Type="LLBLGenCustomTypes.Types.TemporalDatabaseCommand">Creation</DbValue><IsChanged Type=
"System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False</IsNull></Command><UserLogID><CurrentValue 
Type="System.Int32">1</CurrentValue><DbValue Type="System.Int32">1</DbValue><IsChanged Type="System.Boolean">False
</IsChanged><IsNull Type="System.Boolean">False</IsNull></UserLogID></Fields><IsDirty Type="System.Boolean">False
</IsDirty><EntityState Type="SD.LLBLGen.Pro.ORMSupportClasses.EntityState">Fetched</EntityState><SavedFieldSets />
</LayerDataEntity>

The function ReadXml called on the entity is not capable of parsing it. I't probably because of the LLBLGenCustomTypes.Types.TemporalDatabaseCommand enum that I used.

Are you sure that enities are deserialized properly when using custom enum types in the designer ? Maybe I'm missing something in the enum declaration. I've tried :


[DefaultEnumValue((int)TemporalDatabaseCommand.Creation)]
    public enum TemporalDatabaseCommand
    {
        [XmlEnumAttribute("1")] 
        Creation = 1,
        [XmlEnumAttribute("2")]
        Deletion = 2,
        [XmlEnumAttribute("3")]
        NoCommand = 3
    }

but it doesn't seem to take the attributes into account when serializing. If you've got any suggestion to get this working (for a first step into the collection problem), they'll be welcome.

Franck

Posts: 22
Joined: 26-Oct-2005
# Posted on: 15-Dec-2006 12:15:09   

the [DefaultEnumValue((int)TemporalDatabaseCommand.Creation)] attribute I used in the previous code is actually for my code and I defined it, but it doesn't affect the behavior.

Franck

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Dec-2006 12:38:26   

It should simply emit the value with the property in the XML. As it uses custom xml serialization, these attributes aren't used, my code doesn't look for these.

Serializing the data to xml when webservices are used (compactxml mode) is a process where reflection is used to gather information about the properties of an object and the data is then emitted using custom code. However, enums should be written OK OR they should give an exception, but as it results in an XML output block, I have no idea why this doesn't work in your code.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 02-Jan-2007 15:38:09   

Hi Otis,

As far as it looks, the serialization works fine since we have

<Command><CurrentValue Type="LLBLGenCustomTypes.Types.TemporalDatabaseCommand">Creation
</CurrentValue><DbValue Type="LLBLGenCustomTypes.Types.TemporalDatabaseCommand">Creation</DbValue><IsChanged Type=
"System.Boolean">False</IsChanged><IsNull Type="System.Boolean">False</IsNull></Command>

in the generated XML files.

When it comes to the deserialization, your custom code is not able to parse that. It calls the XmlValueToObject function of the SD.LLBLGen.Pro.ORMSupportClasses.XmlHelper class. In that class you simply return null if the type is not one you expect.

So what I don't get is that, in LLBLGen Pro, you can replace the .Net type (here Int16) by a custom type, with a custom type converter, but it doesn't get serialized properly in Xml, so it breaks WCF and probably other things.

Shouldn't you use the custom type converter to serialize/deserialize the entity properly in Xml ? It shouldn't be that hard to convert it back into the original type for serialization purposes. Maybe you can find another way of deserializing it, but returning null, just isn't good enough here.

I think allowing the use of custom enum types is great but that would be even better is serialization is working for it.

Franck

jbb avatar
jbb
User
Posts: 267
Joined: 29-Nov-2005
# Posted on: 02-Jan-2007 15:59:47   

Hello,

could you post the code you used to deserialize? Because serialization and deserialization of entities should work using writexml and readxml.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 02-Jan-2007 16:08:38   

I think what should be done is having an extra clause for 'Enum' in the XmlValueToObject routine, which then would convert the value to an enum instance using the Enum static methods. I find it strange that the type is specified in the xml, as webservices use compactXML which won't emit the type in the field.

TypeConverters aren't in the picture, as they're used to convert values to types which are accepted by the db. As long as it's an entity, the values have the type of the field in the entity.

THe typename is passed to XmlValueToObject, which tries to re-instantiate the type. If your server doesn't have the assembly with the type in a reachable place (e.g. GAC or in the app folder), the type can't be loaded. As the string doesn't match any of the types specified, it falls into the default clause which simply doesn't convert at all hence an error later on. THe routine should get more clever, in that it should consider the field's type as well, in that it should check if that's an enum and if so, it should have code to convert the value to an enum value.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 04-Jan-2007 14:35:47   

The code I used to test is simply :

ReportDataEntity reportEntity = new ReportDataEntity(1);
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntity(filter);
string brokenXml;
filter.WriteXml(out brokenXml);
Console.WriteLine(brokenXml);
filter.ReadXml(brokenXml);

The writeline gives the output above and the program crashes on the last line.

I'm not using WebServices here so that's probably why it doesn't use compactXML.

Using TypeConverters was just an idea to get it working fast, since integer work fine on serialization/deserialization. But you're right that would just be a hack. The enum type should be used directly.

Can I expect the enums to be supported in the runtime soon ?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 05-Jan-2007 14:00:00   

There's one thing I don't understand. If you look into the XmlHelper.XmlValueToObject routine (in the runtime sourcecode), you'll see it checks the type's name and with an enum it thus ends up in the default clause of the switch. It there would just return the value passed in (thus the enum value but in string format) and THAT value is written in the field's Currentvalue.

That won't make a crash happen during deserialization, though it will throw a cast not valid exception during runtime when you request the field's value.

You get a null ref exception during deserialization? Could you give me the stacktrace of taht please?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 05-Jan-2007 16:23:24   

Hi Otis,

I'm affraid the stack trace doesn't really help :

{System.NullReferenceException: Object reference not set to an instance of an object.
   at SD.LLBLGen.Pro.ORMSupportClasses.XmlHelper.XmlValueToObject(String typeName, String xmlValue)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityFields2.ReadXml(XmlNode fieldsElement)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.Xml2Entity(XmlNode node, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.ReadXml(XmlNode node)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.ReadXml(String xmlData)
   at ConceptWare.FIDES.Server.ReportEditionServer.Module.APIImpl.ReportDatabaseAccess.GetR(IEntityEditionContext context, Int32 reportID) in F:\FIDES\Server\Servers\Reports\ReportEditionServer.Module\ReportEditionServer.Module\APIImpl\ReportDatabaseAccess.cs:line 73
   at SyncInvokeGetR(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.InvokeDelegate.Invoke(Object target, Object[] inputs, Object[] outputs)
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)}
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 05-Jan-2007 18:35:13   

Franck wrote:

Hi Otis,

I'm affraid the stack trace doesn't really help :

{System.NullReferenceException: Object reference not set to an instance of an object.
   at SD.LLBLGen.Pro.ORMSupportClasses.XmlHelper.XmlValueToObject(String typeName, String xmlValue)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityFields2.ReadXml(XmlNode fieldsElement)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.Xml2Entity(XmlNode node, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.ReadXml(XmlNode node)
   at SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.ReadXml(String xmlData)
   at ConceptWare.FIDES.Server.ReportEditionServer.Module.APIImpl.ReportDatabaseAccess.GetR(IEntityEditionContext context, Int32 reportID) in F:\FIDES\Server\Servers\Reports\ReportEditionServer.Module\ReportEditionServer.Module\APIImpl\ReportDatabaseAccess.cs:line 73
   at SyncInvokeGetR(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.InvokeDelegate.Invoke(Object target, Object[] inputs, Object[] outputs)
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)}

This is during the webservice call I suppose? (You don't get this exception when you're using the writexml/readxml manually in a routine?). I ask this to rule out any other issues elsewhere. (GetR simply calls ReadXml ? )

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 08-Jan-2007 08:54:58   

Hi Otis,

This is what I get when I call writeXml and readXml manually. It's not even in any remoting/WCF/WS scenario. As stated two messages above I use a function containing :

ReportDataEntity reportEntity = new ReportDataEntity(1);
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntity(filter);
string brokenXml;
filter.WriteXml(out brokenXml);
Console.WriteLine(brokenXml);
filter.ReadXml(brokenXml);

and it gives me that exception.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Jan-2007 10:06:46   

Thanks Franck, I'll see if I can repro it and implement a fix.

(edit) btw:

ReportDataEntity reportEntity = new ReportDataEntity(1);
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntity(filter);
string brokenXml;
filter.WriteXml(out brokenXml);
Console.WriteLine(brokenXml);
filter.ReadXml(brokenXml);

you don't fetch reportEntity, you write filter's Xml wink

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Jan-2007 11:49:28   

Fixed in next build of runtime libs. (2.0.07.0108 )


[Test]
public void EnumXmlSerializationTest()
{
    ProductTcEntity product = new ProductTcEntity(25);
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        adapter.FetchEntity(product);
    }

    string xml;
    product.WriteXml(out xml);
    ProductTcEntity deserialized = new ProductTcEntity();
    deserialized.ReadXml(xml);
    string deserializedXml;
    deserialized.WriteXml(out deserializedXml);
    Assert.AreEqual(xml, deserializedXml);
    Assert.AreEqual(ReorderLevel.Thirty, product.ReorderLevel);
    Assert.AreEqual(ReorderLevel.Thirty, deserialized.ReorderLevel);
}

I made an enum and a converter for it for Product.ReorderLevel to test this.

The crash happened in the type resolving routine. .NET 2.0 requires that the assembly name is specified in a full name. The stupidity is that type.FullName not always returns this.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 08-Jan-2007 12:53:00   

shouldn't AssemblyQualifideName be used instead ?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Jan-2007 13:04:10   

Franck wrote:

shouldn't AssemblyQualifideName be used instead ?

Not necessarily. With the LLBLGenProDataSource(2) controls I ran into this problem for the first time (when I had to emit the adapter etc. typename into the HTML) and it turned out that you just needed to append ', assemblyname' to the typename. E.g.: "Northwind.EntityClasses.CustomerEntity, Northwind". So I have a utility routine for that, and the name is now properly emitted into the XML and the addition for System.Enum to the Xml helper class, makes it possible to convert a string back to an enum value simple_smile

AssemblyQualifiedName is sufficient as well, though it's pretty big, and not necessarily what you want in XML.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 22
Joined: 26-Oct-2005
# Posted on: 08-Feb-2007 11:23:22   

Hi Otis,

Thanks for the fix for enums types, but unfortunately WCF transfer is still broken (I guess that wasn't the problem, or something else is broken). It's still failing on the same part. I sent you an example solution to support AT llblgen.com, so that you can have a look.

Franck

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Feb-2007 12:12:49   

Franck wrote:

Hi Otis,

Thanks for the fix for enums types, but unfortunately WCF transfer is still broken (I guess that wasn't the problem, or something else is broken). It's still failing on the same part. I sent you an example solution to support AT llblgen.com, so that you can have a look.

Franck

Ok, I received. it.

I haven't looked into WCF that much, so I hope it's solvable without me doing a 3 week course on WCF.

I wonder why it fails in WCF usage but write/readxml do work, as that's the same thing... disappointed

Frans Bouma | Lead developer LLBLGen Pro
1  /  2