MVC直接在单个对象上调用模型绑定器



是否有方法可以为单个对象调用模型绑定器?

我不想要/需要一个自定义模型绑定器——我只想做这样的事情:

MyViewModel1 vModel1 = new MyViewModel1();
InvokeModelBinder(vModel1);
MyViewModel2 vModel2= new MyViewModel2();
InvokeModelBinder(vModel2);

完成后,vModel1和vModel2的属性都已绑定到传入请求中的内容。由于我们的控制器/操作的编写方式,我不一定要在操作方法的输入列表中列出vModel1和vModel2(因为最终可能会有一个很长的视图模型列表,可以选择绑定)。

使用控制器。调用UpdateModel:

MyViewModel1 vModel1 = new MyViewModel1();
UpdateModel(vModel1);

注意,如果ModelState在控制器中有验证错误(与在操作中传递的模型相关),UpdateModel(与任何模型)抛出异常,尽管UpdateModel成功并且vModel1已更新。因此,应该删除ModelState中的错误,或者将UpdateModel放在try/catch中并忽略异常

这在很多层面上都是错误的:

  1. 这不是ASP。. NET MVC被设计为工作。
  2. 你的行为没有定义一个明确的合同,他们期望什么数据。
  3. 你从中得到了什么?闻起来像糟糕的设计。

模型绑定由反射驱动。在调用一个操作之前,它将反映方法参数列表,对于每个对象及其属性,它将调用模型绑定器,从各种值提供者(表单POST值提供者、url参数等)中为每个属性查找值。在模型绑定期间,也会执行ModelState验证。

所以不使用默认的ASP。. NET MVC来做这些,你就失去了这一切。

即使你像这样手动获取模型绑定器:

IModelBinder modelBinder = ModelBinders.Binders.GetBinder(typeof(MyObject));
MyObject myObject = (MyObject ) modelBinder.BindModel(this.ControllerContext, ** ModelBindingContext HERE**);

你可以看到你需要初始化一个ModelBindingContext。. NET MVC将根据它所反映的当前属性在内部执行。这是ASP的剪辑。. NET MVC源代码:

protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) {
// collect all of the necessary binding properties
Type parameterType = parameterDescriptor.ParameterType;
IModelBinder binder = GetModelBinder(parameterDescriptor);
IDictionary<string, ValueProviderResult> valueProvider = controllerContext.Controller.ValueProvider;
string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor);
// finally, call into the binder
ModelBindingContext bindingContext = new ModelBindingContext() {
    FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified
    ModelName = parameterName,
    ModelState = controllerContext.Controller.ViewData.ModelState,
    ModelType = parameterType,
    PropertyFilter = propertyFilter,
    ValueProvider = valueProvider
};
object result = binder.BindModel(controllerContext, bindingContext);
return result;

}

相关内容

  • 没有找到相关文章

最新更新