将 JSON 负载映射到具有不同字段名称的 DTO

Sta*_*tan 4 c# asp.net-core-mvc .net-core

我有一个简单的 GitHub 负载传入我的 ASP.NET Core 应用程序,我想知道如何将接收到的负载映射到我的 DTO。

示例 DTO

public class GithubPayload
{
    public string Action { get; set; }  // action
    public string Name { get; set; }    // pull_request.title
}
Run Code Online (Sandbox Code Playgroud)

示例有效载荷

{
  "action": "deleted",
  "pull_request": {
    "title": "Fix button"
  }
}
Run Code Online (Sandbox Code Playgroud)

Nko*_*osi 5

您可以JsonPropertyAction可以解释嵌套属性的 Name上使用属性和自定义转换器。检查 Json.Net 的JsonConverter

public class GithubPayload {
    [JsonProperty("action")]
    public string Action { get; set; }
    [JsonConverter(typeof(NestedConverter), "pull_request.title")]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

将读取嵌套属性NestedConverter的自定义在哪里JsonConverter

public class NestedConverter : JsonConverter {
    private readonly string path;

    public NestedConverter (string path) {
        this.path = path; 
    }

    //...to do
}
Run Code Online (Sandbox Code Playgroud)

更新:

使用 JsonConverter 来转换有效负载本身实际上也有效

public class GithubPayloadConverter : JsonConverter {

    public override bool CanConvert(Type objectType) {
        return objectType == typeof(GithubPayload);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        dynamic data = JObject.Load(reader);
        var model = new GithubPayload {
            Action = data.action,
            Name = data.pull_request.title
        };
        return model;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

并装饰课程本身

[JsonConverter(typeof(GithubPayloadConverter))]
public class GithubPayload {
    public string Action { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

反序列化很简单

string json = @"{ 'action': 'deleted', 'pull_request': { 'title': 'Fix button' } }";

var payload = JsonConvert.DeserializeObject<GithubPayload>(json);
Run Code Online (Sandbox Code Playgroud)