繁体   English   中英

之后在ASP.NET MVC中进行模型绑定:如何将QueryString值转换为视图模型?

[英]Afterwards Model Binding in ASP.NET MVC: How to convert QueryString values into a view model?

我有一个没有参数的动作方法。

QueryString集合包含我所有的值。 QueryString的键与我的视图模型属性匹配。

var queryStringValueProvider = new QueryStringValueProvider(ControllerContext);
var providerResult = queryStringValueProvider.GetValue(ValidationKeys.Id); // ?!

var viewModelTypeName = queryString[ValidationKeys.ViewModelType];

var viewModelType = Type.GetType(viewModelTypeName);
var viewModelInstance = providerResult.ConvertTo(viewModelType); // throws an InvalidOperationException

如何将QueryString集合转换为视图模型? 当您仅将视图模型传递给操作方法参数时,ASP.NET MVC已经做到了。 因此,我需要使用ASP.NET MVC机制进行事后模型绑定

要手动执行自定义模型绑定,请创建一个自定义模型绑定器(实现IModelBinder )并将其注册到您的IoC容器中。

或者,您可以在action方法内部调用this.UpdateModel 这应该将ValueProvider中的值(RouteData,Request.Form集合和QueryString)绑定到模型。

您要的是序列化。 为了简单地执行此操作,可以放置一个构造函数重载,该重载接受QueryStringValueProvider作为参数,并且该构造函数负责根据提供程序初始化所有模型的属性。 如果坚持使用字符串,则可以很容易地将这样的构造函数放到可以被所有模型继承的模型基类中。

也可以将其内置到扩展方法中,因此可以将其称为“按需”而不是在构建时使用。

您可以使用TryUpdateModel

public ContentResult TestAction()
{
   var model = new MyModel();

   if(TryUpdateModel(model, new QueryStringValueProvider(ControllerContext)))
   {
      return Content("success");
   }

   return Content("failed");
}

我的控制器动作

var viewModelTypeName = queryString[ValidationKeys.ViewModelType];
var viewModelType = Type.GetType(viewModelTypeName);
var instance = Activator.CreateInstance(viewModelType);
UpdateModelUsingQueryString(instance);

更新模型

protected internal void UpdateModelUsingQueryString<TModel>(TModel model) where TModel : class
{
    if (model == null) throw new ArgumentNullException("model");

    Predicate<string> propertyFilter = propertyName => new BindAttribute().IsPropertyAllowed(propertyName);
    var binder = Binders.GetBinder(typeof(TModel));

    var bindingContext = new ModelBindingContext()
    {
        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()),
        ModelState = ModelState,
        PropertyFilter = propertyFilter,
        ValueProvider = new QueryStringValueProvider(ControllerContext)
    };
    binder.BindModel(ControllerContext, bindingContext);
}

问题是UpdateModelTryUpdateModel不适用于设计object 两种方法都使用typeof(TModel) 但是您必须使用model.GetType()

看一下: 模型绑定-键入外部装配体

Darin Dimitrov给出了正确的答案:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM