中具有继承的模型绑定

中具有继承的模型绑定

我需要接受来自用户的对象列表:

public async Task<IActionResult> CreateArticle(List<InformationBlockModel> informationBlocks)
    {
        ...
    }

ModelBinder 应该确定具体类型,但是当我尝试将 InformationBlock 转换为 TextInformationBlock 时,会引发异常。

等级制度:
public class InformationBlockModel
{
    public virtual InformationBlockType Type { get; set; }
}

public class TextInformationBlockModel : InformationBlockModel
{
    public string Text { get; set; }

    public override InformationBlockType Type { get; set; } = InformationBlockType.Text;
}

public class ImageInformationBlockModel : InformationBlockModel
{
    public override InformationBlockType Type { get; set; } = InformationBlockType.Image;
    public string Name { get; set; }
}

最佳答案

最后,我找到了一个解决方案:

Startup.cs

services.AddMvc()
    .AddJsonOptions(options => options.SerializerSettings.Converters.Add(new InformationBlockConverter()));

JsonCreationConverter.cs
public abstract class JsonCreationConverter<T> : JsonConverter
{
    public override bool CanWrite { get; } = false;

    public override bool CanRead { get; } = true;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    }

    protected abstract T Create(Type objectType, JObject jObject);

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);

        var target = Create(objectType, jObject);

        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }
}

信息块转换器
public class InformationBlockConverter : JsonCreationConverter<InformationBlockModel>
{
    private readonly Dictionary<InformationBlockType, Type> _types = new Dictionary<InformationBlockType, Type>
    {
        {InformationBlockType.Text, typeof(TextInformationBlockModel)},
        {InformationBlockType.Image, typeof(ImageInformationBlockModel)},
        {InformationBlockType.Video, typeof(VideoInformationBlockModel)}
    };

    protected override InformationBlockModel Create(Type objectType, JObject jObject)
    {
        return (InformationBlockModel) jObject.ToObject(_types[Enum.Parse<InformationBlockType>(
            jObject.GetValue("type", StringComparison.InvariantCultureIgnoreCase).Value<string>(), true)]);
    }
}

信息块类型
public enum InformationBlockType
{
    Text,
    Image,
    Video
}

关于asp.net - Asp.Core 中具有继承的模型绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47624747/

10-10 20:23