编辑:添加赏金,因为我正在寻找除此之外的MVC3解决方案(如果存在):
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
我的“地址”模型'CityStateZip'
上有一个只读属性。
这是从美国地址获取城市,州,邮政的便捷方式。如果该国家不是美国(调用者应首先检查),则会抛出异常。
public string CityStateZip
{
get
{
if (IsUSA == false)
{
throw new ApplicationException("CityStateZip not valid for international addresses!");
}
return (City + ", " + StateCd + " " + ZipOrPostal).Trim().Trim(new char[] {','});
}
}
这是我模型的一部分,因此它受到约束。在ASP.NET MVC2 RC2之前,此字段在数据绑定期间从未引起过问题。我从来没有真正想过它 - 毕竟它只是只读。
现在虽然在2010年1月的RC2版本中它在数据绑定期间给出了一个错误 - 因为默认的模型绑定器似乎想要检查这个值(即使它是只读的)。
导致此错误的'base.OnModelUpdated'行。
public class AddressModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
base.OnModelUpdated(controllerContext, bindingContext);
最后几分钟对模型绑定器的更改显然导致了行为的这种变化 - 但我还不确定它的重现是什么 - 或者这是否是一个错误?我正在将此传递给MVC团队,但好奇是否有人在此期间有任何建议我如何阻止此属性绑定。
这篇文章非常值得一读 - 但是根本没有提到readonly属性(不是我期望它)。问题(如果有的话)可能比这种情况更广泛 - 我只是不确定是否有任何重复 - 如果有的话!
Input Validation vs. Model Validation in ASP.NET MVC
根据@haacked的要求,这里是stacktrace:
我通过简单地将以下行添加到ANY模型并为相应的操作方法发布帖子来实现此目的。在这个例子中,我将它添加到我最简单的模型中。
public string Foo { get { throw new Exception("bar"); } }
[TargetInvocationException:对象'Rolling_Razor_MVC.Models.ContactUsModel'上的属性访问者'Foo'引发了以下异常:'bar'] System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)+390 System.Web.Mvc。<> c__DisplayClassb。< GetPropertyValueAccessor> b__a()+18 System.Web.Mvc.ModelMetadata.get_Model()+22 System.Web.Mvc.ModelMetadata.get_RealModelType()+29 System.Web.Mvc。< GetValidatorsImpl> d__0.MoveNext()+38 System.Linq。< SelectManyIterator> d__14`2.MoveNext()+273 System.Web.Mvc。< Validate> d__5.MoveNext()+644 System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext,ModelBindingContext bindingContext)+92 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Object model)+60 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+1048 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+280 System.Web.Mvc.Controller.TryUpdateModel(TModel model,String prefix,String [] includeProperties,String [] excludeProperties,IValueProvider valueProvider)+449 System.Web.Mvc.Controller.TryUpdateModel(TModel model)+73
答案 0 :(得分:17)
我相信我遇到了类似的问题。我发布了详细信息:
http://forums.asp.net/t/1523362.aspx
编辑:来自MVC团队的回复(来自以上网址):
我们对此进行了调查并得出结论认证系统的行为符合预期。由于模型验证涉及尝试对所有属性运行验证,并且由于非可空值类型属性具有隐式[Required]属性,因此我们将验证此属性并在此过程中调用其getter。我们知道这是对产品V1的重大改变,但有必要让新模型验证系统正常运行。
您可以通过几种方法解决此问题。其中任何一个都应该有效:
再次感谢您的报告!
答案 1 :(得分:2)
MVC3仍然存在同样的问题。
我认为最好的方法就是在global.asax(来自SevenCentral的回答)中这样做:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
这将禁用所有这些
答案 2 :(得分:1)
这对我来说就像是一个错误。我完全不明白为什么ModelBinder需要检查我的只读属性(可能有一些技术细节,但我绝对不理解,并且不愿意花时间去尝试)。
我在我的解决方案中添加了以下模型元数据提供程序以解决问题
protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName)
{
var metadata = base.CreateMetadataPrototype(attributes, containerType, modelType, propertyName);
if (metadata.IsReadOnly)
{
metadata.IsRequired = false;
}
return metadata;
}
protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
{
var metadata = base.CreateMetadataFromPrototype(prototype, modelAccessor);
if (prototype.IsReadOnly)
{
metadata.IsRequired = false;
}
return metadata;
}
您还需要将以下内容添加到Global.asax.cs
protected void Application_Start()
{
ModelMetadataProviders.Current = new RESModelMetadataProvider();
ModelBinders.Binders.Add(typeof(SmartDate), new SmartDateModelBinder());
...
}
答案 3 :(得分:0)
当然我想我可以将CityStateZip
转换为GetCityStateZip()
但是我不能轻易地将它绑在像silverlight这样的东西上。这可能适用于遇到此问题的其他任何人的临时修复。
答案 4 :(得分:0)
我有完全相同的问题!!
有关我的问题的详情,请访问ASP.NET MVC 2.0 Unused Model Property being called when posting a product to the server?
这是否意味着我们需要对我们的属性进行编程,假设它们将被意外调用(在它依赖的属性被设置/初始化之前等等)...如果是这样,这代表了我们编程实践的变化我想知道如何继续。
同时,我只是有一个简单的'if'检查来解决这个问题。
答案 5 :(得分:0)
我遇到了类似的问题,当表单发回控制器时,我不希望验证的字段收到错误。经过一些谷歌搜索,我遇到了http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/,其中指出名称冲突可能会导致问题。
虽然我认为我的post-back变量类没有冲突的属性名称,但重命名接收错误的属性解决了我的问题。
答案 6 :(得分:0)
相同的问题在MVC 5.2.3中仍然存在,并且甚至不是导致该问题的验证代码。 DefaultModelBinder
会在其验证代码之外调用getter,即使它们是只读属性,即使没有将与这些属性匹配的请求数据传递到控制器也是如此。
在此处查看更详细的说明和我的完整解决方案:https://stackoverflow.com/a/54431404/10987278。
我不确定该解决方案是否可以重构以与MVC 3一起使用,但是希望它可以帮助其他仍遇到同样问题的其他人,在我后来偶然发现此问题的MVC版本中。