您的问题无关的事实,类型是在另一个组件,或者您动态地创建Activator.Create
它。下面的代码说明中另一个具有更加简化的方式问题:
[HttpPost, ValidateAntiForgeryToken]
public ActionResult NewWidget(FormCollection collection)
{
// notice the type of the latestPosts variable -> object
object latestPosts = new MyApp.Models.LatestPosts();
TryUpdateModel(latestPosts);
// latestPosts.NumPosts = 0 at this stage no matter whether you had a parameter
// called NumPosts in your request with a different value or not
...
}
问题从Controller.TryUpdateModel<TModel>
使用的typeof(TModel)
代替model.GetType()
以确定如在this connect issue解释模型类型(其与原因关闭的事实茎:by design
)。
的解决办法是推出定制TryUpdateModel
方法,这将表现为你所期望的:
protected internal bool MyTryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class
{
if (model == null)
{
throw new ArgumentNullException("model");
}
if (valueProvider == null)
{
throw new ArgumentNullException("valueProvider");
}
Predicate<string> propertyFilter = propertyName => new BindAttribute().IsPropertyAllowed(propertyName);
IModelBinder binder = Binders.GetBinder(typeof(TModel));
ModelBindingContext bindingContext = new ModelBindingContext()
{
// in the original method you have:
// ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()),
ModelName = prefix,
ModelState = ModelState,
PropertyFilter = propertyFilter,
ValueProvider = valueProvider
};
binder.BindModel(ControllerContext, bindingContext);
return ModelState.IsValid;
}
然后:
[HttpPost, ValidateAntiForgeryToken]
public ActionResult NewWidget(FormCollection collection)
{
object latestPosts = new MyApp.Models.LatestPosts();
MyTryUpdateModel(latestPosts, null, null, null, ValueProvider);
// latestPosts.NumPosts will be correctly bound now
...
}
由于工作一种享受! – nfplee 2012-02-22 14:13:37
雅谢谢! – Rookian 2012-06-22 08:43:51
当我面对这样的解决方案时,我意识到我离成为一名真正优秀的程序员非常遥远。在这个问题上失去了一天。非常感谢你。 – Alexandre 2014-06-12 12:54:36