【问题标题】:Accessing properties with a dot in their name访问名称中带有点的属性
【发布时间】:2016-04-02 17:26:46
【问题描述】:

我正在尝试反序列化 JSON。我的根对象有一个属性“en.pickthall”。我正在使用动态类型来读取我的 JSON。我以为我可以取消“。”在属性中,因为它是一个本地 JSON 文件,但是必须有某种方式来访问这样的属性

var result = App_Code.FileIOHelper.ReadFromDefaultFile("ms-appx:///Assets/en.pickthall.json");

dynamic stuff = JsonConvert.DeserializeObject(result);

foreach(var x in stuff.(en.pickthall)) //Tried this intellisense didn't like it
{

}

【问题讨论】:

标签: c# json json.net


【解决方案1】:

您可以创建一个根类来反序列化并使用JsonProperty

public class Root
{
    // Use the proper type instead of object
    [JsonProperty(PropertyName = "en.pickthall")]
    public IEnumerable<object> EnPickthall { get; set; } 

    public Root() { }
}

如下使用

Root stuff = JsonConvert.DeserializeObject<Root>(result);

foreach(var x in stuff.EnPickthall)
{

}

【讨论】:

    【解决方案2】:

    您可以不序列化为动态,而是序列化为JObject,然后通过

    访问您的属性
    JObject stuff = JsonConvert.DeserializeObject<JObject>(Jsonstring);
    var x = stuff.Value<String>("my.property")
    

    【讨论】:

    • 无论出于何种原因,我无法让这段代码与 Json.NET 12.0.1 一起使用,我不得不使用 var x = stuff.SelectToken("my.property").Value&lt;String&gt;();
    【解决方案3】:

    C# 没有任何引用标识符的方式。如果它不是一个有效的标识符,你唯一的选择就是反射。

    但是,您的 JSON 反序列化器返回的对象可能会更改标识符以使它们在 C# 中可用 - 您可能希望枚举所有属性以检查是否是这种情况。带有索引器的动态对象也可能是一种解决方案(例如允许stuff["en.pickthall"])。

    另一种选择是更改序列化程序映射属性的方式。例如,Newtonsoft.Jsoft 允许您使用 IContractResolver 自定义它。以这种方式很容易将 . 替换为更符合 C# 的东西。

    【讨论】:

      【解决方案4】:

      我知道你说你使用动态类型进行 JSON 反序列化, 但我只是想指出,有一个 .NET RESTful 客户端也支持静态模型定义.对于您或其他任何人在搜索 C# REST 调用中属性名称中的点问题的答案时遇到此响应。

      从新发布的 RestSharp 106.1.0 开始(我的意思是这个版本,因为刚刚添加了此支持),它可以通过 DeserializeAs 属性处理名称中带有点的重命名属性。例如,当我使用以下模型调用 ElasticSearch API 进行 _cat 调用时:

      public class CatResponse
      {
          public string index { get; set; }
          ...
          [DeserializeAs(Name = "docs.count")]
          public string docscount { get; set; }
      }
      

      实际上现在将反序列化为 docscount 的 docs.count 属性取回:

       var resource = $"_cat/indices/{indexPattern}?format=json&pretty=true";
      
       var request = new RestRequest(resource, Method.GET);
       var response = client.Execute<List<CatResponse>>(request);
      

      这种支持是开箱即用的,不需要使用我也听说过的 Newtonsoft.Json.JsonSerializer 是解决这个问题的一个可能的解决方案,但我无法解决工作。

      【讨论】:

        【解决方案5】:

        使用动态对象和 NewtonSoft.Json:

        dynamic json = JValue.Parse(result);
        
           int Opens = Convert.ToInt32(json.opens);
        
           int Clicks = Convert.ToInt32(json.clicks);
        
           string State = json.state;
        

        【讨论】:

        • 这并不能解决名称中带有点的属性的原始问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-05
        相关资源
        最近更新 更多