asp.net-mvc ASP.NET MVC - 值类型的自定义验证消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/646270/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:24:51  来源:igfitidea点击:

ASP.NET MVC - Custom validation message for value types

asp.net-mvcvalidation

提问by Giovanni Galbo

When I use UpdateModel or TryUpdateModel, the MVC framework is smart enough to know if you are trying to pass in a null into a value type (e.g. the user forgets to fill out the required Birth Day field) .

当我使用 UpdateModel 或 TryUpdateModel 时,MVC 框架足够智能,可以知道您是否尝试将 null 传入值类型(例如,用户忘记填写所需的出生日字段)。

Unfortunately, I don't know how to override the default message, "A value is required." in the summary into something more meaningful ("Please enter in your Birth Day").

不幸的是,我不知道如何覆盖默认消息“需要一个值”。在摘要中加入更有意义的内容(“请输入您的出生日期”)。

There has to be a way of doing this (without writing too much work-around code), but I can't find it. Any help?

必须有一种方法可以做到这一点(无需编写太多的变通代码),但我找不到它。有什么帮助吗?

EDIT

编辑

Also, I guess this would also be an issue for invalid conversions, e.g. BirthDay = "Hello".

另外,我想这也是无效转换的问题,例如 BirthDay = "Hello"。

回答by Cristi Todoran

Make your own ModelBinder by extending DefaultModelBinder:

通过扩展 DefaultModelBinder 来制作你自己的 ModelBinder:

public class LocalizationModelBinder : DefaultModelBinder

Override SetProperty:

覆盖 SetProperty:

        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);

        foreach (var error in bindingContext.ModelState[propertyDescriptor.Name].Errors.
            Where(e => IsFormatException(e.Exception)))
        {
            if (propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)] != null)
            {
                string errorMessage =
                    ((TypeErrorMessageAttribute)propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)]).GetErrorMessage();
                bindingContext.ModelState[propertyDescriptor.Name].Errors.Remove(error);
                bindingContext.ModelState[propertyDescriptor.Name].Errors.Add(errorMessage);
                break;
            }
        }

Add the function bool IsFormatException(Exception e)to check if an Exception is a FormatException:

添加函数bool IsFormatException(Exception e)以检查异常是否为 FormatException:

if (e == null)
            return false;
        else if (e is FormatException)
            return true;
        else
            return IsFormatException(e.InnerException);

Create an Attribute class:

创建一个属性类:

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
public class TypeErrorMessageAttribute : Attribute
{
    public string ErrorMessage { get; set; }
    public string ErrorMessageResourceName { get; set; }
    public Type ErrorMessageResourceType { get; set; }

    public TypeErrorMessageAttribute()
    {
    }

    public string GetErrorMessage()
    {
        PropertyInfo prop = ErrorMessageResourceType.GetProperty(ErrorMessageResourceName);
        return prop.GetValue(null, null).ToString();
    }
}

Add the attribute to the property you wish to validate:

将属性添加到要验证的属性:

[TypeErrorMessage(ErrorMessageResourceName = "IsGoodType", ErrorMessageResourceType = typeof(AddLang))]
    public bool IsGood { get; set; }

AddLang is a resx file and IsGoodType is the name of the resource.

AddLang 是一个 resx 文件,IsGoodType 是资源的名称。

And finally add this into Global.asax.cs Application_Start:

最后将其添加到 Global.asax.cs Application_Start 中:

ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder();

Cheers!

干杯!

回答by Darin Dimitrov

With the DefaultModelBinder it is possible to override the default required error message but unfortunately it would apply globally which IMHO renders it completely useless. But in case you decide to do it here's how:

使用 DefaultModelBinder 可以覆盖默认所需的错误消息,但不幸的是,它会全局应用,恕我直言,它完全无用。但如果您决定这样做,方法如下:

  1. Add the App_GlobalResources folder to your ASP.NET site
  2. Add a resources file called Messages.resx
  3. Inside the resources file declare a new string resource with the key PropertyValueRequiredand some value
  4. In Application_Start add the following line:

    DefaultModelBinder.ResourceClassKey = "Messages";
    
  1. 将 App_GlobalResources 文件夹添加到您的 ASP.NET 站点
  2. 添加名为 Messages.resx 的资源文件
  3. 在资源文件中声明一个带有键PropertyValueRequired和一些值的新字符串资源
  4. 在 Application_Start 中添加以下行:

    DefaultModelBinder.ResourceClassKey = "Messages";
    

As you can see there's no link between the model property you are validating and the error message.

如您所见,您正在验证的模型属性与错误消息之间没有链接。

In conclusion it is better to write custom validation logic to handle this scenario. One way would be to use a nullable type (System.Nullable<TValueType>) and then:

总之,最好编写自定义验证逻辑来​​处理这种情况。一种方法是使用可空类型 (System.Nullable<TValueType>),然后:

if (model.MyProperty == null || 
    /** Haven't tested if this condition is necessary **/ 
    !model.MyProperty.HasValue)
{
    ModelState.AddModelError("MyProperty", "MyProperty is required");
}

回答by Alex

I've been using the awesome xValvalidation framework. It lets me do all my validation in the model (Even LINQ-SQL :)). It also emits the javascript required for client side validation.

我一直在使用很棒的xVal验证框架。它让我可以在模型中进行所有验证(甚至 LINQ-SQL :))。它还发出客户端验证所需的 javascript。

EDIT:Sorry left out the linkfor how to get it working for LINQ-SQL

编辑:很抱歉左出链接如何得到它的工作对LINQ-SQL

The basic workflow goes something like this.

基本的工作流程是这样的。

public partial class YourClass
{
    [Required(ErrorMessage = "Property is required.")]
    [StringLength(200)]
    public string SomeProperty{ get; set; }
}


try
{
    // Validate the instance of your object
    var obj = new YourClass() { SomeProperty = "" }
    var errors = DataAnnotationsValidationRunner.GetErrors(obj);
    // Do some more stuff e.g. Insert into database
}
catch (RulesException ex)
{
    // e.g. control name 'Prefix.Title'
    ex.AddModelStateErrors(ModelState, "Prefix");   
    ModelState.SetModelValue("Prefix.Title", new ValueProviderResult(ValueProvider["Prefix.Title"].AttemptedValue, collection["Prefix.Title"], System.Globalization.CultureInfo.CurrentCulture));

}

回答by Alex

how about this?

这个怎么样?

[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
                   ErrorMessage = "Characters are not allowed.")]

That should allow you to tag properties with specific error messages for whatever MVC validators you want to use...

这应该允许您为要使用的任何 MVC 验证器标记具有特定错误消息的属性......

回答by user134936

In ASP.NET MVC 1, I met this problem too.

在 ASP.NET MVC 1 中,我也遇到了这个问题。

In my project, there is a model or business object named "Entry", and its primary key EntryId is int? type, and the value of EntryId can be allowd to input by users.

在我的项目中,有一个名为“Entry”的模型或业务对象,它的主键EntryId是int?类型,EntryId 的值可以允许用户输入。

So the problem is, when the field is blank or zero or some integer value that has existed, the custom error messages can be shown well, but if the value is some non-integer value like "a", i can not find a way to use the custom message to replace the default message like "The value 'a' is invalid".

所以问题是,当该字段为空或零或某个已存在的整数值时,自定义错误消息可以很好地显示,但如果该值是诸如“a”之类的非整数值,我找不到方法使用自定义消息替换默认消息,如“值 'a' 无效”。

when i track the error message in ModelState, i found when the value is non-integer, there will be two errors related to EntryId, and the first item's error message is blank...

当我在ModelState中跟踪错误信息时,发现当值为非整数时,会出现两个与EntryId相关的错误,并且第一项的错误信息为空...

Now i have to use such an ugly code to hack the problem.

现在我必须使用如此丑陋的代码来解决这个问题。

if (ModelState["EntryId"].Errors.Count > 1)
{
    ModelState["EntryId"].Errors.Clear(); //should not use ModelState["EntryId"].remove();
    ModelState.AddModelError("EntryId", "必须为大于0的整数"); //必须为大于0的整数 means "it should be an integer value and great than 0"
}  

but this makes controller fat, hope there is a real solution to solve it.

但这使控制器变胖,希望有一个真正的解决方案来解决它。

回答by Daniel A. White

Look up ModelState.AddError.

抬头看ModelState.AddError

回答by Omu

yes, there is a way, you must use System.ComponentModel.DataAnnotationsin combination with xValand you are going to be able to set validation rules and messages (u can even use resource files for localization) for each of your property using Attributes
look herehttp://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/

是的,有一种方法,您必须将System.ComponentModel.DataAnnotationsxVal结合使用,并且您将能够使用 Attributes
外观为您的每个属性设置验证规则和消息(您甚至可以使用资源文件进行本地化)这里http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/