简体   繁体   English

用于抽象模型的Asp.Net Core 2.0(MVC)Content Binder

[英]Asp.Net Core 2.0 (MVC) Content Binder for an abstract model

I have just started to develop ASP.Net Core 2.0 with MVC Framework. 我刚刚开始使用MVC Framework开发ASP.Net Core 2.0

I have some trouble with CustomModelBinder when posting (form submit) data from View page. 从“视图”页面发布(表单提交)数据时, CustomModelBinder遇到了一些麻烦。

Here is my View: 这是我的观点:

<form action="/Media/CreateVideo" method="post">
                <input type="text" name="Name" />
                <input type="hidden" name="ModelType" value="VideoModel" />
                <input type="text" name="ContentType" value="video" />

                <button type="submit">Yes</button>
  </form>

My models: 我的模特:

    public abstract class ContentModel
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public string ContentType { get; set; }
        public string Data { get; set; }

        public virtual FolderModel ParentFolder { get; set; }
    }



    public abstract class FileModel : ContentModel
    {
        public string Path { get; set; }
    }

    public class VideoModel : FileModel
    {
        //Other properties i.e. video duration, size, format etc.
    }

    public class ImageModel : FileModel
    {
        //Other properties i.e. size, format, cropping value, hue, etc.
    }

My Controller: 我的控制器:

        [HttpPost]
        public IActionResult CreateWeb([ModelBinder(BinderType = typeof(CustomModelBinder))]ContentModel item)
        {
            _contentService.Add(item);
            _contentService.SaveChanges();

            return View();
        }

My Custom Model Binder class: 我的自定义模型活页夹类:

public class CustomModelBinder : IModelBinder
    {

        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));

            ValueProviderResult values = bindingContext.ValueProvider.GetValue("ModelType");
            if (values.Length == 0)
                return Task.CompletedTask;

            string typeString = values.FirstValue;
            Type type = Type.GetType(
                "Magic.Core.Models." + typeString + ", Magic.Core.Models",
                true
            );

            object model = Activator.CreateInstance(type);

            var metadataProvider = (IModelMetadataProvider)bindingContext.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider));
            bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(type);
            bindingContext.Result = ModelBindingResult.Success(model);

            return Task.CompletedTask;
        }
    }

Here is what happens, 这是发生了什么事

I am able to tell the controller that this ContentModel is VideoModel . 我可以告诉控制器该ContentModelVideoModel However, all post value such as Name, ContentType, etc. is all null. 但是,所有帖子值(例如Name,ContentType等)都为空。

I used to do this in MVC5 following this thread Polymorphic model binding and it just worked fine. 我曾经在MVC5中遵循此线程多态模型绑定来做到这一点,并且工作得很好。

My question is did I miss some steps or there is something new in .Net Core related to model binding? 我的问题是我错过了一些步骤,还是.Net Core中有一些与模型绑定有关的新东西?

well, I guess your CustomModelBinder needs some more logic to get the form values from provider: 好吧,我想您的CustomModelBinder需要更多逻辑才能从提供程序获取表单值:

public class CustomModelBinder : IModelBinder
{

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        ValueProviderResult values = bindingContext.ValueProvider.GetValue("ModelType");
        if (values.Length == 0)
            return Task.CompletedTask;

        string typeString = values.FirstValue;
        Type type = Type.GetType(
            "Magic.Core.Models." + typeString + ", Magic.Core.Models",
            true
        );

        object model = Activator.CreateInstance(type);

        //*get form values from provider
        var content = model as ContentModel;
        if(content != null)
        {
            var provider = bindingContext.ValueProvider;

            var contentType = provider.GetValue("ContentType");
            content.ContentType = contentType != null ? contentType.ToString() : string.Empty;

            var name = provider.GetValue("Name");
            content.Name = name != null ? name.ToString() : string.Empty;
        }
        //*/

        var metadataProvider = (IModelMetadataProvider)bindingContext.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider));
        bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(type);
        bindingContext.Result = ModelBindingResult.Success(model);

        return Task.CompletedTask;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM