[英]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);
}
問題是UpdateModel
或TryUpdateModel
不適用於設計object
。 兩種方法都使用typeof(TModel)
。 但是您必須使用model.GetType()
。
看一下: 模型綁定-鍵入外部裝配體
Darin Dimitrov給出了正確的答案:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.