我正在调用API,为所有操作返回标准响应结构。我使用Newtonsoft.Json和JsonConvert.DeserializeObject<Response>
public class Response
{
public int Code { get; set; }
public string Message { get; set; }
public object Result { get; set; }
public DateTime ResponseDateTime { get; set; }
}
Result对象的更改取决于已请求的请求操作以及是否存在错误(Code + Message描述错误)。我知道Result对象的结构,并为我需要的每个Result创建了类。
如何将Result对象转换为类型变量,例如Detail[]
?我知道我可以序列化Result对象并再次反序列化,但肯定有一个更优雅的解决方案。
public class Detail
{
public int Id { get; set; }
public string DetailOne { get; set; }
public string DetailTwo { get; set; }
}
答案 0 :(得分:4)
如果你总是知道你会得到什么样的Result
,我建议Response
通用:
public class Response<TResult>
{
public int Code { get; set; }
public string Message { get; set; }
public T Result { get; set; }
public DateTime ResponseDateTime { get; set; }
}
然后你可以反序列化到Response<Detail[]>
,Json.NET应该处理好一切。
这假设如果出现错误,您将无法获得可能存在问题的Result
。或者,您仍然可以反序列化为Response
类,但具有JToken
属性类型:
public class Response
{
public int Code { get; set; }
public string Message { get; set; }
public JToken Result { get; set; }
public DateTime ResponseDateTime { get; set; }
}
然后使用:
Response response = JsonConvert.DeserializeObject<Response>(json);
if (response.Code == 200) // Or whatever
{
Detail[] details = response.Result.ToObject<Detail[]>();
}
您可以将其包装到通用方法中。我首先至少尝试通用响应类。
答案 1 :(得分:1)
如果您将对象模型更改为:
public class Response<T>
{
public int Code { get; set; }
public string Message { get; set; }
public T Result { get; set; }
public DateTime ResponseDateTime { get; set; }
}
public class Detail
{
public int Id { get; set; }
public string DetailOne { get; set; }
public string DetailTwo { get; set; }
}
然后你可以这样做:
var original = new Response<Detail>()
{
Code = 42,
Message = "OK",
Result = new Detail()
{
Id = 1701,
DetailOne = "Don't",
DetailTwo = "Panic",
},
ResponseDateTime = DateTime.Now,
};
var json = JsonConvert.SerializeObject(original, Newtonsoft.Json.Formatting.Indented);
var response = JsonConvert.DeserializeObject<Response<Newtonsoft.Json.Linq.JToken>>(json);
if (response.Code == 42)
{
Detail detail = response.Result.ToObject<Detail>();
/* Do something with `Detail`. */
}
这似乎是一种非常好的方法来获取基础Detail
对象。
关键技术是序列化Response<Detail>
并反序列化为Response<JToken>
。简单。
当然,如果你真的想创建一个Response<Detail>
实例,你可以通过直接的字段到字段映射,以一种相当直接的方式从Response<JToken>
转换为Response<Detail>
以下是代码的Response<Detail[]>
版本:
var original = new Response<Detail[]>()
{
Code = 42,
Message = "OK",
Result = new Detail[]
{
new Detail()
{
Id = 1701,
DetailOne = "Don't",
DetailTwo = "Panic",
},
new Detail()
{
Id = 360,
DetailOne = "Microsoft",
DetailTwo = "Xbox",
}
},
ResponseDateTime = DateTime.Now,
};
var json = JsonConvert.SerializeObject(original, Newtonsoft.Json.Formatting.Indented);
var response = JsonConvert.DeserializeObject<Response<Newtonsoft.Json.Linq.JToken>>(json);
if (response.Code == 42)
{
Detail[] detail = response.Result.ToObject<Detail[]>();
/* Do something with `Detail[]`. */
}