ASP.NET MVC Html.ValidationSummary (true) n'affiche pas les erreurs de modèle

194

J'ai un problème avec Html.ValidationSummary. Je ne veux pas afficher les erreurs de propriété dans ValidationSummary. Et lorsque j'ai défini Html.ValidationSummary (true), il n'affiche pas les messages d'erreur de ModelState. Lorsqu'il y a une exception dans l'action du contrôleur sur la chaîne

MembersManager.RegisterMember(member);

la section catch ajoute une erreur au ModelState:

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

Mais ValidationSummary n'affiche pas ce message d'erreur. Lorsque j'ai défini Html.ValidationSummary (false), tous les messages s'affichent, mais je ne veux pas afficher les erreurs de propriété. Comment puis-je résoudre ce problème?

Voici le code que j'utilise:

Modèle:

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

Manette:

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

Vue:

<% 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)%>
<% } %>
msi
la source

Réponses:

324

Je crois que la façon dont le drapeau ValidationSummary fonctionne est qu'il n'affichera ModelErrors que string.emptycomme clé. Sinon, il est supposé qu'il s'agit d'une erreur de propriété. L'erreur personnalisée que vous ajoutez a la clé «erreur», elle ne s'affichera donc pas lorsque vous appelez ValidationSummary (true). Vous devez ajouter votre message d'erreur personnalisé avec une clé vide comme celle-ci:

ModelState.AddModelError(string.Empty, ex.Message);
Coup
la source
9
@LordCover: Je suppose que cela "fonctionne comme prévu" et non un bug - la surcharge de ValidationSummary () utilisée par défaut exclut les erreurs ModelState associées aux propriétés du modèle lui-même. Cela laisse ces erreurs être représentées par des appels Html.ValidationMessageFor () pour chaque propriété individuelle sans les avoir dupliquées dans le résumé. Dans cet esprit, il apparaît que toute erreur de modèle ajoutée avec une clé non vide est supposée être associée à une propriété de modèle, même si la clé ne correspond pas au nom d'une propriété.
Daniel Schaffer
26
Juste une note pour les autres implémenteurs: ModelState.AddModelError(string.Empty, ex);cela ne semble pas fonctionner non plus. Vous devez utiliser la ModelState.AddModelError(string, string)surcharge comme indiqué ci-dessus.
wolfyuk
2
mise à jour: Dans MVC4, cela ne semble plus être le cas. ModelState.AddModelError ("", ex.Message); travaux
Neil Thompson
4
MVC5 J'avais encore besoin d'appeler l'ex.Message pour le faire fonctionner.
smiggleworth
sauvé la journée! MVC5 a encore quelques problèmes :)
juFo
67

Cela fonctionne mieux, car vous pouvez afficher validationMessage pour une clé spécifiée:

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

et l'afficher comme ceci:

    @Html.ValidationMessage("keyName")
Ingvesund
la source
28

Je sais que c'est un peu vieux et a été marqué comme réponse avec 147 votes positifs, mais il y a autre chose à considérer.

Vous pouvez avoir toutes les erreurs de modèle, la propriété nommée et la chaîne. Les clés vides de même, être affichées dans le ValidationSummary si vous en avez besoin. Il y a une surcharge dans le ValidationSummary qui fera cela.

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

entrez la description de l'image ici

Levitikon
la source
5
Oui! Il suffit de changer @Html.ValidationSummary(true, "", new { @class = "text-danger" })pour@Html.ValidationSummary(false, "", new { @class = "text-danger" })
Xeningem
7

Peut-être comme ça:

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

Et dans l'affichage, ajoutez:

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

OU

<div class="alert alert-danger">
  @Html.ValidationSummary(false)
</div>
Piotr Knut
la source
5
@Html.ValidationSummary(false,"", new { @class = "text-danger" })

L'utilisation de cette ligne peut être utile

sachind
la source
Ajoutez la ligne ci-dessus dans le fichier cshtml.
sachind
2

Dans mon cas, cela ne fonctionnait pas à cause du retour.

À la place d'utiliser:

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

J'ai utilisé:

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

C'est un modèle, c'est donc bien évidemment ModelState.AddModelError("keyName","Message");un modèle qui doit fonctionner avec un modèle.

Cette réponse montre pourquoi. Ajout de validation avec DataAnnotations

Allan Patrick Patzlaff
la source
0

Si presque tout semble correct, une autre chose à surveiller est de vous assurer que le résumé de validation n'est pas explicitement masqué via une substitution CSS comme celle-ci:

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

Cela peut également faire @Html.ValidationSummaryapparaître le caché, car le résumé est rendu dynamiquement avec la validation-summary-validclasse.

alex
la source
0

Tu peux essayer,

<div asp-validation-summary="All" class="text-danger"></div>
Adrita Sharma
la source
note - ce doit être un <div>, si c'est un <span> il ne sera pas rendu.
Stephen Angell
-4

AJOUTEZ-le dans la partie la plus basse de votre vue:

@section Scripts {@ Scripts.Render ("~ / bundles / jqueryval")}

ronIT
la source