编辑:添加赏金是因为我正在寻找除此之外的 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);

最后几分钟对 modelbinder 的更改显然导致了这种行为变化 - 但我不太确定它的后果是什么 - 或者这是否是一个错误?我正在将其传递给 MVC 团队,但很好奇是否还有其他人在此期间对我如何阻止此属性绑定有任何建议。

这篇文章非常值得阅读有关这些更改的内容 - 但根本没有提到只读属性(不是我所期望的)。这个问题(如果有的话)可能比这种情况更广泛 - 我只是不确定是否有任何后果 - 如果有的话!

输入验证对比ASP.NET MVC 中的模型验证


根据 @haacked 的要求,这是堆栈跟踪:

我通过简单地将以下行添加到任何模型并发布到相应的操作方法来得到这一点。在本例中,我将其添加到我最简单的模型中。

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

[目标调用异常:对象“Rolling_Razor_MVC.Models.ContactUsModel”上的属性访问器“Foo”抛出以下异常:“bar”]system.componentModel.reflectPropertyDescriptor.getValue(对象组件)+390 System.web.mvc。<> c__displayClassb。u003CGetPropertyValueAccessor> b__a()+18 system.web.mvc.modelmetadata.get_model()+22 system.web.mvc.modelmetadata.get_realmodeltype()+29 system.web.mvc。u003CGetValidatorsImpl> d__0.movenext()+38 system.linq。u003CSelectManyIterator> d__14`2.Movenext()+273 System.Web.mvc。u003CValidate> d__5.movenext()+644 system.web.mvc.defaultmodelbinder.onmodelupdated(contranterContext contranctercontext,ModelBindingContext bindingContext)+92 bindingContext)+92 system.web.mvc.mvc.mvc.mvc.deffc.defeftmodelbinder +6 .web。 mvc.defaultmodelbinder.bindcomplexmodel(contrancterContext ContrancterContext,modelBindingContext bindingContext)+1048 System.Web.MVC.MVC.DefaultMmodelBinder.bindModel.bindmodel(contranceerContectext) EL模型,字符串前缀,字符串[ ]包括eproperties,string []排除eproperties,ivalueprovider valueProvider)+449 system.web.mvc.controller.tryupdatemodel(tmodel Model)+73

有帮助吗?

解决方案

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

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


编辑:MVC 团队的回复(来自上述 URL):

我们对此进行了调查并得出结论,验证系统的行为符合预期。由于模型验证涉及尝试对所有属性运行验证,并且由于不可空值类型属性具有隐式 [Required] 属性,因此我们将验证此属性并在此过程中调用其 getter。我们知道这是对产品 V1 的重大更改,但为了使新的模型验证系统正确运行,这是必要的。

您有几种选择来解决这个问题。其中任何一项都应该有效:

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

再次感谢您的报告!

其他提示

还是具有MVC3相同的问题。

我认为最好的办法是只此在Global.asax中(从SevenCentral的答案):

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

这会停用所有这些

这看起来全世界所有喜欢我的错误。我完全无法理解为什么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());

    ...
}

当然,我想我可以转换CityStateZipGetCityStateZip()但我不能在像Silverlight中很容易因为它绑定。这可能会为一个临时的解决工作,其他任何人遇到此问题。

我有相同的问题!!

有关我的问题的详细信息,您可以访问的 ASP.NET MVC 2.0未使用的模型属性发布一个产品到服务器时,被称为?

这是否意味着我们需要把我们的假设,他们将被称为意外性程序(这取决于性质之前建立/初始化等)......如果是这样,这代表了我们的编程习惯的改变和我想知道如何进行。

同时,我只是有一个简单的“如果”检查赶走的问题。

我有一个类似的问题,这没想到被验证时的形式回发到控制器中接收到错误的字段。一些google搜索后,我碰到的 http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/ 它指出,名称冲突可能会导致问题。

虽然我没想到我回来后可变上课了冲突的属性名称,重命名属性收到错误解决我的问题。

同样的问题仍然存在于MVC 5.2.3,并且它甚至不是导致问题的验证代码。所述DefaultModelBinder调用的,即使它们是只读属性和即使没有请求数据被传递给匹配那些特性的控制器其验证代码以外的吸气剂。

请参阅更详细的解释和我的完整的解决方案在这里: https://stackoverflow.com/a/54431404/10987278

我不知道是否该解决方案可重构与MVC 3工作,但希望它可以帮助别人从MVC的更高版本跨越这个问题迷迷糊糊,我也做了同样的问题仍然是痛苦。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top