0

Good Afternoon everyone, I am new on C#/Web Services and I am Trying to do the Following: I have a DataTable that in certain times has different number of columns, then I convert my datatable to a list as follow:

List<dynamic> lstHistReporteGlobal = new List<dynamic>();
foreach (DataRow row in dtReportesHistoricos.Rows)
{
  dynamic dyn = new ExpandoObject();
  lstHistReporteGlobal.Add(dyn);
  foreach (DataColumn column in dtReportesHistoricos.Columns)
  {
    var dic = (IDictionary<string, object>)dyn;
    dic[column.ColumnName] = row[column];
  }
}

Once I return the List on my web service I get the following error:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. System.Dynamic.ExpandoObject does not implement Add(System.Object). at System.Xml.Serialization.TypeScope.GetEnumeratorElementType(Type type, TypeFlags& flags) at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference) at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError) at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException(Type type) at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write8_ArrayOfAnyType(Object o) at Microsoft.Xml.Serialization.GeneratedAssembly.ListOfObjectSerializer.Serialize(Object objectToSerialize, XmlSerializationWriter writer) at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) --- End of inner exception stack trace --- at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces) at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue) at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream) at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues) at System.Web.Services.Protocols.WebServiceHandler.Invoke()

I don't understand why I can not return a dynamic list on my web service.

Someone can give me an idea to return my dynamic datatable as a list on a web service?

  • 1
    Are you aware that ASMX are an obsolete technology and perhaps there is something that is not able to handle? – Steve Sep 16 '19 at 21:44
  • It is not able to serialize the list that you are sending. You can maybe serialize it into a string using Newtonsoft. And then deserialize it after into a List or a DataTable. – billybob Sep 16 '19 at 21:47
  • – Steve, I am using this technology as a client request... some another idea? – rasecxxx Sep 16 '19 at 21:54

1 Answers1

0

You could serialize the DataTable directly into JSON and pass it to the endpoint service.

You could use something like this, to convert it directly into JSON, instead of a List. Here is a function that I tweaked on my project:

public static class DataTableExtensions
{
    public static string ToJson(this DataTable dataTable)
    {
        if (dataTable == null)
        {
            throw new ArgumentNullException(nameof(dataTable));
        }
        List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();

        foreach (DataRow row in dataTable.Rows)
        {
            Dictionary<string, object> item = new Dictionary<string, object>();
            foreach(DataColumn column in dataTable.Columns)
            {
                item.Add(column.ColumnName, Convert.IsDBNull(row[column]) ? null : row[column]);
            }
            list.Add(item);
        }

        return list.SerializeObject();
    }
}

This assumes that you will receive a string in the server endpoint. Afterward, you can deserialize the string that you received back to a list or a DataTable if you want.

You can use those 2 functions to serialize/deserialize:

billybob
  • 2,859
  • 6
  • 35
  • 55