4

我一直在想办法让模型绑定继续使用带有参数的构造函数的模型。

那个行动:

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

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

感谢您的帮助

4

1 回答 1

8

在这种情况下,您需要创建的参数(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)
        }
    }
}

通过将其添加到 global.asax Application_Start 方法,您将仅为 Company 类型注册此活页夹:

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,
                                         ModelBindingContext bindingContext,
                                         Type modelType)
    {
        return ninjectKernel.Get(modelType) ?? base.CreateModel(controllerContext, bindingContext, modelType)
    }
}

您将 global.asax 更新为:

IKernel kernel = NinjectBootStrapper.GetKernel();
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
ModelBinders.Binders.DefaultBinder = new NinjectModelBinder(kernel);
于 2012-11-23T20:48:28.763 回答