我有一个 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
这很好,但是当我将 json 反序列化为 Object 时System.Text.Json
,如下所示,将创建该User
对象但不会分配任何属性,尽管这是意料之中的,因为序列化程序正在寻找带有first_name
and的属性last_name
。 .. 不是['data']['first_name']
User account = JsonSerializer.Deserialize<User>(response.Content, options);
我怎样才能JsonSerializer.Deserialize
忽略data
包装器?在其他 API 调用中,它可能是 Object 的名称,例如transaction
or user
,无论哪种方式,它都会包装数据。
其他注意事项:
我的目标是最新的 .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
字段创建一个自定义转换器。APIid
以整数形式返回,尽管它是User
类中的字符串。这是我遇到的最初令人困惑的错误,但我很快就弄清楚了: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; }
...