gpt4 book ai didi

asp.net-mvc - 模型绑定(bind) - 输入外部装配体

转载 作者:行者123 更新时间:2023-12-04 05:57:10 24 4
gpt4 key购买 nike

我在程序集中有一个类型,它没有被核心库引用,但被 Web 应用程序引用。例如

namespace MyApp.Models {
public class LatestPosts {
public int NumPosts { get; set; }
}
}

现在我在核心库中有以下代码:
[HttpPost, ValidateAntiForgeryToken]
public ActionResult NewWidget(FormCollection collection) {
var activator = Activator.CreateInstance("AssemblyName", "MyApp.Models.LatestPosts");
var latestPosts = activator.Unwrap();

// Try and update the model
TryUpdateModel(latestPosts);
}

代码很容易解释,但 latestPosts.NumPosts 属性永远不会更新,即使该值存在于表单集合中。

如果有人可以帮助解释为什么这不起作用以及是否有替代方法,我将不胜感激。

谢谢

最佳答案

您的问题与类型在另一个程序集中或您使用 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
...
}

关于asp.net-mvc - 模型绑定(bind) - 输入外部装配体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9378690/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com