【问题标题】:Error assigning null to a nullable int - "The value 'null' is not valid for property"将 null 分配给可为 null 的 int 时出错 - “值‘null’对属性无效”
【发布时间】:2011-08-30 20:53:21
【问题描述】:

我的视图模型中有这个属性:

[DisplayName("Region")]
public int? RegionId { get; set; }

我将我的视图模型传递给我的控制器,如果 RegionId 为空,它会在 ModelState.IsValid 处失败。如果我将一个整数传递给它,它就可以正常工作。

错误信息是:

值'null'对区域无效

在检查ModelState.IsValid 之前,我也尝试过调用它,但我得到了同样的错误:

if (viewModel.RegionId == null)
    viewModel.RegionId = (int?)null;

这里有什么问题?为什么我不能将 null 分配给可以为 null 的东西?

【问题讨论】:

  • if (viewModel.RegionId == null) viewModel.RegionId = (int?)null; 为什么在 null 已经为 null 时还要分配它?
  • @Bala - 我查看了有关同一问题的其他帖子,他们说分配 (int?)null 而不是 null
  • @Steven Bala 提出了一个很好的观点。如果 RegionID 已经为空,则无需执行任何操作,只需省略第二行,因为即使它有效,它也不会执行任何操作。

标签: c# asp.net asp.net-mvc asp.net-mvc-3


【解决方案1】:

这是另一种可能的解释。

我正在使用 jQuery 将 AJAX 发布到 MVC 操作方法,如下所示:

$.post('url/here',dataObject);

jQuery 会将数据对象转换为查询字符串。我使用默认模型绑定器将值推送到我的 ViewModel 中。模型验证失败,并显示“值 'null' 对于 field name 无效”。但该属性是一个可为空的 int。检查原始 POST 后,我发现我正在发布的数据对象被序列化为如下所示的查询字符串:

Field1=null&Field2=value&Field3=value

不是这个:

Field1=&Field2=value&Field3=value

因此,模型验证抱怨将字符串文字“null”分配给我的可空 int 是可以理解的。一种解决方案是在 POST 之前检查 NULL。我希望我有时间深入研究,但我只是切换到发送正确处理空值的数据对象的 JSON 表示。

【讨论】:

  • 在我的情况下也是同样的原因。它是由没有
  • 干得好,先生!那正是我的问题。我正在将我的 JSON 对象上的一些属性初始化为 form.Prop = null。将其更改为 form.Prop = '' 一切都再次快乐。
  • 你为我节省了几个小时。谢谢。
【解决方案2】:

在 Global.asax.cs 文件的 Application_Start 方法中,添加以下行:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

问题在于,即使对于可为空的值类型,默认情况下,默认 ValidatorProvider 也会添加一个“必需”属性。

【讨论】:

  • 您还有其他正在使用的 ModelValidatorProviders 吗?在 Global.asax.cs 中,尝试在上面显示的行之前添加以下两行:ModelValidatorProviders.Providers.Clear(); ModelValidatorProviders.Providers.Add(new DataAnnotationsModelMetadataValidatorProvider());
  • 这是 MVC 中的错误吗?从文档中它说这个“获取或设置一个指示是否需要不可为空的值类型的值”这似乎意味着它不应该将它应用于不可为空的类型。 msdn.microsoft.com/en-us/library/…
  • 我认为您误读了文档。此属性适用于所有值类型,可空或不可空。
  • 文档清楚地说明Gets or sets a value that indicates whether non-nullable value types are required. 我在 ASP.NET MVC3 源代码中查找并确认了这一点。仅当此设置为 true 时才添加隐式 RequiredAttribute,元数据表示该属性 IsRequired 并且还没有 RequiredAttribute。 ModelMetadata 默认情况下表示引用类型和可空类型不需要模型。我遇到了同样的问题,您提出的解决方案对我也不起作用。当我找出为什么会发生这种情况以及如何解决它时,我会发布解决方案。
  • -1;这不起作用。也许它是“我的”项目中的其他东西(也许流利的验证也弄乱了它)。但是“我的”项目已经在这样做了,并且没有必需属性,它需要可以为空的字段。
【解决方案3】:

请看这里:ModelState validation fails for nullable types

可能正在传递字符串“null”。在我的场景中,我更新为一个空字符串 "" 并解决了这个错误。

【讨论】:

    【解决方案4】:

    我认为问题不在于分配空值,而是消耗代码除了空值之外没有。该分配是完全有效的(尽管您的空检查被反转,并且强制转换是多余的)。

    viewModel.RegionId = null;
    

    顺便说一句,您可以使用HasValue 检查可空类型上的空值。虽然实际上这与空检查没有什么不同,只是看起来更干净一些:

    if (viewModel.RegionId.HasValue)
    {
        // do something
    }
    

    【讨论】:

    • 从技术上讲,两个例子中的条件都是多余的。
    • 不,如果当前不为空,则将值设置为空。
    • 对。那么为什么不直接将其设置为空而不检查呢?结果是一样的。
    • 看看你的意思,这个想法是从问题的例子中展示 HasValue 的使用,这里没有真正的上下文。
    【解决方案5】:

    我遇到了这个问题。

    我的问题是我在 POST 中将有问题的属性显式设置为 null。因此,类似于您所拥有的,请求看起来像:

    RegionId = null
    

    在我的例子中,它就像省略显式声明一样简单(例如,不要说它为空,只是不要发送任何数据)

    【讨论】:

      【解决方案6】:

      我感觉问题出在您显示的示例代码之外。我创建了一个示例应用程序,它只创建一个表单并具有一个可为空的字段,但它按预期工作。我将开始消除您设置中的其他变量,直到您可以使用可空属性的工作 ViewModel,并且您应该能够确定导致问题的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-12
        • 1970-01-01
        • 2015-08-24
        • 1970-01-01
        • 1970-01-01
        • 2017-02-17
        • 2011-06-01
        相关资源
        最近更新 更多