MVC:Переопределить сообщение проверки по умолчанию
-
05-07-2019 - |
Вопрос
В мире MVC у меня есть эта модель представления...
public class MyViewModel{
[Required]
public string FirstName{ get; set; } }
... и такого рода вещи, на мой взгляд...
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>
Мой вопрос:Если я отправляю эту форму без указания имени, я получаю следующее сообщение "Поле FirstName является обязательным".
ОК.Итак, я иду и меняю свою собственность на...
[DisplayName("First Name")]
[Required]
public string FirstName{ get; set; }
..а теперь получаем "Поле Первого имени обязательно".
Пока все хорошо.
Итак, теперь я хочу, чтобы в сообщении об ошибке отображалось "Имя и бла-бла".Как я могу переопределить сообщение по умолчанию для отображения DisplayName + "Бла-бла-бла", без аннотирования всех свойств чем-то вроде
[Required(ErrorMessage = "First Name Blah Blah")]
Ваше здоровье,
etfairфакс
Решение
public class GenericRequired: RequiredAttribute
{
public GenericRequired()
{
this.ErrorMessage = "{0} Blah blah";
}
}
Другие советы
Вот способ сделать это без выделения подклассов RequiredAttribute
.Просто создайте несколько классов адаптеров атрибутов.Здесь я использую ErrorMessageResourceType
/ErrorMessageResourceName
(с ресурсом), но вы могли бы легко установить ErrorMessage
, или даже проверьте наличие переопределений, прежде чем устанавливать их.
Глобальный.asax.cs:
public class MvcApplication : HttpApplication {
protected void Application_Start() {
// other stuff here ...
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(RequiredAttribute), typeof(CustomRequiredAttributeAdapter));
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(StringLengthAttribute), typeof(CustomStringLengthAttributeAdapter));
}
}
private class CustomRequiredAttributeAdapter : RequiredAttributeAdapter {
public CustomRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
: base(metadata, context, attribute)
{
attribute.ErrorMessageResourceType = typeof(Resources);
attribute.ErrorMessageResourceName = "ValRequired";
}
}
private class CustomStringLengthAttributeAdapter : StringLengthAttributeAdapter {
public CustomStringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
: base(metadata, context, attribute)
{
attribute.ErrorMessageResourceType = typeof(Resources);
attribute.ErrorMessageResourceName = "ValStringLength";
}
}
В этом примере вам нужно создать файл ресурсов с именем Resources.resx с ValRequired
в качестве нового требуемого сообщения по умолчанию и ValStringLength
поскольку длина строки превысила сообщение по умолчанию.Обратите внимание, что для обоих, {0}
получает имя поля, которое вы можете задать с помощью [Display(Name = "Field Name")]
.
Похоже, что RequiredAttribute не реализует IClientValidatable , поэтому, если вы переопределите RequiredAttribute, это нарушит проверку на стороне клиента.
Итак, это то, что я сделал, и это работает.Надеюсь, это кому-то поможет.
public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
public CustomRequiredAttribute()
{
this.ErrorMessage = "whatever your error message is";
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage,
ValidationType = "required"
};
}
}
Просто измени
[Required]
Для
[Required(ErrorMessage = "Your Message, Bla bla bla aaa!")]
Редактировать:Я опубликовал это, потому что искал это решение с атрибутом [Required] и у меня возникли проблемы с его поиском.Создание новых вопросов и ответов выглядит не очень хорошо, поскольку этот вопрос уже существует.
Я пытался решить то же самое, и я нашел очень простое решение в MVC 4.
Во-первых, вам, вероятно, придется хранить сообщения об ошибках в каком-нибудь месте.Я использовал пользовательские ресурсы, хорошо описанные на http://afana.me/post/aspnet-mvc-internationalization.aspx.
Важно то, что я могу получить любой ресурс (даже сообщение об ошибке), просто вызвав ResourcesProject.Ресурсы.Некоторая пользовательская ошибка или Ресурспроект.Ресурсы.Заголовок главной страницы и т.д.Каждый раз, когда я пытаюсь получить доступ к классу ресурсов, он берет информацию о культуре из текущего потока и возвращает правильный язык.
У меня есть сообщение об ошибке для проверки поля в Ресурспроект.Ресурсы.Требуемый атрибут.Чтобы настроить отображение этого сообщения в режиме просмотра, просто обновите атрибут [Обязательно] этими двумя параметрами.
Тип источника сообщения об ошибке - Тип, который будет вызываться (в нашем примере ResourcesProject.Resources)
Имя источника сообщения об ошибке - Свойство, которое будет вызываться для указанного выше типа (в нашем случае RequiredAttribute)
Вот очень упрощенная модель входа в систему, которая показывает только сообщение о проверке имени пользователя.Когда поле пусто, оно примет строку из Ресурспроект.Ресурсы.Требуемый атрибут и отобразите это как ошибку.
public class LoginModel
{
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName="RequiredAttribute")]
[Display(Name = "User name")]
public string UserName { get; set; }
}
Вы можете написать свой собственный атрибут:
public class MyRequiredAttribute : ValidationAttribute
{
MyRequiredAttribute() : base(() => "{0} blah blah blah blaaaaaah")
{
}
public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
string str = value as string;
if (str != null)
{
return (str.Trim().Length != 0);
}
return true;
}
}
Это копия RequiredAttribute из Reflector с измененным сообщением об ошибке.
using Resources;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Web;
using System.Web.Mvc;
public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
public CustomRequiredAttribute()
{
ErrorMessageResourceType = typeof(ValidationResource);
ErrorMessageResourceName = "RequiredErrorMessage";
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = GetRequiredMessage(metadata.DisplayName),
ValidationType = "required"
};
}
private string GetRequiredMessage(string displayName) {
return displayName + " " + Resources.ValidationResource.RequiredErrorMessageClient;
}
}
App_GlobalResources/ValidationResource.resx App_GlobalResources/Разрешение
Теперь используйте аннотацию данных
[CustomRequired]
У меня это сработало.Внимательно прочитайте комментарии внутри кода.(Основано на ответе Чада).
// Keep the name the same as the original, it helps trigger the original javascript
// function for client side validation.
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute, IClientValidatable
{
public RequiredAttribute()
{
this.ErrorMessage = "Message" // doesnt get called again. only once.
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = "Message", // this gets called on every request, so it's contents can be dynamic.
ValidationType = "required"
};
}
}