IT

ASP.NET Web API에서 ModelState 유효성 검사 처리

lottoking 2020. 8. 21. 08:00
반응형

ASP.NET Web API에서 ModelState 유효성 검사 처리


ASP.NET Web API로 모델 유효성 검사를 수행하는 방법이 궁금합니다. 내 모델은 다음과 달라집니다.

public class Enquiry
{
    [Key]
    public int EnquiryId { get; set; }
    [Required]
    public DateTime EnquiryDate { get; set; }
    [Required]
    public string CustomerAccountNumber { get; set; }
    [Required]
    public string ContactName { get; set; }
}

그런 다음 API 컨트롤러에 Post 작업이 있습니다.

public void Post(Enquiry enquiry)
{
    enquiry.EnquiryDate = DateTime.Now;
    context.DaybookEnquiries.Add(enquiry);
    context.SaveChanges();
}

if(ModelState.IsValid)에게 전달할 오류 user-메시지를 추가 하고 처리하려면 어떻게해야 우리 합니까?


우려 사항을 분리하기 위해 모델 유효성 검사를 위해 작업 필터를 사용하는 것이 좋습니다. 따라서 API 컨트롤러에서 유효성 검사를 수행하는 방법에 크게 신경 쓸 필요가 없습니다.

using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace System.Web.Http.Filters
{
    public class ValidationActionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var modelState = actionContext.ModelState;

            if (!modelState.IsValid)
                actionContext.Response = actionContext.Request
                     .CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
        }
    }
}

예를 들면 다음과 같습니다.

public HttpResponseMessage Post(Person person)
{
    if (ModelState.IsValid)
    {
        PersonDB.Add(person);
        return Request.CreateResponse(HttpStatusCode.Created, person);
    }
    else
    {
        // the code below should probably be refactored into a GetModelErrors
        // method on your BaseApiController or something like that

        var errors = new List<string>();
        foreach (var state in ModelState)
        {
            foreach (var error in state.Value.Errors)
            {
                errors.Add(error.ErrorMessage);
            }
        }
        return Request.CreateResponse(HttpStatusCode.Forbidden, errors);
    }
}

이렇게하면 다음과 같은 응답이 반환됩니다 (JSON을 가정하지만 XML의 기본 원칙은 동일 함).

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
(some headers removed here)

["A value is required.","The field First is required.","Some custom errorm essage."]

물론 필드 이름, 필드 ID 등을 추가하는 등 원하는 방식으로 오류 개체 / 목록을 구성 할 수 있습니다.

새 건의 POST와 같은 "단방향"Ajax 호출 인 경우에도 호출자에게 요청이 성공 여부를 결정해야합니다. 사용자가 AJAX POST 요청을 통해 자신에 대한 정보를 추가하는 사이트를 상상해보세요. 입력하려는 정보가 유효하지 않은 경우 어떻게하면 저장 작업이 성공했는지 여부를 어떻게 알 수 있습니까?

이 작업을 수행하는 가장 좋은 방법은 사용하는 좋은 올드 HTTP 상태 코드를 같은 200 OK등. 이렇게하면 JavaScript가 올바른 가능성 (오류, 성공 등)을 사용하여 실패를 처리 할 수 ​​있습니다.

다음은 ActionFilter 및 jQuery를 사용하는 방법의 고급 버전에 대한 멋진 안내입니다. http://asp.net/web-api/videos/getting-started/custom-validation


당신이 계획하는 것이 아닐 수도 있습니다.

.net Web Api 2를 사용하는 경우 다음을 수행 할 수 있습니다.

if (!ModelState.IsValid)
     return BadRequest(ModelState);

모델 오류에 따라 다음 결과가 표시됩니다.

{
   Message: "The request is invalid."
   ModelState: {
       model.PropertyA: [
            "The PropertyA field is required."
       ],
       model.PropertyB: [
             "The PropertyB field is required."
       ]
   }
}

System.ComponentModel.DataAnnotations네임 스페이스의 속성을 사용 하여 유효성 검사 규칙을 수 있습니다 . 자세한 내용은 Model Validation-By Mike Wasson 을 참조하십시오.

비디오 ASP.NET Web API, Part 5 : Custom Validation-Jon Galloway 도 참조하십시오 .

기타 참조

  1. WebAPI 및 WebForms를 사용하여 클라이언트 측보기

  2. ASP.NET Web API가 HTTP 메시지를 도메인 모델에 바인딩하는 방법과 Web API에서 미디어 형식을 사용하는 방법.
  3. Dominick Baier-ASP.NET 웹 API 보안
  4. AngularJS 유효성 검사를 ASP.NET 웹 API 유효성 검사에 연결
  5. ASP.NET MVC에서 AngularJS로 ModelState 오류 표시
  6. 클라이언트에 오류를 오류 방법은 무엇입니까? AngularJS / WebApi ModelState
  7. Web API의 종속성 주입 유효성 검사

또는 앱에 대한 간단한 오류 모음을 찾고 있다면 여기에 구현 된 내용이 있습니다.

public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var modelState = actionContext.ModelState;

        if (!modelState.IsValid) 
        {

            var errors = new List<string>();
            foreach (var state in modelState)
            {
                foreach (var error in state.Value.Errors)
                {
                    errors.Add(error.ErrorMessage);
                }
            }

            var response = new { errors = errors };

            actionContext.Response = actionContext.Request
                .CreateResponse(HttpStatusCode.BadRequest, response, JsonMediaTypeFormatter.DefaultMediaType);
        }
    }

오류 메시지 응답은 다음과 같습니다.

{
  "errors": [
    "Please enter a valid phone number (7+ more digits)",
    "Please enter a valid e-mail address"
  ]
}

씨#

    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }

...

    [ValidateModel]
    public HttpResponseMessage Post([FromBody]AnyModel model)
    {

자바 스크립트

$.ajax({
        type: "POST",
        url: "/api/xxxxx",
        async: 'false',
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(data),
        error: function (xhr, status, err) {
            if (xhr.status == 400) {
                DisplayModelStateErrors(xhr.responseJSON.ModelState);
            }
        },
....


function DisplayModelStateErrors(modelState) {
    var message = "";
    var propStrings = Object.keys(modelState);

    $.each(propStrings, function (i, propString) {
        var propErrors = modelState[propString];
        $.each(propErrors, function (j, propError) {
            message += propError;
        });
        message += "\n";
    });

    alert(message);
};

여기에서 모델 상태 오류를 하나씩 확인할 수 있습니다.

 public HttpResponseMessage CertificateUpload(employeeModel emp)
    {
        if (!ModelState.IsValid)
        {
            string errordetails = "";
            var errors = new List<string>();
            foreach (var state in ModelState)
            {
                foreach (var error in state.Value.Errors)
                {
                    string p = error.ErrorMessage;
                    errordetails = errordetails + error.ErrorMessage;

                }
            }
            Dictionary<string, object> dict = new Dictionary<string, object>();



            dict.Add("error", errordetails);
            return Request.CreateResponse(HttpStatusCode.BadRequest, dict);


        }
        else
        {
      //do something
        }
        }

}


http://blogs.msdn.com/b/youssefm/archive/2012/06/28/error-handling-in-asp-net-webapi.aspx에 설명 된대로 예외를 throw 할 수도 있습니다.

이 기사에서 제안하는 작업을 수행하려면 System.Net.Http를 포함해야합니다.


내가 구현하는 문제가 있었다 허용 솔루션 패턴 내이 ModelStateFilter항상 반환을 false(그리고 이후 400)를위한 actionContext.ModelState.IsValid특정 모델 객체에 대한 :

public class ModelStateFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest};
        }
    }
}

JSON 만 허용하므로 사용자 지정 모델 바인더 클래스를 구현했습니다.

public class AddressModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
    {
        var posted = actionContext.Request.Content.ReadAsStringAsync().Result;
        AddressDTO address = JsonConvert.DeserializeObject<AddressDTO>(posted);
        if (address != null)
        {
            // moar val here
            bindingContext.Model = address;
            return true;
        }
        return false;
    }
}

모델을 통해 직접 등록합니다.

config.BindParameter(typeof(AddressDTO), new AddressModelBinder());

참고 URL : https://stackoverflow.com/questions/11686690/handle-modelstate-validation-in-asp-net-web-api

반응형