【问题标题】:Parsing JSON correctly through JsonTextWriter通过 JsonTextWriter 正确解析 JSON
【发布时间】:2013-04-01 09:21:56
【问题描述】:

我在将JSON 数据与Kendo UI 网格绑定时遇到了困难,但在寻找解决这个问题的方法时,我遇到了另一个问题。 @Petur Subev here. 提到的如何正确解析 JSON 以匹配其正确格式。

我当前的 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}]

很难理解为什么会这样,因为我使用预构建函数来创建 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}]}

【问题讨论】:

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


    【解决方案1】:

    为什么要在 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。您应该使用强类型模型,让框架为您完成序列化。

    【讨论】:

      【解决方案2】:

      看起来你只是想一开始就打电话给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}]
      

      【讨论】:

      • 完成了,我想我已经得到了想要的结果。我只是有点困惑,为什么我在开始时得到一个起始括号 { 并在最后关闭 } .这是对还是错。我已经更新了我的问题,请看一下新的 JSON。
      • @Maven:我怀疑Json 方法本身会将您的数组包装在一个对象中——因此您返回的是一个包含数组的对象,而不仅仅是一个数组。鉴于您首先要调用 Json 方法,您肯定需要自己完成其余的 JSON 编码吗?正如 Darin 所说,您应该能够只返回一个集合。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多