Подтвердить что ты не робот

ASP.NET MVC - Пользовательское сообщение проверки для типов значений

Когда я использую UpdateModel или TryUpdateModel, среда MVC достаточно умна, чтобы знать, пытаетесь ли вы передать нуль в тип значения (например, пользователь забывает заполнить требуемое поле "День рождения" ).

К сожалению, я не знаю, как переопределить сообщение по умолчанию: "Требуется значение". в резюме в нечто более значимое ( "Пожалуйста, введите в свой день рождения" ).

Должен быть способ сделать это (без написания слишком много кода для работы), но я не могу его найти. Любая помощь?

ИЗМЕНИТЬ

Кроме того, я предполагаю, что это также будет проблемой для неверных преобразований, например. BirthDay = "Hello".

4b9b3361

Ответ 1

Создайте свой собственный ModelBinder, расширив DefaultModelBinder:

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), чтобы проверить, является ли исключение исключением FormatException:

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

Создать класс атрибута:

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

Ура!

Ответ 2

В DefaultModelBinder можно переопределить требуемое по умолчанию сообщение об ошибке, но, к сожалению, оно применимо во всем мире, которое ИМХО делает его совершенно бесполезным. Но в случае, если вы решили сделать это здесь, как:

  • Добавить папку App_GlobalResources на ваш сайт ASP.NET
  • Добавить файл ресурсов с именем Messages.resx
  • Внутри файла ресурсов объявить новый ресурс строки с ключом PropertyValueRequired и некоторым значением
  • В Application_Start добавьте следующую строку:

    DefaultModelBinder.ResourceClassKey = "Messages";
    

Как вы видите, нет никакой связи между проверяемой моделью и сообщением об ошибке.

В заключение лучше написать специальную логику проверки для обработки этого сценария. Один из способов - использовать тип с нулевым значением (System.Nullable <TValueType> ), а затем:

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

Ответ 3

Я использую awesome xVal рамки проверки. Это позволяет мне выполнять всю мою проверку в модели (даже LINQ-SQL:)). Он также испускает javascript, необходимый для проверки на стороне клиента.

РЕДАКТИРОВАТЬ: Извините за ссылка за то, как заставить его работать для LINQ-SQL

Основной рабочий процесс выглядит примерно так.

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));

}

Ответ 4

как насчет этого?

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

Это должно позволить вам отмечать свойства с конкретными сообщениями об ошибках для любых валидаторов MVC, которые вы хотите использовать...

Ответ 5

Посмотрите ModelState.AddError.

Ответ 6

В ASP.NET MVC 1 я тоже встретил эту проблему.

В моем проекте есть модель или бизнес-объект с именем "Enter", а его первичный ключ EntryId - int? тип, а значение EntryId может быть разрешено вводить пользователями.

Таким образом, проблема заключается в том, что, когда поле пустое или нулевое или какое-то целочисленное значение, которое существует, пользовательские сообщения об ошибках могут быть хорошо отображены, но если значение представляет собой некоторое нецелое значение типа "a", я не могу найти способ использования настраиваемого сообщения для замены сообщения по умолчанию, например "Значение" a "недействительно".

когда я отслеживаю сообщение об ошибке в ModelState, я обнаружил, что если значение не целое, будут две ошибки, связанные с EntryId, а сообщение об ошибке первого элемента пустое...

Теперь я должен использовать такой уродливый код, чтобы взломать проблему.

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"
}  

но это делает контрольный жир, надеюсь, что существует реальное решение для его решения.

Ответ 7

да, есть способ, вы должны использовать System.ComponentModel.DataAnnotations в комбинации с xVal, и вы сможете установить правила и сообщения для проверки ( u может даже использовать файлы ресурсов для локализации) для каждого вашего свойства, используя атрибуты
смотрите здесь http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/