Pergunta

No mundo da MVC Eu tenho este modelo vista ...

public class MyViewModel{

[Required]
public string FirstName{ get; set; }    }

... e esse tipo de coisa na minha opinião ...

<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>

A minha pergunta: Se eu enviar o formulário sem fornecer um nome, eu recebo a seguinte mensagem "O campo FirstName é exigido"

OK. Então, eu ir e mudar a minha propriedade para ...

[DisplayName("First Name")]
[Required]
public string FirstName{ get; set; }    

.. e agora obter "O campo Nome é exigido"

Tudo de bom até agora.

Então, agora eu quero a mensagem de erro para exibir "Nome Blah Blah". Como posso substituir a mensagem padrão para exibir DisplayName + "Blah Blah", wihtout anotar todas as propriedades com algo como

[Required(ErrorMessage = "First Name Blah Blah")]

Cheers,

ETFairfax

Foi útil?

Solução

public class GenericRequired: RequiredAttribute
{
    public GenericRequired()
    {
        this.ErrorMessage = "{0} Blah blah"; 
    }
}

Outras dicas

Aqui está uma maneira de fazê-lo sem subclassificação RequiredAttribute. Basta fazer algumas classes de adaptador atributo. Aqui eu estou usando ErrorMessageResourceType / ErrorMessageResourceName (com um recurso), mas você pode facilmente configurar ErrorMessage, ou mesmo verificar a existência de substituições antes de definir estes.

Global.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";
    }
}

Este exemplo teria de criar um arquivo de recurso chamado Resources.resx com ValRequired como a nova mensagem padrão necessário e ValStringLength como a mensagem padrão comprimento da corda excedido. Note-se que para ambos, {0} recebe o nome do campo, que pode ser definida com [Display(Name = "Field Name")].

Parece que RequiredAttribute não implementa IClientValidatable, por isso, se você substituir o RequiredAttribute ele quebra validação do lado do cliente.

Então é isso que eu fiz e ele funciona. Espero que isso ajude alguém.

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

Apenas mudança

[Required] 

para

[Required(ErrorMessage = "Your Message, Bla bla bla aaa!")]

Edit: eu postei isso porque eu estava procurando por esta solução com o atributo [Obrigatório] e teve problema para encontrá-lo. Criação de novo Q / A não parecem tão bom, uma vez que esta questão já existe.

Eu estava tentando resolver a mesma coisa e eu encontrei uma solução muito simples em MVC 4.

Primeiro, você provavelmente teria de armazenar mensagens de erro em algum lugar. Eu costumava recursos personalizados, bem descritos em http://afana.me/post/aspnet-mvc -internationalization.aspx .

É importante, que eu possa obter qualquer recurso (mesmo mensagem de erro) simplesmente chamando ResourcesProject.Resources.SomeCustomError ou ResourcesProject.Resources.MainPageTitle etc. Toda vez que tento para acesso de classe Resources, que leva informações cultura de segmento atual e retorna linguagem certa.

Eu tenho mensagem de erro de validação de campo em ResourcesProject.Resources.RequiredAttribute . Para definir esta mensagem a aparecer em View, basta atualizar atributo [Obrigatório] com estes dois parâmetros.

ErrorMessageResourceType - Tipo que será chamado (no nosso exemplo ResourcesProject.Resources)

ErrorMessageResourceName - Propriedade, que será chamado do tipo acima (No nosso caso RequiredAttribute)

Aqui é um modelo de login muito simplificado, que mostra apenas nome de usuário mensagem de validação. Quando o campo estiver vazio, vai levar a seqüência de ResourcesProject.Resources.RequiredAttribute e apresentar isso como um erro.

    public class LoginModel
    {        
        [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName="RequiredAttribute")]
        [Display(Name = "User name")]
        public string UserName { get; set; }
}

Você pode escrever seu próprio atributo:

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

Esta é cópia do RequiredAttribute de refletor com mensagem de erro alterado.

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

enter descrição da imagem aqui

Agora, os dados de uso de anotação

[CustomRequired]

Isso funcionou para mim. Leia atentamente os comentários dentro do código. (Com base na resposta do Chade).

 // 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"
                    };
                }
            }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top