【问题标题】:Deserialize JSON property starting with @反序列化以 @ 开头的 JSON 属性
【发布时间】:2021-11-14 18:53:20
【问题描述】:

我正在编写一个 c# 控制台应用程序,我需要从 webapi 获取 som JSON 日期。 在大多数情况下,这可以正常工作,但是在我的一个 JSON 响应中,我得到了一个以 @ 开头的属性名称。我似乎无法弄清楚如何将该 JSON 属性放入 C# 对象中。

我的代码如下:

public class AlertResponse
{
    public string @class { get; set; }
    public string result { get; set; }
    public string info { get; set; }
}

public class AuthenticationResponse
{
    public string Access_token { get; set; }
}

class Test
{
    private static HttpClient client = new HttpClient();
    private static string BaseURL = "https://xxxxx.xxxx";

    public void Run()
    {
        client.BaseAddress = new Uri(BaseURL);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));

        AuthenticationResponse authenticationResponse = Login();

        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResponse.Access_token);

        AlertResponse OpenAlerts = GetOpenAlerts();
    }
    
    internal AlertResponse GetOpenAlerts()
    {
        var response = client.GetAsync("/api/v2/xxxxxxxxxxxxxxxxxx/alerts/open").Result;

        if (response.IsSuccessStatusCode)
        {
            return response.Content.ReadAsAsync<AlertResponse>().Result;
        }

        else
        {
            Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
        }

        return null;
    }
    
    private AuthenticationResponse Login()
    {
        string apiKey = "gdfashsfgjhsgfj";
        string apiSecretKey = "sfhsfdjhssdjhsfhsfh";

        var byteArray = new UTF8Encoding().GetBytes("public-client:public");
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
        var form = new FormUrlEncodedContent(new Dictionary<string, string> { { "username", apiKey }, { "password", apiSecretKey }, { "grant_type", "password" } });

        HttpResponseMessage tokenMessage = client.PostAsync("/auth/oauth/token", form).Result;

        if (tokenMessage.IsSuccessStatusCode)
        {
            return tokenMessage.Content.ReadAsAsync<AuthenticationResponse>().Result;
        }

        else
        {
            Console.WriteLine("{0} ({1})", (int)tokenMessage.StatusCode, tokenMessage.ReasonPhrase);
        }

        return null;
    }
}

我得到的 JSON 看起来像这样:

"AlertResponse": {
    "@class": "patch_ctx",
    "patchUid": "afdhgfhjdajafjajadfjadfjdj",
    "policyUid": "dsgafdhasfjafhdafhadfh",
    "result": "0x80240022",
    "info": "fdgdfhsfgjh"
}

我该如何解决这个问题?

最好的问候 冰川

【问题讨论】:

  • 您是否尝试过反序列化为匿名对象并查看其内部解析方式?
  • 注意:public string @class { get; set; } 仍然是一个名为 "class" 的属性,而不是 "@class" - @ 只是告诉编译器忽略标识符是保留关键字的事实;根据迈克尔的回答,您需要使用属性来更改序列化名称

标签: c# json .net json-deserialization datacontractserializer


【解决方案1】:

您使用的是 Newtonsoft.Json 还是 System.Text.Json?

在任何一种情况下,您都应该使用

来装饰@class 属性
//System.Text.Json
[JsonPropertyName("@class")]
public string class { get; set; }

//Newtonsoft.Json
[JsonProperty("@class")]
public string class { get; set; }

【讨论】:

  • Afaik 当我使用 HttpResponseMessage.Content.ReadAsAsync.result 我使用 System.Text.Json。但是,当我尝试装饰时,装饰似乎被忽略了我这样装饰: using System.Text.Json.Serialization; [JsonPropertyName("@class")] public string Class { get;放; }
  • 我写的代码应该可以工作。 dotnetfiddle.net/eqNQuA 你确定你设置了正确的 json 序列化器并与相应的属性兼容吗?
【解决方案2】:

我猜你正在寻找DataMemberAttributeDataContract

using System.Runtime.Serialization;

[DataContract]
public class AlertResponse
{
    [DataMember(Name = "@class")]
    public string Class { get; set; }
    [DataMember(Name = "result")]
    public string Result { get; set; }
    [DataMember(Name = "info")]
    public string Info { get; set; }
}

【讨论】:

  • 正是我想要的 :) 非常感谢
  • @Glacierdk 哪个答案对您有用?您已接受其他答案并感谢此帖
  • 我点错了 :S 我已经更正了 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多