4

data次のようなプロパティで データ コンテンツをラップする API JSON 応答があります。

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

RequestSharpそのため、 のようなライブラリを使用してユーザー オブジェクトをリクエストすると、ユーザーresponse.ContentのコンテンツがdataAPI から取得された 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

これは問題ありませんが、次のように JSON を Object にデシリアライズしようとSystem.Text.Jsonすると、オブジェクトが作成されますが、User属性は割り当てられません。 .. いいえfirst_namelast_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; }
...
4

4 に答える 4

-1

データ オブジェクトを取り除くか、カスタム json コンバーターを作成できます。あなたがやろうとしていることはベストプラクティスではないので、送信されたデータを変更するか、そのまま使用することをお勧めします。

于 2020-01-02T19:19:01.277 に答える