Asp.net mvc 使模型绑定对没有默认构造函数的模型起作用

Asp.net mvc 使模型绑定对没有默认构造函数的模型起作用,asp.net-mvc,model,Asp.net Mvc,Model,我一直在试图找到一种方法,让模型绑定与带有参数的构造函数的模型一起进行 行动: [HttpPost] public ActionResult Create(Company company, HttpPostedFileBase logo) { company.LogoFileName = SaveCompanyLogoImage(logo); var newCompany = _companyProvider.Cr

我一直在试图找到一种方法,让模型绑定与带有参数的构造函数的模型一起进行

行动:

 [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>();
        }
    }
希望这能解释我的问题,如果这是一个相当冗长的问题,我很抱歉


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

通过将此文件夹添加到global.asax应用程序\u启动方法,您将仅为公司类型注册此文件夹:

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);
    }
}
您可以将global.asax更新为:

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

哇,多么棒的回答!!非常感谢您抽出时间,这很有启发性!我有点不确定你所说的“(当你使用Ninject时,它知道如何构建具体类型的实例而不需要注册它们”感谢Quantum!我的意思是Ninject知道如何解析具体类(即没有抽象类或接口)无需注册它们,只要它们具有无参数构造函数或其依赖项也可以被解析。例如,您不需要注册像bind()这样的绑定。to(),只要Foo具有无参数构造函数或其依赖项也可以被解析。回答得很好。“ninjectKernel.Get(controllerType)”是否应该NinjectModelBinder中的“字符串”是否替换为“ninjectKernel.Get(modelType)”字符串?
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,
                                         ModelBindingContext bindingContext,
                                         Type modelType)
    {
        return ninjectKernel.Get(modelType) ?? base.CreateModel(controllerContext, bindingContext, modelType)
    }
}
IKernel kernel = NinjectBootStrapper.GetKernel();
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
ModelBinders.Binders.DefaultBinder = new NinjectModelBinder(kernel);