反序列化以 @ 开头的 JSON 属性

Posted

技术标签:

【中文标题】反序列化以 @ 开头的 JSON 属性【英文标题】:Deserialize JSON property starting with @ 【发布时间】: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" - @ 只是告诉编译器忽略标识符是保留关键字的事实;根据迈克尔的回答,您需要使用属性来更改序列化名称 【参考方案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】:

我猜你正在寻找DataMemberAttribute 和DataContract

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

以上是关于反序列化以 @ 开头的 JSON 属性的主要内容,如果未能解决你的问题,请参考以下文章

json 从遗留属性名称反序列化

是否有可能在反序列化时以某种方式捕获与任何 POCO 属性不匹配的 JSON 数据的其余部分?

使用嵌套对象中的属性反序列化 JSON [重复]

ServiceStack 文本设置以在反序列化 json 时推断原始值类型

Json.net反序列化不反序列化所有属性

具有 IEnumerable<ISomeInterface> 类型属性的 NewtonSoft.Json 序列化和反序列化类