次のようなdata
プロパティのデータコンテンツをラップするAPI JSON応答があります。
{
"data":{
"email":"[email protected]",
"mobile":"+1555555123",
"id":4,
"first_name":"Merchant",
"last_name":"Vendor",
"role":"Merchant",
}
}
したがって、RequestSharp
のようなライブラリを使用してユーザーオブジェクトをリクエストすると、response.Content
には、APIから取得したdata
jsonプロパティにユーザーのコンテンツがラップされます。コード:
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呼び出しでは、transaction
や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
フィールド用のカスタムコンバーターを作成する必要がありました。 APIはid
を整数として返しますが、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; }
...
次のようなオブジェクトを作成できます。
public class Data
{
public string email { get; set; }
public string mobile { get; set; }
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string role { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
その後
var data = JsonSerializer.Deserialize<RootObject>(JsonData);
その後、次のようなデータにアクセスできます。
RootObject.Data.email ;
RootObject.Data.first_name
また、JSON文字列をC#POCOクラスに変換する必要があるときはいつでも、次のようなツールを使用できます。 http://json2csharp.com/