web-dev-qa-db-ja.com

System.Text.Json API呼び出しからネストされたオブジェクトをデシリアライズ-データは親JSONプロパティにラップされます

次のような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.Deserializedataラッパーを無視するようにするにはどうすればよいですか?他の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フィールド用のカスタムコンバーターを作成する必要がありました。 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; }
...
2
DogEatDog

次のようなオブジェクトを作成できます。

  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/

0
Cyber Progs