当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《ASP.NETMVC-值类型的自定义验证消息》经验,为你挑选了2个好方法。

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

不幸的是,我不知道如何覆盖默认消息"需要一个值".在总结中更有意义的事情("请输入您的出生日").

必须有一种方法可以做到这一点(没有编写过多的解决方法),但我找不到它.有帮助吗?

编辑

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



1> 小智..:

通过扩展DefaultModelBinder创建自己的ModelBinder:

public class LocalizationModelBinder : DefaultModelBinder

覆盖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;
            }
        }

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

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

创建一个Attribute类:

[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();
    }
}

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

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

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

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

ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder();

干杯!


很好的答案,但它有一个问题.`propertyDescriptoy.Name`并不总是用作`ModelState`的键.您应该使用继承的`CreateSubPropertyName`方法来创建密钥,如下所示:`ModelMetadata propertyMetadata = bindingContext.PropertyMetadata [propertyDescriptor.Name]; string propertyName = CreateSubPropertyName(bindingContext.ModelName,propertyMetadata.PropertyName);`然后你可以使用`bindingContext.ModelState [propertyName]`代替.
Ow,...和属性类中的`GetErrorMessage`应该返回`ErrorMessage`,以防它不为空(或反过来).它没有考虑属性的用户指定内联错误消息(没有任何资源)的情况.

2> Darin Dimitr..:

使用DefaultModelBinder,可以覆盖默认的必需错误消息,但不幸的是,它将全局应用,恕我直言使其完全无用.但如果你决定这样做,那么如何:

    将App_GlobalResources文件夹添加到ASP.NET站点

    添加名为Messages.resx的资源文件

    在资源文件中,使用键PropertyValueRequired和一些值声明一个新的字符串资源

    在Application_Start中添加以下行:

    DefaultModelBinder.ResourceClassKey = "Messages";
    

正如您所看到的,您要验证的模型属性与错误消息之间没有任何关联.

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

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

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有