Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

Type Discriminator Configuration ASP.NET Core Web API

$
0
0

For a polymorphic Web API endpoint. Is there a way to configure the type discriminator?

I only found a solution with a JsonConverter. But the problem is the framework behaves then a bit different. E.g. the ValidationAttributes do not get evaluated any more.

Also the code feels like somehow "bypassing" the framework

[JsonConverter(typeof(ScheduleApiConverter))]
public class ScheduleBase
{
public string Type { get; set; }
// [...]
}

public class ScheduleApiConverter : ApiTypeConverter<ScheduleBase>
{
    protected override ScheduleBase Create(Type objectType,
      JObject jObject)
    {
        // TODO: read the raw JSON object through jObject to identify the type
        // e.g. here I'm reading a 'typename' property:

        var typeString = jObject.Value<string>("Type");
        if (ScheduleMongoConverter.WEEKLY_DISCRIMINATOR.Equals(typeString)) {
            return new ScheduleWeekly();
        }
        else if (ScheduleMongoConverter.DAILY_DISCRIMINATOR.Equals(typeString)) {
            return new ScheduleDaily();
        }
        else if (ScheduleMongoConverter.ONCE_DISCRIMINATOR.Equals(typeString)) {
            return new ScheduleOnce();
        }
        else {
            return new ScheduleOnce();
        }

        //now the base class' code will populate the returned object.
    }
}




public abstract class ApiTypeConverter<T> : JsonConverter
{
    // List<string> Errors = new List<string>();

    // this is very important, otherwise serialization breaks!
    public override bool CanWrite {
        get {
            return false;
        }
    }

    // Create an instance of objectType, based properties in the JSON object
    // objectType: type of object expected
    // jObject: contents of JSON object that will be deserialized
    protected abstract T Create(Type objectType, JObject jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
      object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        // Load JObject from stream
        JObject jObject = JObject.Load(reader);

        // Create target object based on JObject
        T target = Create(objectType, jObject);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value,
      JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Viewing all articles
Browse latest Browse all 9386

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>