web-dev-qa-db-fra.com

Obtenir un message d'erreur si ModelState.IsValid échoue?

J'ai cette fonction dans mon contrôleur.

[HttpPost]
public ActionResult Edit(EmployeesViewModel viewModel)
{
    Employee employee = GetEmployee(viewModel.EmployeeId);
    TryUpdateModel(employee);

    if (ModelState.IsValid)
    {
        SaveEmployee(employee);
        TempData["message"] = "Employee has been saved.";
        return RedirectToAction("Details", new { id = employee.EmployeeID });
    }

    return View(viewModel); // validation error, so redisplay same view
}

ModelState.IsValid renvoie toujours false et réaffiche la vue. Mais je n'ai aucune idée de quelle est l'erreur.

Existe-t-il un moyen d’obtenir l’erreur et de la réafficher à l’utilisateur?

56
Steven

Vous pouvez le faire dans votre vue sans rien faire de spécial dans votre action en utilisant Html.ValidationSummary () pour afficher tous les messages d'erreur, ou Html.ValidationMessageFor () pour afficher un message pour une propriété spécifique de le modèle.

Si vous avez toujours besoin de voir les erreurs dans votre action ou votre contrôleur, consultez la propriété ModelState.Errors

32
Daniel Schaffer

Essaye ça

if (ModelState.IsValid)
{
    //go on as normal
}
else
{
    var errors = ModelState.Select(x => x.Value.Errors)
                           .Where(y=>y.Count>0)
                           .ToList();
}

errors sera une liste de toutes les erreurs.

Si vous souhaitez afficher les erreurs à l'utilisateur, il vous suffit de renvoyer le modèle à la vue. Si vous n'avez pas supprimé les expressions Razor @Html.ValidationFor(), elles s'afficheront.

if (ModelState.IsValid)
{
    //go on as normal
}
else
{
    return View(model);
}

La vue montrera toutes les erreurs de validation à côté de chaque champ et/ou dans le ValidationSummary s'il est présent.

113
Captain Kenpachi

Si vous souhaitez générer une seule chaîne de message d'erreur contenant les messages d'erreur ModelState, vous pouvez utiliser SelectMany pour réduire les erreurs dans une seule liste:

if (!ModelState.IsValid)
{
    var message = string.Join(" | ", ModelState.Values
        .SelectMany(v => v.Errors)
        .Select(e => e.ErrorMessage));
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
}
64
JohnnyHK

Si l'état modal n'est pas valide et que l'erreur ne peut pas être vue à l'écran parce que votre contrôle est en accordéon réduit, vous pouvez alors renvoyer le HttpStatusCode afin que le message d'erreur réel s'affiche si vous utilisez F12. Vous pouvez également enregistrer cette erreur dans le journal des erreurs ELMAH. Ci-dessous le code

if (!ModelState.IsValid)
{
              var message = string.Join(" | ", ModelState.Values
                                            .SelectMany(v => v.Errors)
                                            .Select(e => e.ErrorMessage));

                //Log This exception to ELMAH:
                Exception exception = new Exception(message.ToString());
                Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

                //Return Status Code:
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
}

Mais veuillez noter que ce code enregistrera toutes les erreurs de validation. Donc, cela ne devrait être utilisé que lorsque cette situation survient où vous ne pouvez pas voir les erreurs à l'écran.

5
Sachin T Sawant

Essayer

ModelState.Values.First().Errors[0].ErrorMessage
0
Delmirio Segura

C'est une extension de l'échantillon

public class GetModelErrors
{
    //Usage return Json to View :
    //return Json(new { state = false, message = new GetModelErrors(ModelState).MessagesWithKeys() });
    public class KeyMessages
    {
        public string Key { get; set; }
        public string Message { get; set; }
    }
    private readonly ModelStateDictionary _entry;
    public GetModelErrors(ModelStateDictionary entry)
    {
        _entry = entry;
    }

    public int Count()
    {
        return _entry.ErrorCount;
    }
    public string Exceptions(string sp = "\n")
    {
        return string.Join(sp, _entry.Values
            .SelectMany(v => v.Errors)
            .Select(e => e.Exception));
    }
    public string Messages(string sp = "\n")
    {
        string msg = string.Empty;
        foreach (var item in _entry)
        {
            if (item.Value.ValidationState == ModelValidationState.Invalid)
            {
                msg += string.Join(sp, string.Join(",", item.Value.Errors.Select(i => i.ErrorMessage)));
            }
        }
        return msg;
    }

    public List<KeyMessages> MessagesWithKeys(string sp = "<p> ● ")
    {
        List<KeyMessages> list = new List<KeyMessages>();
        foreach (var item in _entry)
        {
            if (item.Value.ValidationState == ModelValidationState.Invalid)
            {
                list.Add(new KeyMessages
                {
                    Key = item.Key,
                    Message = string.Join(null, item.Value.Errors.Select(i => sp + i.ErrorMessage))
                });
            }
        }
        return list;
    }
}
0
OMANSAK

Je ne sais pas s'il s'agit de votre problème, mais si vous ajoutez un utilisateur puis changez le nom de votre application, cet utilisateur restera dans la base de données (bien sûr), mais sera invalide (ce qui est un comportement correct). Cependant, aucune erreur ne sera ajoutée pour ce type d'échec. La liste des erreurs est vide, mais ModelState.IsValid renverra false pour la connexion.

0
user1056921

Ok Vérifiez et ajoutez à regarder:

  1. Faites un point d'arrêt sur votre ligne ModelState dans votre code
  2. Ajouter l'état de votre modèle à votre montre 
  3. Développez ModelState "Values"
  4. Développer les valeurs "Résultats"

Vous pouvez maintenant voir une liste de toutes les sous-clés avec son état de validation à la fin de la valeur.

Alors recherchez la Valeur invalide .

0
Mostafa Basha
ModelState.Values.SelectMany(v => v.Errors).ToList().ForEach(x => _logger.Error($"{x.ErrorMessage}\n"));
0
user781861