gpt4 book ai didi

c# - System.Text.Json 从 API 调用反序列化嵌套对象 - 数据包装在父 JSON 属性中

转载 作者:行者123 更新时间:2023-12-04 02:40:44 26 4
gpt4 key购买 nike

我有一个 API JSON 响应,它将数据内容包装在 data 中。属性,如下所示:

{ 
"data":{
"email":"admin@example.com",
"mobile":"+1555555123",
"id":4,
"first_name":"Merchant",
"last_name":"Vendor",
"role":"Merchant",
}
}

因此,当使用类似 RequestSharp 的库请求用户对象时, response.Content将用户的内容包裹在 data 中json 属性,因为它来自 API。代码:

var request = RequestHelper.CreateTokenRequest(email, password); // Create the request from a helper
var client = new RestClient(BaseUrl); // create new RestSharp Client
IRestResponse response = client.Execute(request); // execute the request
var content = response.Content; // raw content as string

这很好,但是当我使用 System.Text.Json 将 json 反序列化为对象时,如下所示,将创建 User对象但不会分配任何属性,尽管这是预期的,因为序列化程序正在寻找具有 first_name 的属性。和 last_name ...不是 ['data']['first_name']
User account = JsonSerializer.Deserialize<User>(response.Content, options);


我如何获得 JsonSerializer.Deserialize忽略 data包装?在其他 API 调用中,它可能是对象的名称,例如 transactionuser ,无论哪种方式,它都会包装数据。

其他注意事项:

我的目标是最新的 .Net Core 3.1 并且正在从 Newtonsoft Json.Net 迁移

我的用户对象:

using System.ComponentModel;
using System.Text.Json.Serialization;

namespace MyApplication.Models
{
public interface IUser
{
string FirstName { get; set; }
string LastName { get; set; }
string Email { get; set; }
string Mobile { get; set; }
string Id { get; set; }
string Role { get; set; }
}

public class User : IUser
{
[JsonPropertyName("first_name")]
public string FirstName { get; set; }

[JsonPropertyName("last_name")]
public string LastName { get; set; }

[JsonPropertyName("email")]
public string Email { get; set; }

[JsonPropertyName("mobile")]
public string Mobile { get; set; }

[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("role")]
public string Role { get; set; }

[JsonIgnore]
public string Token { get; set; }
}
}


解决后更新:

我从下面的 u/Nikunj Kakadiya 中选择了答案作为可行的方法,并且与我最终所做的最相似。

我创建了一个基于通用模板的容器类来处理 data像这样:

public class Container<T>
{
[JsonPropertyName("data")]
public T Data { get; set; }
}

然后我使用该容器类来包装从 API 调用返回的 json 内容,如下所示:

var options = new JsonSerializerOptions
{
AllowTrailingCommas = true
};

Container<User> accountContainer = JsonSerializer.Deserialize<Container<User>>(response.Content, options);
User account = accountContainer.Data;

此外,正如 u/Pavel Anikhouski 所指出的,我对 User 的连载类导致了一个错误,需要我为 id 创建自定义转换器 field 。 API 返回 id尽管它是 User 中的字符串,但它作为整数类(class)。这是我遇到的错误,最初令人困惑,但我很快就弄清楚了: ERROR: The JSON value could not be converted to System.String. Path: $.data.id | LineNumber: 0 | BytePositionInLine: 77.
这是自定义转换器 IntToStringConverter :

public class IntToStringConverter : JsonConverter<string>
{
public override string Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) => reader.GetInt32().ToString();

public override void Write(
Utf8JsonWriter writer,
string value,
JsonSerializerOptions options) =>
writer.WriteStringValue(value);
}

然后更改了 User使用客户转换器的类:

...
[JsonPropertyName("id")]
[JsonConverter(typeof(IntToStringConverter))]
public string Id { get; set; }
...

最佳答案

你需要再补一个类。下面给出

Public class UserData
{
public User data { get; set; };
}

现在您可以使用名为 UserData 的新类反序列化数据,如下所示
UserData account = JsonSerializer.Deserialize<UserData>(response.Content, options);

关于c# - System.Text.Json 从 API 调用反序列化嵌套对象 - 数据包装在父 JSON 属性中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59568647/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com