O ASP.NET MVC Html.ValidationSummary (true) não exibe erros de modelo


194

Estou com algum problema com o Html.ValidationSummary. Não quero exibir erros de propriedade no ValidationSummary. E quando eu defino Html.ValidationSummary (true), ele não exibe mensagens de erro do ModelState. Quando houver alguma exceção na ação do controlador na string

MembersManager.RegisterMember(member);

A seção catch adiciona um erro ao ModelState:

ModelState.AddModelError("error", ex.Message);

Mas ValidationSummary não exibe essa mensagem de erro. Quando defino Html.ValidationSummary (false), todas as mensagens são exibidas, mas não quero exibir erros de propriedade. Como posso resolver este problema?

Aqui está o código que estou usando:

Modelo:

public class Member
{
        [Required(ErrorMessage = "*")]
        [DisplayName("Login:")]
        public string Login { get; set; }

        [Required(ErrorMessage = "*")]
        [DataType(DataType.Password)]
        [DisplayName("Password:")]
        public string Password { get; set; }

        [Required(ErrorMessage = "*")]
        [DataType(DataType.Password)]
        [DisplayName("Confirm Password:")]
        public string ConfirmPassword { get; set; }
}

Controlador:

[HttpPost]
public ActionResult Register(Member member)
{
    try
    {
        if (!ModelState.IsValid)
            return View();

        MembersManager.RegisterMember(member);
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("error", ex.Message);

        return View(member);
    }
}

Visão:

<% using (Html.BeginForm("Register", "Members", FormMethod.Post, 
                        new { enctype = "multipart/form-data" })) {%> 
    <p>
        <%= Html.LabelFor(model => model.Login)%>
        <%= Html.TextBoxFor(model => model.Login)%>
        <%= Html.ValidationMessageFor(model => model.Login)%>
    </p>

    <p>
        <%= Html.LabelFor(model => model.Password)%>
        <%= Html.PasswordFor(model => model.Password)%>
        <%= Html.ValidationMessageFor(model => model.Password)%>
    </p>

    <p>
        <%= Html.LabelFor(model => model.ConfirmPassword)%>
        <%= Html.PasswordFor(model => model.ConfirmPassword)%>
        <%= Html.ValidationMessageFor(model => model.ConfirmPassword)%>
    </p>

    <div>
        <input type="submit" value="Create" />
    </div>

    <%= Html.ValidationSummary(true)%>
<% } %>

Respostas:


324

Acredito que a maneira como o sinalizador ValidationSummary funciona é que ele exibirá apenas ModelErrors string.emptycomo a chave. Caso contrário, presume-se que seja um erro de propriedade. O erro personalizado que você está adicionando possui a chave 'error', portanto não será exibido quando você chamar ValidationSummary (true). Você precisa adicionar sua mensagem de erro personalizada com uma chave vazia como esta:

ModelState.AddModelError(string.Empty, ex.Message);

9
@ LordCover: Eu acho que isso está "funcionando como projetado" e não um bug - a sobrecarga de ValidationSummary () usada por padrão exclui erros ModelState associados às propriedades do modelo em si. Isso deixa esses erros a serem representados pelas chamadas Html.ValidationMessageFor () para cada propriedade individual sem que elas sejam duplicadas no resumo. Assim, parece que qualquer erro de modelo adicionado a uma chave não vazia é considerado associado a uma propriedade de modelo, mesmo que a chave não corresponda ao nome de uma propriedade.
Daniel Schaffer

26
Apenas uma observação para outros implementadores: ModelState.AddModelError(string.Empty, ex);também não parece funcionar. Você deve usar a ModelState.AddModelError(string, string)sobrecarga como mostrado acima.
wolfyuk

2
atualização: No MVC4, isso não parece mais ser o caso. ModelState.AddModelError ("", ex.Message); funciona
Neil Thompson

4
MVC5 Eu ainda precisava ligar para o ex.Message para fazê-lo funcionar.
smiggleworth

salvou o dia! MVC5 ainda tem alguns problemas :)
jufo

67

Isso funciona melhor, pois você pode mostrar validationMessage para uma chave especificada:

    ModelState.AddModelError("keyName","Message");

e exibi-lo assim:

    @Html.ValidationMessage("keyName")

28

Eu sei que isso é meio antigo e foi marcado como respostas com 147 votos a favor, mas há algo mais a considerar.

Você pode ter todos os erros de modelo, a propriedade nomeada e string.Empty keys iguais, serão mostrados no ValidationSummary, se necessário. Há uma sobrecarga no ValidationSummary que fará isso.

    //   excludePropertyErrors:
    //   true to have the summary display model-level errors only, or false to have
    //   the summary display all errors.
    public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors);

insira a descrição da imagem aqui


5
Sim! Basta mudar @Html.ValidationSummary(true, "", new { @class = "text-danger" })para@Html.ValidationSummary(false, "", new { @class = "text-danger" })
Xeningem 25/03

7

Talvez assim:

[HttpPost]
public ActionResult Register(Member member)
{
    try
    {
       if (!ModelState.IsValid)
       {
          ModelState.AddModelError("keyName", "Form is not valid");
          return View();
       }
       MembersManager.RegisterMember(member);
    }
    catch (Exception ex)
    {
       ModelState.AddModelError("keyName", ex.Message);
       return View(member);
    }
}

E no display adicione:

<div class="alert alert-danger">
  @Html.ValidationMessage("keyName")
</div>

OU

<div class="alert alert-danger">
  @Html.ValidationSummary(false)
</div>

5
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

Usar esta linha pode ser útil


Adicione a linha acima no arquivo cshtml.
sachind

2

No meu caso, não estava funcionando por causa do retorno.

Ao invés de usar:

return RedirectToAction("Rescue", "CarteiraEtapaInvestimento", new { id = investimento.Id, idCarteiraEtapaResgate = etapaDoResgate.Id });

Eu usei:

return View("ViewRescueCarteiraEtapaInvestimento", new CarteiraEtapaInvestimentoRescueViewModel { Investimento = investimento, ValorResgate = investimentoViewModel.ValorResgate });

É um modelo, então é óbvio que ModelState.AddModelError("keyName","Message"); deve trabalhar com um modelo.

Esta resposta mostra o porquê. Adicionando validação com DataAnnotations


0

Se quase tudo parece certo, outra coisa a se observar é garantir que o resumo da validação não esteja sendo explicitamente oculto por meio de alguma substituição de CSS como esta:

.validation-summary-valid {
    display: none;
}

Isso também pode fazer com que o @Html.ValidationSummaryapareça oculto, pois o resumo é renderizado dinamicamente com a validation-summary-validclasse.


0

Podes tentar,

<div asp-validation-summary="All" class="text-danger"></div>

note - este deve ser um <div>, se for um <span>, não será renderizado.
Stephen Angell

-4

Adicione-o na parte mais baixa da sua visualização:

@ scripts de seção {@ Scripts.Render ("~ / bundles / jqueryval")}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.