programing tip

ModelState.IsValid가 실패하면 오류 메시지가 표시됩니까?

itbloger 2020. 11. 19. 07:54
반응형

ModelState.IsValid가 실패하면 오류 메시지가 표시됩니까?


컨트롤러에이 기능이 있습니다.

[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계속 false를 반환하고 뷰를 다시 표시합니다. 그러나 나는 그 오류가 무엇인지 전혀 모른다.

오류를 가져 와서 사용자에게 다시 표시하는 방법이 있습니까?


Html.ValidationSummary ()사용하여 모든 오류 메시지를 표시하거나 Html.ValidationMessageFor () 를 사용하여 모델의 특정 속성에 대한 메시지를 표시하면 작업에서 특별한 작업을 수행하지 않고도 뷰에서이 작업을 수행 할 수 있습니다 .

여전히 작업 또는 컨트롤러 내에서 오류를 확인해야하는 경우 ModelState.Errors 속성을 참조하세요.


이 시도

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

오류 는 모든 오류의 목록입니다.

사용자에게 오류를 표시하려면 모델을 뷰로 반환하기 만하면되고 Razor @Html.ValidationFor()식을 제거하지 않은 경우 표시됩니다.

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

뷰는 각 필드 옆 및 / 또는 ValidationSummary (있는 경우)에 모든 유효성 검사 오류를 표시합니다.


오류 메시지가 포함 된 단일 오류 메시지 문자열을 생성하려는 경우 오류를 단일 목록으로 병합하는 데 ModelState사용할 수 있습니다 SelectMany.

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

Modal State가 유효하지 않고 컨트롤이 축소 된 아코디언에 있기 때문에 화면에 오류가 표시되지 않는 경우 F12를 수행하면 실제 오류 메시지가 표시되도록 HttpStatusCode를 반환 할 수 있습니다. 또한이 오류를 ELMAH 오류 로그에 기록 할 수 있습니다. 아래는 코드입니다

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

But please note that this code will log all validation errors. So this should be used only when such situation arises where you cannot see the errors on screen.


It is sample extension

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

If anyone is here for WebApi (not MVC) you just return the ModelState object:

return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);


I have no idea if this is your problem, but if you add a user and then change the name of your application, that user will remain in the database (of course), but will be invalid (which is correct behavior). However, there will be no error added for this type of failure. The error list is empty, but ModelState.IsValid will return false for the login.


Ok Check and Add to Watch:

  1. Do a breakpoint at your ModelState line in your Code
  2. Add your model state to your Watch
  3. Expand ModelState "Values"
  4. Expand Values "Results View"

Now you can see a list of all SubKey with its validation state at end of value.

So search for the Invalid value.


Try

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

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

참고URL : https://stackoverflow.com/questions/5212248/get-error-message-if-modelstate-isvalid-fails

반응형