C# 如何创建不同类型的JSON数据模型

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

我正在调用一个API,它返回如下响应

{
    "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();
    }

}