C#使用动态属性类型反序列化JSON

nxowjjhe  于 2023-05-19  发布在  C#
关注(0)|答案(2)|浏览(273)

API目前返回两种类型的json string(类型字段始终为string,但数据字段可能为string或list或int):
例如类型1:

{
    "type": "error",
    "data": "error message"
}

第二类:

{
    "type": "success",
    "data": [
        {
            "id": 1,
            "title": "tortor at auctor urna nunc",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        },
        {
            "id": 2,
            "title": "gravida rutrum quisque non tellus",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        }
        ]
}

我有下面的类来Mapjson字符串:

class ResponseData
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("data")]
    public string Data { get; set; }
}

我想将json反序列化为ResponseData并打印出data字段中的文本,例如:

var response = await httpClient.GetAsync(url);
var responseData = await response.Content.ReadFromJsonAsync<ResponseData>();
Debug.WriteLine(responseData.Data);

如果API返回json类型1,则代码工作正常。但如果它返回json类型2,则会抛出以下错误消息:
Exception thrown: 'System.Text.Json.JsonException' in System.Private.CoreLib.dllThe JSON value could not be converted to System.String. Path: $.data | LineNumber: 0 | BytePositionInLine: 32.: Error
有什么办法解决这个问题吗?谢谢
我希望如果API返回json类型2,至少可以将以下json字符串作为字符串保存到responseData.Data中:

"[
    {
        \"id\": 1,
        \"title\": \"tortor at auctor urna nunc\",
        \"content\": \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\"
    }
]"

这样我就可以将responseData.Datajson字符串反序列化为另一个对象

var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data);
hxzsmxv2

hxzsmxv21#

问题是,在这两种情况下,你都试图将“data”反序列化为字符串(因为你已经在ResponseData类中定义了属性Data为字符串类型),但在第二种情况下,“data”是一个json数组,它不能自动转换为字符串。
如果我可以这么说的话,我不确定你的设计首先是最佳的方法,但是如果你想让它按原样工作,或多或少,你可以将Data的类型更改为obejct。
以下是使用Newtonsoft的想法的快速演示:

string example1 = @"{
    ""type"": ""error"",
    ""data"": ""error message""
}";

string example2 = @"{
    ""type"": ""success"",
    ""data"": [
        {
            ""id"": 1,
            ""title"": ""tortor at auctor urna nunc"",
            ""content"": ""Lorem ipsum dolor sit amet, consectetur adipiscing elit.""
        },
        {
            ""id"": 2,
            ""title"": ""gravida rutrum quisque non tellus"",
            ""content"": ""Lorem ipsum dolor sit amet, consectetur adipiscing elit.""
        }
        ]
}";

var response1 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseData>(example1);
Console.WriteLine(response1.Data.ToString());

var response2 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseData>(example2);
Console.WriteLine(response2.Data.ToString());

class ResponseData
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("data")]
    public object Data { get; set; }
}
xtfmy6hx

xtfmy6hx2#

你可以试试这个代码

var json = await response.Content.ReadAsStringAsync();

    var jn = JsonNode.Parse(json).AsObject();
    ResponseData responseData = jn.Deserialize<ResponseData>();

    if (responseData.Type == "success")
        responseData.Data = jn["data"].Deserialize<List<Datum>>();
    else
        responseData.ErrorMessage = jn["data"].GetValue<string>();

public partial class ResponseData
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    public string ErrorMessage { get; set; }

    public List<Datum> Data { get; set; }
}

public partial class Datum
{
    [JsonPropertyName("id")]
    public long Id { get; set; }

    [JsonPropertyName("title")]
    public string Title { get; set; }

    [JsonPropertyName("content")]
    public string Content { get; set; }
}

相关问题