【问题标题】:Unable to serialize json keyvaluepair无法序列化 json 键值对
【发布时间】:2016-04-16 10:50:48
【问题描述】:

我有 json,尝试使用 Newtonsoft.Json 对 json 进行反序列化,但我无法在列表中获取某些值。

这就是我的 json 的样子

{
    "status": "success",
    "msg": "success",
    "code": 1,
    "data": {
        "country": "India",
        "countryid": "766",
        "operator": "Airtel India",
        "operatorid": "1371",
        "connection_status": "99",
        "destination_msisdn": "919895070723",
        "destination_currency": "INR",
        "product_list": "100,200,300,330,350,440,500,1000",
        "service_fee_list": "0.00,0.00",
        "retail_price_list": "7.50,14.50,21.50,70.50",
        "wholesale_price_list": "6.05,12.03,29.97,59.85",
        "local_info_value_list": "100.00,1000.00",
        "local_info_amount_list": "87.00,175.00,887.00",
        "local_info_currency": "INR",
        "authentication_key": "16809",
        "error_code": "0",
        "error_txt": "Transaction successful",
        "nick_name": "eldho",
        "price_map": {
            "100": "7.50",
            "200": "14.50",
            "300": "21.50",
            "330": "23.50",
            "350": "25.00",
            "440": "31.50",
            "500": "35.50",
            "1000": "70.50"
        },
        "local_info": {
            "100": "87.00",
            "200": "175.00",
            "300": "264.00",
            "330": "290.40",
            "350": "350.00",
            "440": "387.20",
            "500": "442.00",
            "1000": "887.00"
        },
        "service_map": {
            "100": "0.00",
            "200": "0.00",
            "300": "0.00",
            "330": "0.00",
            "350": "0.00",
            "440": "0.00",
            "500": "0.00",
            "1000": "0.00"
        },
        "operator_logo": "https:\/\/fm.transfer-to.com\/logo_operator\/logo-1371",
        "promo_code": 0,
        "benef_id": "16598"
    }
}

更新:local_info 和 service_map 是动态数据

我通常使用Json2charp创建json模型类

我的序列化代码是这样的

using (var _client = new HttpClient())        
{        
    _client.BaseAddress = new Uri(baseServiceUri);

    var content = new FormUrlEncodedContent(new[] 
    {
        new KeyValuePair<string,string>("someparameter",token),
        new KeyValuePair<string,string>("id",myId.ToString()),        
    });

    var response = await _client.PostAsync(new Uri(baseAccessPoint, UriKind.Relative), content);

    if (!response.IsSuccessStatusCode)
    {
        throw new HttpRequestException(response.ReasonPhrase);
    }

    //I get value in this 
    var responseResult = await response.Content.ReadAsStringAsync();

    //Unable to deseralize it.
    return JsonConvert.DeserializeObject<BeneficoryMobileDTO>(responseResult, new JsonSerializerSettings()
    {
        //NullValueHandling = NullValueHandling.Ignore,
        Error = JsonDeserializeErrorHandler,    
    });
}

我的模型看起来像这样。

 [DataContract]
public class BeneficoryMobileDTO
{
    [DataMember]
    public string status { get; set; }

    [DataMember]
    public string msg { get; set; }

    [DataMember]
    public string code { get; set; }

    [DataMember(Name = "data")]
    public BeneficoryMobileDetailsDTO BeneficoryMobileDetails { get; set; }
}

public class BeneficoryMobileDetailsDTO
{
    //I have removed some property to show things that doesn't work

    //THIS CAN'T BE SERALIZED
    [DataMember(Name = "PriceMap")]
    public dynamic price_map { get; set; }

    //THIS CAN'T BE SERALIZED
    [DataMember(Name = "ServiceMap")]
    public dynamic service_map { get; set; }

    //THIS CAN'T BE SERALIZED 
    [DataMember(Name = "LocalInfo")]
    public object LocalInfo { get; set; }


    [DataMember]
    public int benef_id { get; set; }
}

只有 LocalInfo 、 ServiceMap 和 PriceMap 此属性获取 Null 值。除了它之外的所有东西都是序列化的。

请告诉我我做错了什么

【问题讨论】:

  • 数字是否总是相同(即 100、200、300、330 等)?

标签: c# json windows-phone-8 deserialization dotnet-httpclient


【解决方案1】:

问题的原因是属性的名称。它们不能在 C# 中直接用作标识符mustn't begin with a number (identifier-start-character)。所以这样的属性是无效的:

public string 100 { get; set; } // "100" is an invalid property name
// generates compiler error CS1519: Invalid token '100' in class, struct, or interface member declaration

json2csharp(我以前不知道;真是个好工具!)在生成以下类时给你一个提示:

public class PriceMap
{
    public string __invalid_name__100 { get; set; } // invalid hint
    public string __invalid_name__200 { get; set; }
    // other props omitted
}

要让反序列化成功,您可以做的是注释这些属性(请参阅documentation)并告诉 json.net 应该如何映射它们:

public class PriceMap
{
    [JsonProperty(PropertyName = "100")]
    public string _100 { get; set; }
    [JsonProperty(PropertyName = "200")]
    public string _200 { get; set; }
    // other props omitted
}

替代方案:

您不必使用由 json2csharp 生成的 PriceMap 等类,并且可以像您在问题中所做的那样坚持使用 dynamic。

基本上发生的问题只是属性的名称。结果始终为空,因为您通过 DataMember-attribute 告诉 json.net 它应该将 json 键 "PriceMap" 映射到名为 price_map 的属性。这不起作用,因为您的 json 中没有 json 键 "PriceMap"。相反,它被简单地称为"price_map"。所以删除DataMember-attribute,属性就会被正确映射。


附带说明:如果您不想离开 Visual Studio,有一个很酷的功能将 JSON 粘贴为类,它会为您自动生成必要的类:

【讨论】:

  • 这是动态生成的,我该如何映射它
  • 命名有问题。我的错误我以前没有发现这个。
  • 请更新您的答案,我可以将其标记为答案
猜你喜欢
  • 1970-01-01
  • 2012-02-19
  • 2016-02-17
  • 2014-08-04
  • 1970-01-01
  • 2016-12-30
  • 2016-10-08
  • 1970-01-01
相关资源
最近更新 更多