通过JsonTextWriter正确解析JSON

时间:2013-04-01 09:21:57

标签: .net asp.net-mvc json kendo-ui

我在使用JSON网格绑定Kendo UI数据时遇到了困难,但在搜索此问题的解决方案时,我遇到了另一个问题。如何正确解析JSON以匹配@Petur Subev所提及的正确格式here.

我当前的JSON采用以下格式:

//{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null}
//{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0}

但正如指出它应该是这样的:

[{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null},
{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0},
{"No":null,"Desc":"asfasfasfskfjklajsfkjasklfjklasjfklajsfkljaklsfjklasjfkljasfkljlasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0}]

很难理解为什么会这样,因为我使用prebuilt来创建一个JSON,但我仍然得到了错误的帮助。

Model Code我有:

public object GetResult(string id)
{
    var sqlCom = new SqlCommand("SELECT [No],[Desc],[Date],[Height],[Final] FROM [cr_form] WHERE [uId]=@id;", sqlConn);
    sqlCom.Parameters.AddWithValue("@id", id);

    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    JsonWriter jsonWriter = new JsonTextWriter(sw);
    var rcrds = GETSQLRESULTS(sqlCom);

    try
    {
        int i = 0;
        if (rcrds != null || rcrds.HasRows)
        {
            //jsonWriter.WriteStartObject();
            while (rcrds.Read())
            {
                jsonWriter.WriteStartObject(); //Changed
                for (int j = 0; j < rcrds.FieldCount; j++)
                {
                    jsonWriter.WritePropertyName(rcrds.GetName(j)); // column name
                    jsonWriter.WriteValue(rcrds.GetValue(j)); // value in column
                }
                i++;
                jsonWriter.WriteEndObject(); //Changed
            }
            //jsonWriter.WriteEndObject();

        }

    }

    catch (Exception ex) { }
    return jsonWriter;
}
Controller

中的

public ActionResult GetRecords()
{
    var usrObj = new User();
    var jsnRslt = usrObj.GetResult(Session["Id"].ToString());

//After Changes in the Model I am getting it in the required Array format:
//{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null}
//{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0}
//{"No":null,"Des...

    return Json(jsnRslt, JsonRequestBehavior.AllowGet);            
}

添加WriteStartArray();

之后
{[{"No":null,"Desc":"asfasfasfasfasfasfasfasfasfasfasfasf","Date":"2013-03-27T00:00:00","Height":0,"Final":null},
{"No":null,"Desc":"etwetwetwetwet","Date":"2013-03-27T00:00:00","Height":0,"Final":0},
{"No":null,"Desc":"asfasfasfskfjklajsfkjasklfjklasjfklajsfkljaklsfjklasjfkljasfkljlasf","Date":"2013-03-27T00:00:00","Height":0,"Final":0},
{"No":null,"Desc":"hdfhdfhdfh","Date":"2013-04-04T00:00:00","Height":1,"Final":0}]}

2 个答案:

答案 0 :(得分:4)

为什么要在GetResult方法中构建JSON?为什么要编写这样的管道代码而不是将其留给框架?

您应该关注的是您的业务逻辑。

只需定义一个代表您想要返回的数据的模型(您可能需要根据数据库中的列类型调整模型属性的类型):

public class MyModel
{
    public int? No { get; set; }
    public string Desc { get; set; }
    public DateTime Date { get; set; }
    public int? Height { get; set; }
    public int? Final { get; set; }
}

然后让你的方法返回这个模型(事实上这个模型的集合更精确):

public IEnumerable<MyModel> GetResult(string id)
{
    string connectionString = "...";
    using (var conn = new SqlConnection(connectionString))
    using (var cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "SELECT [No],[Desc],[Date],[Height],[Final] FROM [cr_form] WHERE [uId]=@id;";
        cmd.Parameters.AddWithValue("@id", id);
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                yield return new MyModel
                {
                    No = GetValue(reader, "No"),
                    Desc = reader.GetString(reader.GetOrdinal("Desc")),
                    Date = reader.GetDateTime(reader.GetOrdinal("Date")),
                    Height = GetValue(reader, "Height"),
                    Final = GetValue(reader, "Final"),
                };
            }
        }
    }
}

private static int? GetValue(DbDataReader reader, string columnName)
{
    var columnIndex = reader.GetOrdinal(columnName);
    if (!reader.IsDBNull(columnIndex))
    {
        return reader.GetInt32(columnIndex);
    }
    return null;
}

注意我是如何删除tr / catch逻辑的,因为你没有在catch语句中做任何有用的事情,并且静默消耗这样的异常是个坏主意。

最后在你的控制器动作中:

public ActionResult GetRecords()
{
    var usrObj = new User();
    var jsnRslt = usrObj.GetResult(Session["Id"].ToString());
    return Json(jsnRslt, JsonRequestBehavior.AllowGet);
}

正如您在本示例中所看到的,您不应该担心管道和JSON。您应该使用强类型模型,并让框架为您执行序列化。

答案 1 :(得分:1)

看起来您只想在开始时致电WriteStartArray ...

示例代码:

using System;
using Newtonsoft.Json;

class Test
{
    static void Main()
    {
        using (var writer = new JsonTextWriter(Console.Out))
        {
            writer.WriteStartArray();
            for (int i = 0; i < 5; i++)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("Foo");
                writer.WriteValue(i);
                writer.WriteEnd();
            }
            writer.WriteEnd();
        }
    }
}

输出:

[{"Foo":0},{"Foo":1},{"Foo":2},{"Foo":3},{"Foo":4}]