JSON serialisation of generated Entities...

Posts   
 
    
Posts: 6
Joined: 06-Mar-2014
# Posted on: 06-Mar-2014 06:36:05   

I have followed the official post on how to do this to the letter.

Official Post for reference: https://www.llblgen.com/documentation/4.0/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Distributed%20systems/gencode_webservices.htm

Including adding the DataContract and DataMember attributes as instructed. However I continue to get the following exception at run time of my WebApi project:


<ExceptionMessage>
Type 'EventexWebApi.Data.EntityClasses.EventNewsItemEntity' cannot be IXmlSerializable and have DataContractAttribute attribute.
</ExceptionMessage>

This is my set up:

  • Visual Studio 2013 WebApi project targeting .Net 4.5
  • LLBLGen Pro 4.1 - Target Framework: LLBLGen Pro Runtime Framework; Adapter Template Group; Target Platform .NET 4.5
  • SQL Server 2008

This is the code that is meant to return the collection in JSON:


public IEnumerable<EventNewsItemEntity> GetEventNewsItems()
        {
            using (var adapter = new DataAccessAdapter())
            {
                var metaData = new LinqMetaData(adapter);
                return metaData.EventNewsItem.WithPath(p => p.Prefetch<EventNewsItemTagEntity>(x => x.EventNewsItemTags).SubPath(t => t.Prefetch(y => y.Tag))).ToList();
            }
        }

This is the code in my WebApiConfig class:


public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 
            json.SerializerSettings.ContractResolver = new DefaultContractResolver()
            {
                IgnoreSerializableInterface = true,
                IgnoreSerializableAttribute = true
            };

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

I have used LLBLGen pro for around 8 years on hundreds of projects across various platforms and it has always served me well. However this issue is a potential death knell for me. I have spent a lot of time trying to find out what is wrong but I am at a complete dead end.

Any help on this would be appreciated and as I said I have followed everything perfectly as stated in the official documentation so directing me to that will not help. simple_smile

Regards, Andrew

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 06-Mar-2014 06:50:31   
David Elizondo | LLBLGen Support Team
Posts: 6
Joined: 06-Mar-2014
# Posted on: 06-Mar-2014 07:15:06   

daelmo wrote:

Hi Andrew,

Please check these related threads: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=22474 http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=22349

The first thread seems to no longer exist. It goes back to the default forum page.

The second thread I have read as part of my investigation into the issue and even though I thought it did not help I actually tried to emulate what that user did.

I changed my GetEventNewsItems method as follows:


public HttpResponseMessage GetEventNewsItems()
        {
            using (var adapter = new DataAccessAdapter())
            {
                var eventEntity = new EventEntity(1);           
                var newsItems = eventEntity.EventNewsItems;
                adapter.FetchEntityCollection(newsItems, eventEntity.GetRelationInfoEventNewsItems());
                return Request.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(newsItems));
            }
        }

After doing this it was throwing the following error:


Self referencing loop detected with type 'EventexWebApi.Data.HelperClasses.EntityCollection`1[EventexWebApi.Data.EntityClasses.EventNewsItemEntity]'. Path '[0]._event'.

I solved that by doing the following:


public HttpResponseMessage GetEventNewsItems()
        {           
            using (var adapter = new DataAccessAdapter())
            {
                var eventEntity = new EventEntity(1);           
                var newsItems = eventEntity.EventNewsItems;
                adapter.FetchEntityCollection(newsItems, eventEntity.GetRelationInfoEventNewsItems());
                return Request.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(newsItems, new JsonSerializerSettings() {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}));
            }
        }

My issue is now the same as the user whose thread you posted on here. The JSON being returned is:


[{"_eventNewsItemTags":null,"_event":{"_fieldsData":[[null,null],[null,null],[1,null],[null,null],[null,null]],"_fieldsFlags": [false,false,false,false,true,false,false,false,false,false],"_fieldsState":0,"_fieldsIsDirty":true,"_name":"EventEntity", "_isNew":true,"_validator":null,"_objectID":"e4b3e77d-e349-4335-8f1d-c78d222354f4","_concurrencyPredicateFactoryToUse":null, "_dataErrorInfoError":"","_dataErrorInfoErrorsPerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null, "_auditorToUse":null,"_relatedEntitySyncInfos":null,"_field2RelatedEntity":null},"_fieldsData":[["&lt;p&gt;Fnatic continue to defy believe with a horrendous run of form which has seen them fall from a 7-0 starting record to 8 losses in a row. What started out as such a promising split has turned into a nightmare and with their next match against Gambit there is no respite. As a team they have some serious thinking to do because if they don't turn things around very soon they could be staring down the possibility of a relegation battle to survive in the LCS. Something that would have been unthinkable just one month ago.&lt;br /&gt;&lt;/p&gt;","&lt;p&gt;Fnatic continue to defy believe with a horrendous run of form which has seen them fall from a 7-0 starting record to 8 losses in a row. What started out as such a promising split has turned into a nightmare and with their next match against Gambit there is no respite. As a team they have some serious thinking to do because if they don't turn things around very soon they could be staring down the possibility of a relegation battle to survive in the LCS. Something that would have been unthinkable just one month ago.&lt;br /&gt;&lt;/p&gt;"],[1,1],["2014-02-27T23:42:32.44","2014-02-27T23:42:32.44"],[null,null],["2014-02-27T23:42:32.447", "2014-02-27T23:42:32.447"],[1,1],[2,2],["http://images.rankingshq.com/lcs/fnatic-100.png","http://images.rankingshq.com/lcs/fnatic-100.png"], [null,null],[null,null],[true,true],[1,1],["Fnatic Crash to 8th straight loss","Fnatic Crash to 8th straight loss"]],"_fieldsFlags":[false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,true, false,true,false,false,false,false,false,false],"_fieldsState":1,"_fieldsIsDirty":false,"_name":"EventNewsItemEntity", "_isNew":false,"_validator":null,"_objectID":"f4951c96-19c1-4b95-99e7-f4d7c6c3a16d","_concurrencyPredicateFactoryToUse":null, "_dataErrorInfoError":"","_dataErrorInfoErrorsPerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null, "_auditorToUse":null,"_relatedEntitySyncInfos":{"e4b3e77d-e349-4335-8f1d-c78d222354f4":{"Event":{"DataSupplyingEntity": {"_fieldsData":[[null,null],[null,null],[1,null],[null,null],[null,null]],"_fieldsFlags":[false,false,false,false,true, false,false,false,false,false],"_fieldsState":0,"_fieldsIsDirty":true,"_name":"EventEntity","_isNew":true,"_validator":null ,"_objectID":"e4b3e77d-e349-4335-8f1d-c78d222354f4","_concurrencyPredicateFactoryToUse":null,"_dataErrorInfoError":"" ,"_dataErrorInfoErrorsPerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null,"_auditorToUse":null,"_ elatedEntitySyncInfos":null,"_field2RelatedEntity":null},"Relation":{"TypeOfRelation":2,"IsWeak":false,"AmountFields": 1,"CustomFilterReplacesOnClause":false,"CustomFilter":null,"HintForJoins":0,"AliasPKSide":"","AliasFKSide":"","StartEnt ityIsPkSide":false,"AliasStartEntity":"","AliasEndEntity":"","InheritanceInfoPkSideEntity":null,"InheritanceInfoFkSideE ntity":null,"MappedFieldName":"Event","IsHierarchyRelation":false}}}},"_field2RelatedEntity":{"Event":"e4b3e77d-e349-4 335-8f1d-c78d222354f4"}},{"_eventNewsIte mTags":null,"_event":{"_fieldsData":[[null,null],[null,null],[1,null],[null,null],[null,null]],"_fieldsFlags":[false,fa lse,false,false,true,false,false,false,false,false],"_fieldsState":0,"_fieldsIsDirty":true,"_name":"EventEntity","_isNe w":true,"_validator":null,"_objectID":"e4b3e77d-e349-4335-8f1d-c78d222354f4","_concurrencyPredicateFactoryToUse":null," _dataErrorInfoError":"","_dataErrorInfoErrorsPerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null," _auditorToUse":null,"_relatedEntitySyncInfos":null,"_field2RelatedEntity":null},"_fieldsData":[["Alliance started the season with much fanfare and hype however they failed to live up to those expectations with a poor start to the split. However in recent weeks they have been on the improve and now can begin to set their sights on a top 2 finish. A team of stars, can they become a star team?&lt;br /&gt;","Alliance started the season with much fanfare and hype however they failed to live up to those expectations with a poor start to the split. However in recent weeks they have been on the improve and now can begin to set their sights on a top 2 finish. A team of stars, can they become a star team?&lt;br /&gt;"],[1,1],["2014-02-28T06:27:25.073","2014-02-28T06:27:25.073"],["2014-02-28T06:28:16.293","2014-02-28T06:28:16.293" ],["2014-02-28T06:28:03.567","2014-02-28T06:28:03.567"],[1,1],[3,3],["http://images.rankingshq.com/lcs/team-coast-100.p ng","http://images.rankingshq.com/lcs/team-coast-100.png"],[1,1],[null,null],[true,true],[1,1],["Alliance starting to gain momemtum.","Alliance starting to gain momemtum."]],"_fieldsFlags":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,f alse,false,false,false,true,false,false,false,false,false,false],"_fieldsState":1,"_fieldsIsDirty":false,"_name":"Event NewsItemEntity","_isNew":false,"_validator":null,"_objectID":"703bcff4-d5b5-4d29-80d5-a2ded88f77c4","_concurrencyPredica teFactoryToUse":null,"_dataErrorInfoErr or":"","_dataErrorInfoErrorsPerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null,"_auditorToUse":null ,"_relatedEntitySyncInfos":{"e4b3e77d-e349-4335-8f1d-c78d222354f4":{"Event":{"DataSupplyingEntity":{"_fieldsData":[[null ,null],[null,null],[1,null],[null,null],[null,null]],"_fieldsFlags":[false,false,false,false,true,false,false,false,fals e,false],"_fieldsState":0,"_fieldsIsDirty":true,"_name":"EventEntity","_isNew":true,"_validator":null,"_objectID":"e4b3e 77d-e349-4335-8f1d-c78d222354f4","_concurrencyPredicateFactoryToUse":null,"_dataErrorInfoError":"","_dataErrorInfoErrors PerField":null,"_typeDefaultValueProvider":null,"_authorizerToUse":null,"_auditorToUse":null,"_relatedEntitySyncInfos": null,"_field2RelatedEntity":null},"Relation":{"TypeOfRelation":2,"IsWeak":false,"AmountFields":1,"CustomFilterReplacesO nClause":false,"CustomFilter":null,"HintForJoins":0,"AliasPKSide":"","AliasFKSide":"","StartEntityIsPkSide":false,"Alia sStartEntity":"","AliasEndEntity":"","InheritanceInfoPkSideEntity":null,"InheritanceInfoFkSideEntity":null,"MappedField Name":"Event","IsHierarchyRelation":false}}}},"_field2RelatedEntity":{"Event":"e4b3e77d-e349-4335-8f1d-c78d222354f4"}}]

His solution to this was the following:

Appearently, I need to explicitly pass the right MediaTypeFormatter to the Request.CreateResponse method.

So I am just trying to work out exactly what that means. If I do so I might have this all working. Any further help on this appreciated!

Regards, Andrew

ps - thanks for the prompt reply.

(places spaces in the JSON to properly format the post. All JSON lines originally were full length without the spaces -- Otis)

Posts: 6
Joined: 06-Mar-2014
# Posted on: 06-Mar-2014 08:08:22   

Alright I have solved this. However it seems to be behaving a little strangely.

This is the final method that returns the JSON serialised entity collection successfully:


public HttpResponseMessage GetEventNewsItems()
        {
            using (var adapter = new DataAccessAdapter())
            {
                var eventEntity = new EventEntity(1);
                var newsItems = eventEntity.EventNewsItems;
                adapter.FetchEntityCollection(newsItems, eventEntity.GetRelationInfoEventNewsItems());
                return Request.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(newsItems, 
                    new JsonSerializerSettings()
                    {
                        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                        ContractResolver = new DefaultContractResolver()
                        {
                            IgnoreSerializableInterface = true,
                            IgnoreSerializableAttribute = true
                        }
                    }));
            }
        }

For some reason the WebApi is not reading the values from the WebApiConfig.cs and is making me include all the settings in the actual call. I am not sure why however I am just happy that it is now working.

Regards, Andrew

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 06-Mar-2014 18:24:18   

Did the answer in the other thread work for you? https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22349

Posts: 6
Joined: 06-Mar-2014
# Posted on: 06-Mar-2014 22:14:37   

Walaa wrote:

Did the answer in the other thread work for you? https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22349

Yes, in fact his solution was the same as the one I came up with with the only exception he placed the Json serialisation code into a separate method. So it is producing the expected JSON now.

I preferred the more elegant method in the official documentation however for some reason we both have been unable to get it to work.

Problem solved for the time being now though thanks. simple_smile

Andrew

MichelZ avatar
MichelZ
User
Posts: 24
Joined: 25-Jul-2008
# Posted on: 04-Jan-2015 14:58:37   

I resolved this by removing the other formatters. I don't know if it has any other side effects yet:

        // Web API configuration and services
        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        json.SerializerSettings.ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableInterface = true,
            IgnoreSerializableAttribute = true
        }; 

** config.Formatters.Clear(); config.Formatters.Add(json);**