c# - 抽象模型的 Asp.Net Core 2.0 (MVC) Content Binder

标签 c# asp.net-mvc asp.net-core-mvc

我刚刚开始使用 MVC 框架开发 ASP.Net Core 2.0

从 View 页面发布(表单提交)数据时,我在使用 CustomModelBinder 时遇到一些问题。

这是我的观点:

<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>

我的模型:

    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.
    }

我的 Controller :

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

            return View();
        }

我的自定义模型绑定(bind)器类:

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

这是发生了什么,

我可以告诉 Controller 这个 ContentModelVideoModel。 但是,所有的post值如Name,ContentType等都是null。

我曾经在这个线程之后在 MVC5 中这样做 Polymorphic model binding 它运行良好。

我的问题是我是否遗漏了某些步骤,或者 .Net Core 中是否有与模型绑定(bind)相关的新内容?

最佳答案

好吧,我猜你的 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;
    }
}

关于c# - 抽象模型的 Asp.Net Core 2.0 (MVC) Content Binder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48313688/

相关文章:

css - 样式化 HTML 助手 ASP.NET MVC

c# - 普通 MVC 项目登录需要哪些表?

c# - 如何在 ASP.NET Core Razor 页面中绑定(bind)复杂列表

c# - VS 2017 .NET 4.6.2 新增 ASP.NET Core Web Application (.NET Framework) 默认为 x86 平台

c# - 实现 APNG 渲染函数

asp.net-mvc - Entity Framework : There is already an open DataReader associated with this Command which must be closed first

asp.net-core - .Net Core 图像处理(裁剪和调整大小)/文件处理

c# - 设置组合框的下拉高度(winrt)

c# - 日期和时间正则表达式

c# - 如何使用 DI 在类构造函数中获取 Microsoft.AspNet.Http.HttpContext 实例