加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 使模型绑定适用于没有默认构造函数的模型

发布时间:2020-12-16 07:18:48 所属栏目:asp.Net 来源:网络整理
导读:我一直试图找到一种方法,让模型绑定继续使用带有参数的构造函数的模型. 那个行动: [HttpPost] public ActionResult Create(Company company,HttpPostedFileBase logo) { company.LogoFileName = SaveCompanyLogoImage(logo); var newCompany = _companyProv
我一直试图找到一种方法,让模型绑定继续使用带有参数的构造函数的模型.

那个行动:

[HttpPost]
        public ActionResult Create(Company company,HttpPostedFileBase logo)
        {
            company.LogoFileName = SaveCompanyLogoImage(logo);
            var newCompany = _companyProvider.Create(company);
            return View("Index",newCompany);
        }

和模型

public  Company(CustomProfile customProfile)
        {
            DateCreated = DateTime.Now;
            CustomProfile = customProfile;
        }

我做了我的研究,似乎我需要搞乱我的ninjectControllerfactory:

public class NinjectControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel ninjectKernel;

        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings();
        }

        protected override IController GetControllerInstance(RequestContext requestContext,Type controllerType)
        {
            return controllerType == null
                       ? null
                       : (IController) ninjectKernel.Get(controllerType);
        }

        private void AddBindings()
        {
            ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>();
            ninjectKernel.Bind<IMembershipProvider>().To<MembershipProvider>();
            ninjectKernel.Bind<ICustomProfileProvider>().To<CustomProfileProvider>();
            ninjectKernel.Bind<ICompanyProvider>().To<CompanyProvider>();
        }
    }

我也觉得我需要修改我的模型绑定器,但我不清楚前进的方向:

public class CustomProfileModelBinder : IModelBinder
{
    private const string sessionKey = "CustomProfile";

    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)
    {
        // get the Cart from the session 
        var customProfile = (CustomProfile) controllerContext.HttpContext.Session[sessionKey];
        // create the Cart if there wasn't one in the session data
        if (customProfile == null)
        {
            customProfile = new CustomProfile("default name");
            controllerContext.HttpContext.Session[sessionKey] = customProfile;
        }
        // return the cart
        return customProfile;
    }

    #endregion
}

希望这能解释我的问题,如果这是一个相当冗长的问题,我很抱歉!

谢谢你的帮助

解决方法

在这种情况下,似乎必须从会话中获取您需要创建的参数(CustomProfile).然后,您可以使用从默认模型绑定器派生的Company模型的特定模型绑定器,仅更改它创建Company类实例的方式(然后它将以与默认类型相同的方式填充属性):

public class CompanyModelBinder: DefaultModelBinder
{
    private const string sessionKey = "CustomProfile";

    protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType)
    {
        if(modelType == typeOf(Company))
        {
            var customProfile = (CustomProfile) controllerContext.HttpContext.Session[sessionKey];
            // create the Cart if there wasn't one in the session data
            if (customProfile == null)
            {
                customProfile = new CustomProfile("default name");
                controllerContext.HttpContext.Session[sessionKey] = customProfile;
            }

            return new Company(customProfile);
        }
        else
        {
            //just in case this gets registered for any other type
            return base.CreateModel(controllerContext,bindingContext,modelType)
        }
    }
}

您只需将此绑定器注册到Company类型,方法是将其添加到global.asax Application_Start方法:

ModelBinders.Binders.Add(typeOf(Company),CompanyModelBinder);

另一种选择可能是通过继承DefaultModelBinder来使用Ninject依赖项创建依赖性感知模型绑定器(因为您使用的是Ninject,它知道如何构建具体类型的实例而无需注册它们).
但是,您需要配置一个在Ninject中构建CustomProfile的自定义方法,我相信您可以使用ToMethod().
为此您将提取您将在控制器工厂外提取Ninject内核的配置:

public static class NinjectBootStrapper{
    public static IKernel GetKernel()
    {
        IKernel  ninjectKernel = new StandardKernel();
        AddBindings(ninjectKernel);
    }

    private void AddBindings(IKernel ninjectKernel)
    {
        ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>();
        ninjectKernel.Bind<IMembershipProvider>().To<MembershipProvider>();
        ninjectKernel.Bind<ICustomProfileProvider>().To<CustomProfileProvider>();
        ninjectKernel.Bind<ICompanyProvider>().To<CompanyProvider>();
        ninjectKernel.Bind<CustomProfile>().ToMethod(context => /*try to get here the current session and the custom profile,or build a new instance */ );
    }
}

public class NinjectControllerFactory : DefaultControllerFactory
{
    private readonly IKernel ninjectKernel;

    public NinjectControllerFactory(IKernel kernel)
    {
        ninjectKernel = kernel;
    }

    protected override IController GetControllerInstance(RequestContext requestContext,Type controllerType)
    {
        return controllerType == null
                   ? null
                   : (IController) ninjectKernel.Get(controllerType);
    }
}

在这种情况下,您将创建此模型绑定器:

public class NinjectModelBinder: DefaultModelBinder
{
    private readonly IKernel ninjectKernel;

    public NinjectModelBinder(IKernel kernel)
    {
        ninjectKernel = kernel;
    }

    protected override object CreateModel(ControllerContext controllerContext,Type modelType)
    {
        return ninjectKernel.Get(modelType) ?? base.CreateModel(controllerContext,modelType)
    }
}

你会将global.asax更新为:

IKernel kernel = NinjectBootStrapper.GetKernel();
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
ModelBinders.Binders.DefaultBinder = new NinjectModelBinder(kernel);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读