ASP.NET MVC - Custom validation message for value types

前端 未结 7 1894
粉色の甜心
粉色の甜心 2020-11-30 02:46

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

7条回答
  •  無奈伤痛
    2020-11-30 03:11

    Make your own ModelBinder by extending DefaultModelBinder:

    public class LocalizationModelBinder : DefaultModelBinder
    

    Override 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:

    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.

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

    ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder();
    

    Cheers!

提交回复
热议问题