asp.net-mvc – 为什么ASP.NET MVC在数据绑定期间关心我的只读属性?

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – 为什么ASP.NET MVC在数据绑定期间关心我的只读属性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:添加赏金,因为我正在寻找除此之外的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版本在数据绑定中给我一个错误 – 因为默认模型binder似乎想要检查这个值(即使它是只读的)。

它是’base.OnModelUpdated’行,导致此错误被触发。

public class AddressModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext,ModelBindingContext bindingContext)
    {
        base.OnModelUpdated(controllerContext,bindingContext);

模型绑定的最后几分钟更改明显地导致了行为的这种变化 – 但是我不太清楚它的后果是什么 – 或者这是否是一个错误?我把这个传递给了MVC团队,但好奇的是,如果其他人有任何建议,同时我如何可以防止这个属性绑定。

这篇文章非常值得阅读有关这些变化 – 但是根本没有提到只读属性(不是我期望的)。这个问题(如果有的话)可能比这种情况更广泛 – 我不知道有什么后果 – 如果有的话!

Input Validation vs. Model Validation in ASP.NET MVC

根据@haacked的要求,这里是stacktrace:

我通过简单地将以下行添加到任何模型,并发布到相应的操作方法。在这种情况下,我把它添加到我最简单的模型中。

public string Foo { get { throw new Exception("bar"); } }

[TargetInvocationException: Property accessor ‘Foo’ on object ‘Rolling_Razor_MVC.Models.ContactUsModel’ threw the following exception:’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

解决方法

我相信我遇到了类似的问题。我已经发布了详细信息:

http://forums.asp.net/t/1523362.aspx

编辑:MVC团队的响应(来自URL):

我们调查了这一点,并得出结论,验证系统的行为是按预期的。由于模型验证涉及尝试在所有属性上运行验证,并且由于非可空值类型属性具有隐式[必需]属性,因此我们将在该过程中验证此属性调用其getter。我们了解到,这是从V1产品的突破性变化,但是必须使新型号验证系统正常运行。

你有几个选择可以解决这个问题。其中任何一个应该工作:

>将Date属性更改为方法而不是属性;这样就可以被MVC框架忽略了。
>将属性类型更改为DateTime?而不是DateTime。这将从此属性删除隐式[必需]。
>清除静态DataAnnotationsModelValidatorProvider.AddImplicitrequiredAttributeForValueTypes标志。这从应用程序范围内的所有非可空值类型属性中移除隐式[必需]。
我们正在考虑在V3中添加一个属性,该信号将向我们发出信号,“不要绑定它,不要验证它,只是假装该属性不存在”。

再次感谢报告!

猜你在找的asp.Net相关文章