C# 如何创建不同类型的JSON数据模型
我正在调用一个API,它返回如下响应C# 如何创建不同类型的JSON数据模型,c#,json,.net-core,json.net,C#,Json,.net Core,Json.net,我正在调用一个API,它返回如下响应 { "data": { "name": "John", "score": 51 }, "ret": 0 } 发生错误时,响应将更改为 { "data": "error message", "ret": 1 } 请注意,“data”属性因对象和字符串而异 现在我可以使用JsonConverter在不同类型上返回不同的类,问题是保存此响应的模型。i、 如果我使用 public class
{
"data": {
"name": "John",
"score": 51
},
"ret": 0
}
发生错误时,响应将更改为
{
"data": "error message",
"ret": 1
}
请注意,“data”属性因对象和字符串而异
现在我可以使用JsonConverter在不同类型上返回不同的类,问题是保存此响应的模型。i、 如果我使用
public class MyResponse
{
[JsonConverter(typeof(MyResponseType))]
[JsonProperty(PropertyName = "data")]
public MyResponseType Data { get; set; }
[JsonProperty(PropertyName = "ret")]
public int ReturnCode { get; set; }
}
MyResponseType当然可以保存对象,但不能转换为字符串
我尝试使用泛型类型来保存数据
public class MyReponse<T>
{
[JsonProperty(PropertyName = "data")]
public T Data { get; set; }
[JsonProperty(PropertyName = "ret")]
public int ReturnCode { get; set; }
}
公共类MyResponse
{
[JsonProperty(PropertyName=“data”)]
公共T数据{get;set;}
[JsonProperty(PropertyName=“ret”)]
public int ReturnCode{get;set;}
}
但另一个问题来了,这个MyResponse类被.Net Core中的一个服务使用,该服务在ConfigureServices步骤中通过依赖注入进行初始化,这不允许传入泛型。这就是该模型在服务中的使用方式以及服务的初始化方式
服务:
public class MyService<T> : IMyService {
public bool someMethod() {
...
var resp = JsonConvert.DeserializeObject<MyReponse<T>>(myResponse);
...
}
}
公共类MyService:IMyService{
公共布尔方法(){
...
var resp=JsonConvert.DeserializeObject(myResponse);
...
}
}
在Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IMyService, MyService>(); // Generics can't be passed in here
...
}
public void配置服务(IServiceCollection服务)
{
...
services.AddTransient();//此处无法传递泛型
...
}
关于如何创建适当的数据模型来处理这种情况,有什么建议吗?因此,假设出现错误时“ret”值为1,我能想到的最简单的解决方案是在强制转换之前检查该属性
所以你可以有两个模型
public class MyResponse
{
[JsonConverter(typeof(MyResponseType))]
[JsonProperty(PropertyName = "data")]
public MyResponseType Data { get; set; }
[JsonProperty(PropertyName = "ret")]
public int ReturnCode { get; set; }
}
及
然后决定应转换为哪种类型。因此,假设出现错误时“ret”值为1,我能想到的最简单的解决方案是在转换之前检查该属性
所以你可以有两个模型
public class MyResponse
{
[JsonConverter(typeof(MyResponseType))]
[JsonProperty(PropertyName = "data")]
public MyResponseType Data { get; set; }
[JsonProperty(PropertyName = "ret")]
public int ReturnCode { get; set; }
}
及
然后决定应转换为哪种类型。我将在api客户端级别管理它
public class MyApiClientException: Exception
{
public int ErrorCode { get; private set; }
public MyApiClientException(string message, int errorCode): base(message)
{
this.ErrorCode = errorCode;
}
}
public class MyApiClient
{
private readonly HttpClient httpClient;
public MyApiClient(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public async Task<T> GetAsync<T>(string uri)
{
using (var response = await httpClient.GetAsync(uri))
{
var stringContent = await response.Content.ReadAsStringAsync();
var jtoken = JToken.Parse(stringContent);
int errorCode = (int)jtoken["ret"];
var jdata = jtoken["data"];
if (errorCode > 0)
{
throw new MyApiClientException((string)jdata, errorCode);
}
return jdata.ToObject<T>();
}
}
}
我将在api客户端级别管理它
public class MyApiClientException: Exception
{
public int ErrorCode { get; private set; }
public MyApiClientException(string message, int errorCode): base(message)
{
this.ErrorCode = errorCode;
}
}
public class MyApiClient
{
private readonly HttpClient httpClient;
public MyApiClient(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public async Task<T> GetAsync<T>(string uri)
{
using (var response = await httpClient.GetAsync(uri))
{
var stringContent = await response.Content.ReadAsStringAsync();
var jtoken = JToken.Parse(stringContent);
int errorCode = (int)jtoken["ret"];
var jdata = jtoken["data"];
if (errorCode > 0)
{
throw new MyApiClientException((string)jdata, errorCode);
}
return jdata.ToObject<T>();
}
}
}
此MyResponse类由.Net Core中的一个服务使用,
您可以向我们展示代码吗您的通用数据模型似乎非常适合我。我们可以在服务初始化中进行一些修复吗。因此,您的数据模型将适用于这两种情况。您是否可以共享ConfigureServices
方法以及如何注册MyResponse
?此MyResponse类由.Net Core中的一个服务使用,
您能否向我们展示代码您的通用数据模型似乎非常适合我。我们可以在服务初始化中进行一些修复吗。为了使您的数据模型适用于这两种情况,您能否共享ConfigureServices
方法以及如何注册MyResponse
?
public class MyServiceFactory
{
public MyService<T> CreateService<T>()
{
throw NotImplementedException();
}
}