代码之家  ›  专栏  ›  技术社区  ›  iMSn20

反序列化具有相同应答属性名称但内部属性不同的JSON

  •  1
  • iMSn20  · 技术社区  · 2 年前

    我正在实现一个外部API,如果可以的话,它会给我这样的响应:

    {
        status: "success",
        answer: {
            token: "tokenGenerated..."
        }
    }
    

    或者如果我遇到错误:

    {
        status: "ERROR",
        answer: {
            errorCode: "error code"
            errorMessage: "error message"
        }
    }
    

    我试图在两个不同的类中反序列化响应,一个用于OK响应,另一个用于ERROR响应。我在做这样的事情:

    public class Response
    {
        [JsonProperty("status")]
        private string Status { get; set; }
        public bool IsSuccess => Status != "ERROR";
        
        [JsonProperty("answer")]
        public object Response { get; set; }
    }
    
    public class ResponseError : Response
    {
        [JsonProperty("errorCode")]
        public string ErrorCode { get; set; }
    
        [JsonProperty("errorMessage")]
        public string ErrorMessage { get; set; }
    }
    
    public class ResponseOk : Response
    {
        [JsonProperty("token")]
        public string Token { get; set; }
    }
    

    当我得到回应时,我会这样做:

    var readResponse = await response.Content.ReadAsStringAsync();                    
    var deserializedResponse = JsonConvert.DeserializeObject<Response>(readResponse);
    if (deserializedResponse.IsSuccess)
        return JsonConvert.DeserializeObject<ResponseOk>(readResponse);
    else
        return JsonConvert.DeserializeObject<ResponseError>(readResponse);
    

    在我的方法中,我返回一个对象。 例如,我的问题是,如果我获得了OK状态,那么属性状态就得到了很好的实现,并且在响应属性中我得到了“token:”tokenhere“,而不是在token属性中。

    如果我试图将Token属性和errors属性放在Resposne类中,我需要在这两种情况下都应用JsonProperty(“answer”),当然我会得到一个异常。

    有更好的方法来实施我的案例吗? 谢谢。

    1 回复  |  直到 2 年前
        1
  •  1
  •   Roman    2 年前

    您映射 answer JSON中的对象到 Response 中的属性 回答

    拥有此类课程:

    public class ResponseOk : Response
    {
        [JsonProperty("token")]
        public string Token { get; set; }
    }
    

    你希望 token 属性作为根属性,但 代币 在…内 答复 所以这个映射不起作用。

    当您遇到错误时,您也会遇到同样的问题- ErrorCode ErrorMessage 也不会设置,因为您将它们映射到根属性。

    您可以将类更改为:

    public class Response
    {
        [JsonProperty("status")]
        private string Status { get; set; }
        public bool IsSuccess => Status != "ERROR";
        
        [JsonProperty("answer")]
        public Answer Response { get; set; } // can be just renamed to "Answer"
    }
    
    public class Answer
    {
        [JsonProperty("errorCode")]
        public string ErrorCode { get; set; }
    
        [JsonProperty("errorMessage")]
        public string ErrorMessage { get; set; }
    
        [JsonProperty("token")]
        public string Token { get; set; }
    }
    

    现在您可以检查 IsSuccess 在里面 回答 上课并决定使用什么- Token 或错误属性。

        2
  •  0
  •   Jonathan    2 年前

    您可以这样定义类(尚未测试):

    public class Response
    {
        [JsonProperty("status")]
        private string Status { get; set; }
        public bool IsSuccess => Status != "ERROR";
    }
    
    public class ResponseError : Response
    {
        [JsonProperty("answer")]
        public ResponseErrorContent answer { get; set; }
    }
    
    public class ResponseErrorContent
    {
        [JsonProperty("errorCode")]
        public string ErrorCode { get; set; }
    
        [JsonProperty("errorMessage")]
        public string ErrorMessage { get; set; }
    }
    
    public class ResponseOk : Response
    {
        [JsonProperty("answer")]
        public ResponseOkContent answer { get; set; }
    }
    
    public class ResponseOkContent
    {
        [JsonProperty("token")]
        public string Token { get; set; }
    }