【问题标题】:Custom error for view-model int overflow (invalid values)视图模型 int 溢出的自定义错误(无效值)
【发布时间】:2016-01-20 01:03:11
【问题描述】:

在我的模型中,我有一个可为空的 int。

在视图中,我有一个“数字”类型的输入。

问题是用户可能会输入一个大于最大可能整数值的数字,这会导致以下错误:

值 [value] 对 [field] 无效

我想更改此消息,并且对属性进行 [Range(...)] 验证没有帮助,因为没有调用我的验证,因为框架无法将值解析为 int。

--------- 编辑 ---------

我的验证在正常输入下正常执行,如下所示:

我的验证没有被调用的意思是我已经读到如果框架无法将值解析为 int(因为该值超过了整数的最大值),它会忽略任何进一步的“不必要" 验证。

因此我的 Range 验证被忽略,如下所示:

我尝试创建自定义 ValidationAttribute,但具有相同的行为(在正常整数输入时被正确调用,但在整数输入溢出时被忽略)

--------- /编辑 ---------

我见过的所有解决方案,都建议绑定一个自定义资源文件,我可以在其中覆盖无效值的默认消息。

但我希望能够在每个属性中指定一条自定义消息,以防出现无效值。

我考虑过使用字符串而不是整数,并创建一个自定义 ValidationAttribute 来尝试将其解析为整数。

还有其他选择吗?

// 编辑:我可以通过客户端验证(在某种程度上)避免这个问题 - 但我想知道是否可以从服务器端,以防有人编辑 html 并强制更高价值

【问题讨论】:

  • 你是什么意思我的验证都没有被调用?如果您的代码正确,他们将被调用。您需要出示您的代码。
  • 它对我来说很好用(参考this DotNetFiddle)。如果您输入9999999999999,则一旦您退出控件,就会显示范围验证消息。
  • 但那是客户端验证 - 这部分解决了问题,但我想要服务器端验证..
  • 您正在获得服务器端验证(但可能不是您期望的方式)。发生的事情是 DefaultModelBinder 试图将值设置为 9999999999999 它不能,因此 value is not valid 错误被添加到 ModelState (“范围”条件甚至不是检查是因为没有意义)
  • 完全正确 - 所以我的问题仍然存在,我如何(如果可以)覆盖该默认消息,如果可以,我可以将不同的消息设置为不同的属性吗?

标签: asp.net asp.net-mvc asp.net-mvc-5


【解决方案1】:

您可以通过多种方式验证用户输入:

这是自定义验证属性的示例:

public class MyIntegerValidationAttribute : ValidationAttribute
{
    public string[] PropertyNames { get; }

    public MyIntegerValidationAttribute(params string[] propertyNames)
    {
        PropertyNames = propertyNames;
    }    

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty);

        //here you have values of your properties 
        var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<int>();

        if (YOUR_CUSTOM_CONDITION)
        {
            return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        return null;
    }
}

public class ViewModel
{
    [MyIntegerValidationAttribute("B", "C", ErrorMessage = "My error message")]
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
}

【讨论】:

  • 我不能将数据注释用作公关。我的帖子(见编辑),我也想要服务器端验证(另见编辑)
  • 我已经通过自定义验证属性的示例实现更新了我的答案,这应该可以解决您的问题。
  • 感谢您的尝试,但使用您的确切代码,我仍然收到默认错误消息。请看这两张图片:i.imgur.com/gkY2HVO.pngi.imgur.com/U2d8ffC.png
  • 尝试关闭该字段上的任何其他验证并仅使用该自定义属性(在该属性内执行所有验证检查)。
  • 我没有其他验证 - 我使用了您的确切 ViewModel
猜你喜欢
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 2015-10-17
  • 2012-07-28
相关资源
最近更新 更多