【问题标题】:help with parsing json in .net帮助解析 .net 中的 json
【发布时间】:2011-09-13 09:52:11
【问题描述】:

我需要帮助解析这个 json,在这个 sn-p 中只有三个项目,但列表上升到 2000 左右。

 {"1":
        {"Latitude":52.1643540,
         "Longitude":-2.154353,
         "Name":"AAA"
         },
     "2":
        {"Latitude":53.13,
         "Longitude":-2.13445,
         "Name":"BBB"
        },
     "3":
        {"Latitude":55.143243,
         "Longitude":-2.45234,
         "Name":"CCC"
        }}

我想生成一个“Place”对象列表,并且我希望将数字用作 ID 例如,具有 PlaceId 纬度、经度、名称属性的 Place 类。

给出第一个列表元素:

place.PlaceId = 1
place.Latitude = 52.1643540
place.Longitude = 2.154353
place.Name = "AAA"

【问题讨论】:

  • 您的问题是什么?您目前如何解析 JSON?

标签: c# .net


【解决方案1】:

您是否尝试过使用Json.NET?您可以在 this 以前的 SO 帖子中找到示例。

【讨论】:

    【解决方案2】:

    如果您能够更改该 JSON,那么我会选择 James 的回答,但如果事实证明您不能,事情会变得更复杂。我无法找到一个 JSON 序列化程序,它可以理解该格式,并将 JSON 中的索引号作为属性名称。然而,它似乎是有效的,并且我尝试过的所有浏览器都很好理解。

    我认为您最好的选择是使用 .net 的 Javascript 库(其中有几个,但我喜欢 IronJS)。使用它,您可以执行 JSON 并读出结果。下面是一些从文件中读取 JSON 并将结果写入控制台的示例代码。

    public class Place
    {
        public int ID { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public string Name { get; set; }
    }
    
    
    class Program
    {
        static void Main(string[] args)
        {
            var ctx = new IronJS.Hosting.CSharp.Context();
            string json;
            using (TextReader reader = File.OpenText("array_items.txt"))
            {
                json = reader.ReadToEnd();
            }
    
            CommonObject result= (CommonObject)ctx.Execute("var x=" + json);
            Dictionary<uint,BoxedValue> indexes = new Dictionary<uint,BoxedValue>();
            result.GetAllIndexProperties(indexes, uint.MaxValue);
            List<Place> places = new List<Place>();
    
            foreach (uint idx in indexes.Keys)
            {
                Place p = new Place();
                p.ID = (int)idx;
                p.Name = (string)indexes[idx].Object.Members["Name"];
                p.Latitude = (double)indexes[idx].Object.Members["Latitude"];
                p.Longitude = (double)indexes[idx].Object.Members["Longitude"];
                places.Add(p);
            }
    
            foreach (Place place in places)
            {
                Console.WriteLine("ID = {0}", place.ID);
                Console.WriteLine("Name = {0}", place.Name);
                Console.WriteLine("Latitude = {0}", place.Latitude);
                Console.WriteLine("Longitude = {0}", place.Longitude);
            }
    
            Console.ReadKey();
        }
    }
    

    但是,您确实需要在这里小心。根据您运行的位置,这可能会使您容易受到脚本注入攻击。最好扫描 JS 以查找可能有害的脚本(例如,任何不属于数字且不在引号内的内容)。

    【讨论】:

      【解决方案3】:

      您好,如果您无法更改 JSON,您可以通过执行以下操作对其进行反序列化:

          var serializer = new JavaScriptSerializer();
          var deserializedDictionary = serializer.Deserialize<Dictionary<string, PlaceDetails>>(jsonString);
      
          var result = new List<Place>();
      
          foreach (var key  in deserializedDictionary.Keys)
          {
              result.Add(new Place(key, deserializedDictionary[key]));
          }
      

      所需课程:

          public class PlaceDetails
          {
              public float Latitude { get; set; }
              public float Longitude { get; set; }
              public string Name { get; set; }
          }
      
          public class Place
          {
              public Place(string placeID, PlaceDetails placeDetails)
              {
                  this.PlaceID = Convert.ToInt32(placeID);
                  this.Latitude = placeDetails.Latitude;
                  this.Longitude = placeDetails.Longitude;
                  this.Name = placeDetails.Name;
              }
      
              public int PlaceID { get; set; }
              public float Latitude { get; set; }
              public float Longitude { get; set; }
              public string Name { get; set; }
          }
      

      您仍然需要对 System.Web.Extensions.dll 的引用并使用 System.Web.Script.Serialization 命名空间。

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        尝试去梨化。以下是您可能会有所帮助的帖子:

        C# automatic property deserialization of JSON

        Parse JSON in C#

        【讨论】:

          【解决方案5】:

          我会将您的 JSON 格式更改为如下所示:

          [
              {
                  "PlaceID" : 1,
                  "Latitude" :52.1643540,
                  "Longitude" :-2.154353,
                  "Name" :"AAA"
              },
              {
                  "PlaceID" : 2,
                  "Latitude":53.13,
                  "Longitude":-2.13445,
                  "Name":"BBB"
              },
              {
                  "PlaceID" : 3,
                  "Latitude":55.143243,
                  "Longitude":-2.45234,
                  "Name":"CCC"
              }
          ]
          

          然后我会使用以下内容:

          public class Place
          {
              public int PlaceID { get; set; }
              public float Latitude { get; set; }
              public float Longitude { get; set; }
              public string Name { get; set; }
          }
          

          要反序列化我会使用:

          JavaScriptSerializer serializer = new JavaScriptSerializer();
          var listOfPlaces = serializer.Deserialize<List<Place>>(jsonString);
          

          为了使用 JavaScriptSerializer,您需要引用 System.Web.Extensions.dll 并使用 System.Web.Script.Serialization 命名空间。

          【讨论】:

          • 一共有2000多条,改json会非常繁琐。
          • 对不起,我认为它可能是从某个地方生成的,我添加了另一个答案,应该可以帮助您解决问题。
          【解决方案6】:

          是这样的吗:

             public class Place
              {
          
                  public string ID { get; set; }
                  public string Name { get; set; }
                  public float Latitude { get; set; }
                  public float Longitude { get; set; }
          
              }
          private void Run()
          {
              List<Place> places = new List<Place>();
              JObject jObject = JObject.Parse(json);
              foreach (var item in jObject)
              {
                  JToken jPlace = jObject[item.Key];
                  float latitude = (float)jPlace["Latitude"];
                  float longitude = (float)jPlace["Longitude"];
                  string name = (string)jPlace["Name"];
                  places.Add(new Place { ID = item.Key, Name = name, Latitude = latitude, Longitude = longitude });
          
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-14
            • 1970-01-01
            • 1970-01-01
            • 2021-11-01
            • 2018-12-11
            • 1970-01-01
            • 1970-01-01
            • 2011-07-05
            相关资源
            最近更新 更多