【问题标题】:Deserializing a JSON file with JavaScriptSerializer()使用 JavaScriptSerializer() 反序列化 JSON 文件
【发布时间】:2011-07-27 00:17:37
【问题描述】:

我将反序列化的 json 文件的结构如下所示;

{
    "id" : "1lad07",
    "text" : "test",
    "url" : "http:\/\/twitpic.com\/1lacuz",
    "width" : 220,
    "height" : 84,
    "size" : 8722,
    "type" : "png",
    "timestamp" : "Wed, 05 May 2010 16:11:48 +0000",
    "user" : {
        "id" : 12345,
        "screen_name" : "twitpicuser"
    }
}

我创建了一个类,该类将文件名作为 JavaScriptSerializer 的属性。我将用来反序列化 json 的代码如下;

            using (var reader = new StreamReader(twitpicResponse.GetResponseStream())) {


                var responseBody = reader.ReadToEnd();
                var deserializer = new JavaScriptSerializer();
                var results = deserializer.Deserialize<Response>(responseBody);

            }

我的问题是如何读取 json 文件中的用户字段。如下所示;

"user" : {
    "id" : 12345,
    "screen_name" : "twitpicuser"
}

它有子属性和值。我如何在我的 Response 类中命名它们。我的响应类现在看起来像这样;

public class Response {

    public string id { get; set; }
    public string text { get; set; }
    public string url { get; set; }
    public string width { get; set; }
    public string height { get; set; }
    public string size { get; set; }
    public string type { get; set; }
    public string timestamp { get; set; }

}

最好的情况是什么?

【问题讨论】:

  • 谢谢,您的问题实际上有我在其中寻找的答案。

标签: c# json deserialization javascriptserializer


【解决方案1】:
  1. 您需要创建一个保存用户值的类,就像响应类User
  2. 向响应类“用户”添加一个属性,该属性具有用户值User 的新类的类型。

    public class Response {
    
        public string id { get; set; }
        public string text { get; set; }
        public string url { get; set; }
        public string width { get; set; }
        public string height { get; set; }
        public string size { get; set; }
        public string type { get; set; }
        public string timestamp { get; set; }
        public User user { get; set; }
    
    }
    
    public class User {
    
        public int id { get; set; }
        public string screen_name { get; set; }
    
    }
    

一般来说,您应该确保 json 的属性类型和您的 CLR 类匹配。 您尝试反序列化的结构似乎包含多个数值(很可能是 @987654324 @)。我不确定JavaScriptSerializer 是否能够自动将数字反序列化为字符串字段,但无论如何您都应该尝试使您的 CLR 类型尽可能接近实际数据。

【讨论】:

  • @ntziolis 感谢您的回复。所以我猜 Reponse 类中的 id 属性也应该是 int ?
  • @ntziolis:如果我没记错的话,你需要添加一个无参数的公共构造函数
  • @skarmats 不,JavaScriptSerializer 和相应的解析器不需要您显式定义构造函数,它比 XmlSerializer 简单得多。
  • @ntziolis:我永远不会习惯这些差异 :d 感谢您提供信息 :)
  • @skarmats 实际上,JavaScriptSerializer 是其他序列化程序的兄弟,它没有在 .NET 基础架构中的任何地方使用,例如WCF(即使使用 json 作为格式)。它只是作为一种在 WCF 和其他框架场景之外序列化/反序列化 json 的快速而简单的方法提供。
【解决方案2】:

假设您不想创建另一个类,您可以随时让反序列化器为您提供键值对字典,如下所示:

string s = //{ "user" : {    "id" : 12345,    "screen_name" : "twitpicuser"}};
var serializer = new JavaScriptSerializer();
var result = serializer.DeserializeObject(s);

你会得到一些东西,你可以在哪里做:

var userId = int.Parse(result["user"]["id"]); // or (int)result["user"]["id"] depending on how the JSON is serialized.
// etc.

在调试器中查看result,看看里面有什么。

【讨论】:

  • 将数组索引到结果中是一个很好的(事后看来很明显)。谢谢!
  • 我收到错误:无法使用 [] 将索引应用于“对象”类型的表达式
  • 改变 var 结果 = serializer.DeserializeObject(s);动态结果 = serializer.DeserializeObject(s);在 .net 4+ 中为我工作
【解决方案3】:

对于.Net 4+:

string s = "{ \"user\" : {    \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}}";

var serializer = new JavaScriptSerializer();
dynamic usr = serializer.DeserializeObject(s);
var UserId = usr["user"]["id"];

对于 .Net 2/3.5: 此代码应适用于 1 级 JSON

samplejson.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%
string s = "{ \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}";
var serializer = new JavaScriptSerializer();
Dictionary<string, object> result = (serializer.DeserializeObject(s) as Dictionary<string, object>);
var UserId = result["id"];
 %>
 <%=UserId %>

对于 2 级 JSON:

sample2.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%
string s = "{ \"user\" : {    \"id\" : 12345,    \"screen_name\" : \"twitpicuser\"}}";
var serializer = new JavaScriptSerializer();
Dictionary<string, object> result = (serializer.DeserializeObject(s) as Dictionary<string, object>);
Dictionary<string, object> usr = (result["user"] as Dictionary<string, object>);
var UserId = usr["id"];
 %>
 <%= UserId %>

【讨论】:

    【解决方案4】:

    使用 id 字段和 screen_name 字段创建子类 User,如下所示:

    public class User
    {
        public string id { get; set; }
        public string screen_name { get; set; }
    }
    
    public class Response {
    
        public string id { get; set; }
        public string text { get; set; }
        public string url { get; set; }
        public string width { get; set; }
        public string height { get; set; }
        public string size { get; set; }
        public string type { get; set; }
        public string timestamp { get; set; }
        public User user { get; set; }
    }
    

    【讨论】:

      【解决方案5】:
        public class User : List<UserData>
          {
      
              public int id { get; set; }
              public string screen_name { get; set; }
      
          }
      
      
          string json = client.DownloadString(url);
          JavaScriptSerializer serializer = new JavaScriptSerializer();
          var Data = serializer.Deserialize<List<UserData>>(json);
      

      【讨论】:

        【解决方案6】:
        //Page load starts here
        
        var json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new
        {
            api_key = "my key",
            action = "categories",
            store_id = "my store"
        });
        
        var json2 = "{\"api_key\":\"my key\",\"action\":\"categories\",\"store_id\":\"my store\",\"user\" : {\"id\" : 12345,\"screen_name\" : \"twitpicuser\"}}";
        var list = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<FooBar>(json);
        var list2 = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<FooBar>(json2);
        
        string a = list2.action;
        var b = list2.user;
        string c = b.screen_name;
        
        //Page load ends here
        
        public class FooBar
        {
            public string api_key { get; set; }
            public string action { get; set; }
            public string store_id { get; set; }
            public User user { get; set; }
        }
        
        public class User
        {
            public int id { get; set; }
            public string screen_name { get; set; }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-20
          • 1970-01-01
          • 2021-09-02
          • 2015-01-11
          相关资源
          最近更新 更多