Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

json.net - .NET WebApi + DataTable

I'm building a .NET WebApi project. One of my ApiControllers returns a datatable. In JSON format, it all looks good, but the XML-format contains so much junk I don't need.

So, I was thinking, let's write my own XML-serialization. For doing this I've made a new class that implements IXmlSerializable. It looks like this:

public class MyDataTable : IXmlSerializable
{
    public MyDataTable(DataTable datatable)
    {
        this.Data = datatable;
    }


    public void WriteXml(XmlWriter writer)
    {

        writer.WriteStartElement("Test");
        writer.WriteElementString("T", "hello world");
        writer.WriteEndElement();
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        throw new NotImplementedException();
    }

    public DataTable Data { get; set; }
}

Now my XML looks great, but my JSON isn't. The JSON looks like:

{"Data":[{"id":1,"name":"John"},{"id":2,"name":"Julia"}]}

What I really want is this:

[{"id":1,"name":"John"},{"id":2,"name":"Julia"}]

Is there an easy way to remove the "Data"-string from the JSON-result, without rewriting the whole thing? Or is there a better solution than this one?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have written my own datatable serialization to achieve my goal.

For the interested folk:

[JsonConverter(typeof(DataTableConverter))]
[XmlRoot("Result")]
public class MyDataTable : IXmlSerializable
{
    public MyDataTable(DataTable datatable)
    {
        this.Data = datatable;
    }


    public void WriteXml(XmlWriter writer)
    {
        foreach (DataRow row in Data.Rows)
        {
            writer.WriteStartElement(Data.TableName);
            foreach (DataColumn column in row.Table.Columns)
            {
                writer.WriteElementString(column.ColumnName, row[column].ToString());
            }
            writer.WriteEndElement();
        }
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        throw new NotImplementedException();
    }
    public DataTable Data { get; set; }
}

And a custom JSON converter:

public class DataTableConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return typeof(MyDataTable).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        MyDataTable myDataTable = value as MyDataTable;
        DataTable dt = myDataTable.Data;

        writer.WriteStartArray();

        foreach (DataRow row in dt.Rows)
        {
            writer.WriteStartObject();
            foreach (DataColumn column in row.Table.Columns)
            {
                writer.WritePropertyName(column.ColumnName);
                serializer.Serialize(writer, row[column]);
            }
            writer.WriteEndObject();
        }

        writer.WriteEndArray();
    }
}

Implement the new DataTable class like this:

public class ValuesController : ApiController
{
    // GET api/values
    public MyDataTable Get()
    {
        DataTable dt = new DataTable();
        dt.TableName = "info";
        using (SqlConnection cn = new SqlConnection("Data Source=(local);Initial Catalog=ApiPoc;Integrated Security=true;"))
        {
            cn.Open();
            using (SqlCommand cm = new SqlCommand("select * from employee",cn))
            {
                SqlDataReader dr = cm.ExecuteReader();
                dt.Load(dr);
            }
        }
        MyDataTable md = new MyDataTable(dt);
        return md;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...