Get JSON.NET in WebAPI to serialize exact type, not subclass

I have three classes in a domain

public class ArtistInfo { private Guid Id { get; set; } public string Name { get; set; } public string DisplayName { get; set; } public bool IsGroup { get; set; } public bool IsActive { get; set; } public string Country { get; set; } } public class Artist : ArtistInfo { public DateTime Created { get; set; } public int CreatedById { get; set; } public DateTime Updated { get; set; } public int UpdatedById { get; set; } } public class Track { public string Title { get; set; } public string DisplayTitle { get; set; } public int Year { get; set; } public int Duration { get; set; } public int? TrackNumber { get; set; } //[SomeJsonAttribute] public ArtistInfo Artist { get; set; } } 

From the ASP.NET web API, I am returning a general list of (tracks). No matter what I tried, the web API returns the Artist property as the artist Artist artist. Is it possible to somehow limit this in the API output to just use ArtistInfo? I do not want to write the "ViewModels / DTOs" add-on to handle this situation. Can I decorate ArtistInfo with a hint for the JSON Serializer?

+5
source share
2 answers

One way to get the desired result is to use a custom JsonConverter , which can limit the set of serialized properties. Here is the one that will serialize the properties of the base type T :

 public class BaseTypeConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(T).IsAssignableFrom(objectType); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { JObject obj = new JObject(); foreach (PropertyInfo prop in typeof(T).GetProperties()) { if (prop.CanRead) { obj.Add(prop.Name, JToken.FromObject(prop.GetValue(value))); } } obj.WriteTo(writer); } public override bool CanRead { get { return false; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } 

To use the converter, check the Artist property in your Track class with the [JsonConverter] attribute, as shown below. Then only the ArtistInfo Artist properties will be serialized.

 public class Track { public string Title { get; set; } public string DisplayTitle { get; set; } public int Year { get; set; } public int Duration { get; set; } public int? TrackNumber { get; set; } [JsonConverter(typeof(BaseTypeConverter<ArtistInfo>))] public ArtistInfo Artist { get; set; } } 

Demo here

+1
source

Although the answer of Brian Rogers was appropriate. But if you need a quicker solution than the [JsonIgnore] property, it will come in handy.

 public class Artist : ArtistInfo { [JsonIgnore] public DateTime Created { get; set; } [JsonIgnore] public int CreatedById { get; set; } [JsonIgnore] public DateTime Updated { get; set; } [JsonIgnore] public int UpdatedById { get; set; } } 

Check out the demo here . I updated the Brian code.

0
source

Source: https://habr.com/ru/post/1200950/


All Articles