Defining an EntityView to be serializable

Posts   
1  /  2
 
    
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 06-May-2013 21:14:54   

Hi,

I'm building a website using version 4 in self servicing mode. I'm trying to use a commercial gridcontrol (Syncfusion) in Ajax mode. I set the datasource of this grid to an LLBLGen datasource.

When I try the page in debug mode, a runtime error is given, stating that the used entityview is not marked serializable. The underlying entity class is marked serializable.

The entityview is something internal to LLBLGen. How can I set the Serializable attribure for this object? Or should I use another approach?

Best regards,

Jan

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 06-May-2013 23:09:16   

Could you please post the stack trace and exact exception error? Also, does this work in Release mode?

JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 06-May-2013 23:53:59   

In Release mode I get the same error:

SerializationException: Het type SD.LLBLGen.Pro.ORMSupportClasses.EntityView`1[[HITc.WCS.EntityClasses.WeldingJobEntity, HITc.WCS, Version=1.0.4873.21216, Culture=neutral, PublicKeyToken=null]] in assembly SD.LLBLGen.Pro.ORMSupportClasses, Version=4.0.0.0, Culture=neutral, PublicKeyToken=ca73b74ba4e3ff27 is niet als serialiseerbaar gemarkeerd.]

Translates as EntityView ..... is not marked serializable

System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +10491111 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +230 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +121 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +178 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +51 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +540 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +131 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph) +12 Syncfusion.Web.UI.WebControls.Grid.Grouping.Common.Utils.ConvertObjectToString(Object obj) +113 Syncfusion.Web.UI.WebControls.Grid.Grouping.Common.DataSourceSerializer.Serialize(Object oDataSource, DataSourceType& dstType) +528 Syncfusion.Web.UI.WebControls.Grid.Grouping.GridGroupingControl.SaveDataSource() +161 Syncfusion.Web.UI.WebControls.Grid.Grouping.GridGroupingControl.SaveViewState() +93 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +93 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Control.SaveViewStateRecursive(ViewStateMode inheritedMode) +324 System.Web.UI.Page.SaveAllState() +574 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1225

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 07-May-2013 07:16:08   
  • Does it work with the shipped asp.net grid control?

  • Please post the declarative ASPX for the Grid and the LLBLGen DataSource.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 07-May-2013 09:13:05   

The view isn't serializable, but that's for a reason: it's a view on an underlying collection. However with a datasource control, you should never run into this...

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 07-May-2013 19:10:29   

So this should be considered as faulty implementation of the control. I'll try to see what happens if I do the binding in the code file.

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 07-May-2013 19:49:11   

Also please try with the default asp.net grid.

JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 07-May-2013 23:13:03   

The problem does not occur when I run the grid with EnableAjaxMode set to false. I wanted to use it with this parameter set to true, since the skins available in that situation more nice.

I`ll stick to the working situation unless someone presents a proper solution.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 08-May-2013 11:43:33   

What I think happens (but it's just speculation from my side, so it can be completely wrong) is this: - the grid is bound to a collection (through the datasource control). - The collection implements IListSource, which makes the grid be bound to an entityview. - the grid wants to transport its data to the client over ajax, so its server part serializes the data it has (the entity view) to be send over the wire. - as serializing the entityview is not working as it's not marked serializable, it fails.

What I find odd is that the grid serializes to binary, as ajax is xml oriented, if I'm not mistaken. Did you ask Telerik Syncfusion what could cause this?

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 11-May-2013 20:42:12   

The control is part of Syncfusion Essential Studio.

They'll probably will not have an LLBL license, so sending an example will not help.

It's a bit difficult for me to formulate the problem. I'll think about it.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 12-May-2013 11:35:53   

JayBee wrote:

The control is part of Syncfusion Essential Studio.

They'll probably will not have an LLBL license, so sending an example will not help.

We have a Lite, 8 entities free version now, so they should be able to reproduce it. The main thing for them to check is what object they serialize. If it's the object directly bound to their grid, then it will be EntityView (due to the IListSource implementation of the bound object) which isn't serializable.

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 21-Oct-2013 21:22:24   

I'm using it know outside of Ajax. That works fine.

Just found out that in the control I had set the Data Source Caching Mode to None. After I changed it into ViewState or Session the error reoccured.

I'll try to discuss this with Syncfusion.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 22-Oct-2013 07:30:41   

JayBee wrote:

Just found out that in the control I had set the Data Source Caching Mode to None. After I changed it into ViewState or Session the error reoccured.

I'll try to discuss this with Syncfusion.

Ok. Please give us feedback when you get a response from Syscfusion.

David Elizondo | LLBLGen Support Team
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 08-Nov-2013 10:18:13   

I was able to create the same problem with Northwind. After some research by Syncfusion, this is there answer:

Hi Jan, We deeply regret to let you know that the mentioned issue is not in our source. We have also tried with java script serializer after that we are facing Circular reference issue. The data source returned from llblgen DataSource control has circular reference by default. So we are not able to serialize this data source. Please let us know if you have any further assistance. Regards, Satheeskumar S

In a previous post I mentioned that the problem does not occur when EnableAjaxMode is set to false. This is not true. Other problems will occur. E.g. sorting info of filter info gets lost unless the datasource is rebound to the grid on each page change.

I have pointed Syncfusion to this thread.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 08-Nov-2013 10:50:52   

JayBee wrote:

I was able to create the same problem with Northwind. After some research by Syncfusion, this is there answer:

Hi Jan, We deeply regret to let you know that the mentioned issue is not in our source. We have also tried with java script serializer after that we are facing Circular reference issue. The data source returned from llblgen DataSource control has circular reference by default. So we are not able to serialize this data source. Please let us know if you have any further assistance. Regards, Satheeskumar S How to proceed?

I have no idea what they're doing over there, but what they gave you doesn't show they understand the real issue. The collection bound to the control has multiple ways to serialize its data: through binary serialization or through xml serialization. It seems what they're doing is simply throwing a dumb serializer from .NET on it without specifying that it should take cyclic references into account.

Your initial issue was that they tried to serialize the EntityView, because they called IListSource's method to obtain the object. The view isn't serializable, as deserializing it won't work (it's a view on a collection after all). DataView has the same problem, but I'm sure they have special code for that implemented.

Now they can't serialize objects because they're referencing each other. They can serialize the collection to XML just fine, as it implements IXmlSerializable. It also can be serialized to JSon, if they specify that the json serializer should take into account the cyclic references. They should do that anyway, as most object collections bound to their control will likely be referencing objects using cyclic references.

What I don't get is that if the control is used in normal webforms mode, it's able to display the rows just fine, but it can't serialize that data over the wire, because it suddenly has to serialize things?

I don't know what we can do, as the collection has IListSource implemented and it's up to binding controls to handle that with care, like all of them do with DataTable's IListSource implementation as they know it's returning a DataView, something which isn't serializable and which implements the exact same interfaces as the collection does.

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 09-Nov-2013 12:06:31   

Reaction from Syncfusion:

Thanks for your update.

We have confirmed that the issue with “Data Source is not marked as Serializable using LLBLGen DataSource” is a defect and we have logged a defect report. We will try with XML serializer to resolve this issue. If it is not possible we will give you a custom event to serialize the object. The fix for this issue is estimated to be available on November 29, 2013.

I'll keep this thread updated...

JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 30-Nov-2013 14:18:51   

They are not going to solve it:

We appreciate your patience. We have tried XML Serializer to serialize the data source. But we are unable to serialize the Data source. So we have provided the Custom event to serialize the data source as we promised. The patch for the Custom Serialize Event can be downloaded from the following .....

The example they have supplied contains some horrible code. I'll try to escalate the issue.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 02-Dec-2013 10:36:36   

If you need help from us, let us know.

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 02-Dec-2013 22:05:49   

Frans, that would be nice. What do you suggest?

What they are proposing is that I write my own serializer each time I need it. That is what the example they have send me shows. My escalation resulted in the following:

We are sorry about the inconvenience caused.

We have already tried all the possibilities to serialize the llblgen data. But we are facing more difficulties while serializing the datasource. We have tried with JsonSerializer and Xml Serializer. By using JsonSerializer the datasource is serialized but while deserializing we have faced some problems like data which is deserialized is not in the correct format. In XmlSerialization also we are facing difficulties to deserialize the Xmlstring to the LLBLGen Data.

And we have also tried to serialize the datasource to entity collection and using EntityCollectionNonGeneric to deserialize those entities. But here also we are facing problems. So only we have provided the custom event to do the serialization in your end. In our sample we are using Binary Formatter. Here we have demonstrated how to use this event.

Please refer the below code snippet to use the event.

The snippet shows how to use the event. A code example on how to serialize an LLBLGen datasource (SelfServicing) is missing.

I think a UI tool should help make things easier. Their grid, when working, has great support for master-child relations. Perhaps serializing to support this is to complex.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 03-Dec-2013 10:17:35   

the event likely allows you to serialize the data to some format, which is then sent to the client, consumed there and displayed.

I think the real problem is that the client side of course wants to have this data in a given format so it can work with it, i.o.w.: the communication between server side of the control and the client side is defined by their protocol and dataformat.

So if the data comes back, what happens then? it will be in their format, and has to be stored in live objects, inside the datasource control bound to the grid, I presume. So this event is a little odd, as you have to serialize the data to something, but when it comes back from the client, you don't have to do anything apparently.

Doesn't add up.

Please ask them this: when you bind a datatable to the grid in ajax mode, what does their code do? it can't do the same thing as they try to do with out collection, as the datatable is bound through its dataview control, which isn't serializable either. I.o.w.: they have special code in place for that. If they say they don't, they're lying, as there's no way a dataview is serializable.

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 03-Dec-2013 12:02:33   

As an example Syncfusion composed a sln with the following Default.aspx. I wish they would habe composed an example based on the LLBL example I have provided.

It shows how the exchange of data between client and server can be programmed. Probably their internal code follows the same mechanism.

I don't see myself programming this, each time I want to use their grid in combination with LLBLGen. Then I will probably stop using the product for this purpose.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Syncfusion.Web.UI.WebControls.Grid.Grouping;
using Syncfusion.Web.UI.WebControls.Shared;
using System.Data;
using System.Data.SqlClient;
using Syncfusion.Grouping;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Syncfusion.Web.UI.WebControls.Shared.Common;
namespace SampleLLBLGen
{
    public partial class _Default : Page
    {
        SqlConnection myConnection = null;
        SqlDataAdapter myDataAdapter = null;
        DataSet myDataSet = null;
        ArrayList myList = new ArrayList();
        string ConnectionString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;Integrated Security=True";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                GetData();
        }

        private void GetData()
        {
            try
            {
                myConnection = new SqlConnection(ConnectionString);
                myDataAdapter = new SqlDataAdapter("SELECT * FROM Employees", myConnection);
                myDataSet = new DataSet();
                myDataAdapter.Fill(myDataSet);
                DataTable myDataTable = myDataSet.Tables[0];
                this.GridGroupingControl1.DataSource = myDataTable;
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            this.GridGroupingControl1.OnDataSourceSerialization += GridGroupingControl1_OnDataSourceSerialization;
        }

        void GridGroupingControl1_OnDataSourceSerialization(object sender, Syncfusion.Web.UI.WebControls.Grid.Grouping.SerializationEventArgs e)
        {
            if (e.ConvertionType == Syncfusion.Web.UI.WebControls.Grid.Grouping.ConvertionType.Serialization)
            {
                if (e.DataSource != null)
                {
                    MemoryStream strSerialize = new MemoryStream();
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(strSerialize, e.DataSource);
                    e.SerializedValue = CompressData(strSerialize);
                }
                e.IsHandled = true;
            }
            else if (e.ConvertionType == Syncfusion.Web.UI.WebControls.Grid.Grouping.ConvertionType.Deserialization)
            {
                object emp = null;
                byte[] btCompressedData = Convert.FromBase64String(e.SerializedValue);
                MemoryStream strDecompress = new MemoryStream(btCompressedData);
                CompressedStreamReader csrDecompressor = new CompressedStreamReader(strDecompress, true);
                byte[] btDecompressedData = csrDecompressor.ReadToBuffer();
                strDecompress.Close();

                // Deserialize decompressed data to object
                MemoryStream strDeserialize = new MemoryStream(btDecompressedData);
                BinaryFormatter bf = new BinaryFormatter();
                emp = bf.Deserialize(strDeserialize);
                strDeserialize.Close();
                e.DataSource = emp;
                e.IsHandled = true;
            }
        }

        private static string CompressData(MemoryStream strSerialize)
        {
            // Read serialized data into raw-data buffer
            int nRawDataLen = (int)strSerialize.Length;
            byte[] btRawData = new byte[nRawDataLen];
            strSerialize.Position = 0;
            strSerialize.Read(btRawData, 0, nRawDataLen);
            strSerialize.Close();

            //// Compress serialized raw-data
            MemoryStream strCompress = new MemoryStream();
            CompressedStreamWriter cswCompressor = new CompressedStreamWriter(strCompress, true, CompressionLevel.Best, false);
            cswCompressor.Write(btRawData, 0, nRawDataLen, true);

            //// Read compressed data from stream into compressed-data buffer
            int nCompressedDataLen = (int)strCompress.Length;
            byte[] btCompressedData = new byte[nCompressedDataLen];
            strCompress.Position = 0;
            strCompress.Read(btCompressedData, 0, nCompressedDataLen);
            strCompress.Close();

            //Convert into Base64
            string sData = Convert.ToBase64String(btCompressedData);
            return sData;
        }

    }
}
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 04-Dec-2013 15:51:49   

Most of the example they've given is about fetching the datatable and compression. The compression is generic, so you can use it as well, it seems.

this line: bf.Serialize(strSerialize, e.DataSource);

serializes the data into the stream. If e.DataSource is the control, you can obtain the actual collection from that and pass it to the Serialize method instead of the e.DataSource.

However this data arrives the client in the browser. How that js code is then able to deserialize this data is beyond me. IMHO they rely here on the fact the dataset serializes to xml regardless of whether you use binary serialization or not, so they unpack the binary blob which is actually xml on the client and (speculation, but there's IMHO not really any other explanation) as the format is known (dataset xml) they can consume it.

So if you serialize a collection to binary with this code, it's IMHO not really going to work on the client (as javascript has to deserialize the binary data to entities wink )

But it depends on what e.DataSource is. I find it a little odd that they do it this way, because the internal format of how the server side sends data to the client should be independent from the data objects bound to the grid.

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 04-Dec-2013 16:04:47   

They have tried to make their method work in an LLBLGen example I supplied. The example is based on Selfservice mode.

This afternoon I received a zip file with an avi in it. The avi shows the debug process. It appears that in their attempt to solve the problem, they deserialize using the Selfservice datasource and try to serialize using the Adapter datasource methods.

I've send a reply explaining this. Hope this will help them to solve it.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 04-Dec-2013 16:46:06   

That is indeed problematic... hopefully they'll manage to get it working so you can proceed!

Frans Bouma | Lead developer LLBLGen Pro
JayBee
User
Posts: 269
Joined: 28-Dec-2006
# Posted on: 06-Dec-2013 16:03:26   

Update:

We have tried with Self Servicing mode and we are able to serialize and deserialize the LLBGen data source using XML. We have referred from below link.

http://www.llblgen.com/documentation/4.1/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_xmlsupport.htm

We are facing issue in providing a complete runnable sample for LLBgen datasource. We are analysing on this since the event “OnDataSourceSerialization” will trigger for datasource and its source list, the deserialization is not proper. We will update you with proper details on 9 Dec 2013.

1  /  2