首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ASP.net MVC内核中替换DefaultModelBinder

在ASP.net MVC内核中替换DefaultModelBinder
EN

Stack Overflow用户
提问于 2018-06-17 11:03:00
回答 2查看 4.9K关注 0票数 11

我正在将一个MVC5项目转换为核心。我目前有一个自定义模型绑定器,我将其用作我的nhibernate实体模型绑定器。我可以选择获取和绑定,方法是从数据库中获取实体,然后调用基本DefaultModelBinder将修改后的数据从请求绑定到实体中。

现在我正在尝试实现IModelBinder...我可以很好地获取实体。但是,当我不再需要调用基本DefaultModelBinder时,如何调用“默认模型绑定器”来绑定其余的表单数据呢?

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2020-01-11 02:12:27

你可以这样做:

代码语言:javascript
复制
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;

namespace Media.Onsite.Api.Middleware.ModelBindings
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                // add the custom binder at the top of the collection
                options.ModelBinderProviders.Insert(0, new MyCustomModelBinderProvider());
            });
        }
    }

    public class MyCustomModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context.Metadata.ModelType == typeof(MyType))
            {
                return new BinderTypeModelBinder(typeof(MyCustomModelBinder));
            }

            return null;
        }
    }

    public class MyCustomModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            if (bindingContext.ModelType != typeof(MyType))
            {
                return Task.CompletedTask;
            }

            string modelName = string.IsNullOrEmpty(bindingContext.BinderModelName)
                ? bindingContext.ModelName
                : bindingContext.BinderModelName;

            ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
            if (valueProviderResult == ValueProviderResult.None)
            {
                return Task.CompletedTask;
            }

            bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

            string valueToBind = valueProviderResult.FirstValue;

            if (valueToBind == null /* or not valid somehow*/)
            {
                return Task.CompletedTask;
            }

            MyType value = ParseMyTypeFromJsonString(valueToBind);

            bindingContext.Result = ModelBindingResult.Success(value);

            return Task.CompletedTask;
        }

        private MyType ParseMyTypeFromJsonString(string valueToParse)
        {
            return new MyType
            {
                // Parse JSON from 'valueToParse' and apply your magic here
            };
        }
    }

    public class MyType
    {
        // Your props here
    }

    public class MyRequestType
    {
        [JsonConverter(typeof(UniversalDateTimeConverter))]
        public MyType PropName { get; set; }

        public string OtherProp { get; set; }
    }
}
票数 8
EN

Stack Overflow用户

发布于 2021-08-31 13:54:09

我也处于同样的境地。我需要从数据库实例化对象,然后让MVC/Core为我绑定所有属性。经过几个小时的谷歌搜索和“堆栈溢出”,这是我构建的:

代码语言:javascript
复制
public class MyBinder : ComplexTypeModelBinder
{
    public SettingsBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders) : base(propertyBinders, new LoggerFactory()) { }

    protected override object CreateModel(ModelBindingContext bindingContext)
    {
        return Get_Object_From_Database(); //custom creation logic
    }
}

public class MyBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        //make sure I use it with my type only
        if (context.Metadata.ModelType == typeof(My_Object))
        {
            //get property binders for all the stuff
            var propertyBinders = context.Metadata.Properties.ToDictionary(p => p, p => context.CreateBinder(p));

            return new MyBinder(propertyBinders);
        }

        return null;
    }
}

//startup.cs
services.AddMvc(option =>
{
    option.ModelBinderProviders.Insert(0, new MyBinderProvider());
});

ComplexTypeModelBinder被标记为过时,但微软团队在github上表示,这意味着该类型不应由微软内部使用,但它将继续存在。

使用.NET 5测试成功

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50893324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档