How serialize List < List < > > from WebService ASMX ?

DranakDranak FRMember ✭✭
edited October 2017 in Xamarin.Forms

Hi,

I come to you because I have issues I don't really understand and I don't manage to solve the problem.

1- DataTable

So, I have a Webservice ASMX who use DataTable (but with Xamarin Forms I can't use it because he doesn't know System.Data).

I have this reference ( just the part of DataTable )

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2102.0")]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="tempuri.org")]
    public partial class getTableAnswerResponseGetTableAnswerResult : object, System.ComponentModel.INotifyPropertyChanged {

        private System.Xml.XmlElement[] anyField;

        private System.Xml.XmlElement any1Field;

        /// <remarks/>
        [System.Xml.Serialization.XmlAnyElementAttribute(Namespace=".w3.org/2001/XMLSchema", Order=0)]
        public System.Xml.XmlElement[] Any {
            get {
                return this.anyField;
            }
            set {
                this.anyField = value;
                this.RaisePropertyChanged("Any");
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAnyElementAttribute(Namespace="urn:schemas-microsoft-com:xml-diffgram-v1", Order=1)]
        public System.Xml.XmlElement Any1 {
            get {
                return this.any1Field;
            }
            set {
                this.any1Field = value;
                this.RaisePropertyChanged("Any1");
            }
        }

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName) {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null)) {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }
    }

So I remplace System.Xml.XmlElement by System.Xml.Linq.XElement ( not like this thread on this forum "Xamarin Forms adding Service Reference to PCL - no XmlElement in System.Xml error" ( I can't add link) tell to remplace it by System.Xml.Linq.XDocument).

And it "works" ( I can compile and the WebMethod ( setQuery () ) I try to use work properly )

2- MyDataTable

But now I want ( and need) to use DataTable, so I created my own like this ( on WebService)

MyDataTable Class

[XmlRoot(ElementName = "MyDataTable")]
public class MyDataTable
{
    [XmlElement("TableName")]
    public String TableName { get; set; }

    [XmlElement("Rows")]
    public List<Row> Rows { get; set; }

    public MyDataTable()
    {
        TableName = "non renseigné";
        Rows = new List<Row>();
    }

    public MyDataTable(String tableName, List<Row> table)
    {
        TableName = tableName;
        //Rows = table[0];
        Rows = new List<Row>();

    }

}

Row Class

    [XmlRoot(ElementName = "Row")]
    public class Row
    {
        [XmlElement(Type = typeof(List<ItemObject>), ElementName = "Columns")]
        public List<ItemObject> Columns { get; set; }

        public Row(List<ItemObject> columns)
        {
            Columns = columns;
        }

        public Row()
        {
            Columns = new List<ItemObject>();
        }
    }

ItemObject Class

[XmlRoot(ElementName = "ItemObject")]
public class ItemObject
{

    [XmlElement(Type = typeof(String), ElementName = "ColumnName")]
    public String ColumnName { get; set; }

    [XmlElement(Type = typeof(object), ElementName = "Valeur")]
    public object Valeur { get; set; }

    [XmlElement(Type = typeof(String), ElementName = "Type")]
    public String Type { get; set; }


    public ItemObject()
    {

    }

    public ItemObject(String columnName, object valeur, string type)
    {
        this.Valeur = valeur;
        this.Type = type;
        this.ColumnName = columnName;

    }

}

I update my reference on Xamarin Forms cross platform project and I don't have the System.Xml.XmlElement issue because I think he "can" serialize my "complexe object" now.

But when I launch it I can't more use the method which I used before.
I have a exception I can't even give you because I think even VS don't understand what he is doing.
( he propose me to debug this exception with another debugger ....)

So I search a answer , I try lot of thing and I conclude by Xamarin don't like List<List<>> ( even if it is to
encapsulate in an object. In this case it Row)

I try to remplace List my List into MyDataTable Class and it's work ( I can use setQuery() method)

So what I can do with my MyDataTable class ?
Obviously the first implementation of this class work properly with an ASP.net project

Thank to you to read this long thread and maybe to help me :smiley::wink:

Dranak

ps: I am french so if my english is a little bit eyesight, sorry. :blush:

Posts

  • ShahidAli.7296ShahidAli.7296 USMember ✭✭

    Hi Dranak,

    I hope I understood your issue correctly, basically you are trying to deserialise you result from web service call on your client, if that's the case then I would encourage you to return the data as Json from your web service . Then on you client side call from your app, you can easily deserialise your json collection using "JsonConvert" as:

    List yourlistName = JsonConvert.DeserializeObject<List>(await response.Content.ReadAsStringAsync());

  • DranakDranak FRMember ✭✭
    edited October 2017

    Hi @ShahidAli.7296

    Thanks for your quickly answer :)

    I don't personally deserialise my object from to WebService to Xamarin.

    Normally, it's reference's duty into my Xamarin project but the reference he autogenerate deserialise not properly the object List when Row has List in his attributes. ( this is what I have concluded )

    So what I'm trying to do is to understand "list of Row" to Xamarin.

    I do not prefer to modify the generated reference file (after if it is what to do ...) so I think it would be necessary to modify my classes in my WebService but how?

    To be able to move forward, I modified the MyDataTable class instead of having List I go through a List but this is not a very nice code and not practical, for me at least.

    With that my calls of the methods of my WebService works, because it deserialize well my objects.( For me it's that)

    If the solution is to use JSON files I would do it but I have no idea how to do because for now the references of my webservices are automatically generated ....

    I hope you will understand what I am trying to do :smile:

    Dranak

  • ShahidAli.7296ShahidAli.7296 USMember ✭✭

    Things to bare in mind here:

    Your asmx service call should return a json response, it could be any type i.e. from returning a simple string response to returning a complex object or collection of objects, as long as it get returned as json. You could easily return Json using the following code from your api.

    [WebMethod]
    [ScriptMethod(UseHttpGet=true ,ResponseFormat = ResponseFormat.Json)]
    public void HelloWorld()
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        Context.Response.Clear();
        Context.Response.ContentType = "application/json";           
        HelloWorldData data = new HelloWorldData();
        data.Message = "HelloWorld";
        Context.Response.Write(js.Serialize(data));
    }
    

    Note: for de-serialisation to work, both the types on your client (app) and server (asmx webservice, web api) side must be the same, more specifically the same name with similar properties. the sample class below should be the same on both sides.
    Public class Student
    {
    public int ID {get;set;}
    public string Name {get;set;}
    }

  • DranakDranak FRMember ✭✭
    edited October 2017

    Ok I will try this but before just few things:

    • Are you sure Xamarin Forms understand Json ? Because normaly everyone can deserialise List of List ( like my asp.net app) so it would not shock me that xamarin does not know how to do it.
    • The second one I don't have any "mirror class" in my clients (asp.net or Xamarin) because I can use directly the object of my Webservice ( when he deserialise well my object obviously .........)

    There are nothing more easier to do for Xamarin deserialise properly my objects ?
    Because all redo with JSON for a single object because of Xamarin, it's look like overkill ...

    Dranak

    ps:
    It makes me crazy that xamarin does not handle system.Data and does not know deserialise some simple objects :disappointed::cry:

  • ShahidAli.7296ShahidAli.7296 USMember ✭✭

    Are you sure it can't handle System.Data?

    developer.xamarin.com/api/namespace/System.Data/

  • DranakDranak FRMember ✭✭

    I pretty sure because when I put the using in my project, Vs tell me this doesn't exist :( (obviously in other project he find it)

    For example this topic forums.xamarin.com/discussion/27193/system-data-dll-with-xamarin-forms

    Dranak

Sign In or Register to comment.