Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map JSON payload to DTO with different field names

I have a simple GitHub payload incoming to my ASP.NET Core application and I would like to know how can I map the payload I receive to my DTO.

Example DTO

public class GithubPayload
{
    public string Action { get; set; }  // action
    public string Name { get; set; }    // pull_request.title
}

Example payload

{
  "action": "deleted",
  "pull_request": {
    "title": "Fix button"
  }
}
like image 704
Stan Avatar asked Mar 09 '23 05:03

Stan


1 Answers

You can use JsonProperty attribute on Action and a custom converter on the Name that can interpret nested properties. check Json.Net's JsonConverter

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

Where NestedConverter is a custom JsonConverter that will read a nested property

public class NestedConverter : JsonConverter {
    private readonly string path;

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

    //...to do
}

Update:

Using a JsonConverter for converting the payload itself actually works as well

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();
    }
}

and decorating the class itself

[JsonConverter(typeof(GithubPayloadConverter))]
public class GithubPayload {
    public string Action { get; set; }
    public string Name { get; set; }
}

Deserialization is simply

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

var payload = JsonConvert.DeserializeObject<GithubPayload>(json);
like image 106
Nkosi Avatar answered Mar 11 '23 05:03

Nkosi