Web API에서 X-HTTP-Method-Override에 대한 DelegatingHandler를 구현하는 방법

공용 도메인을 통해 REST Web API를 배포 할 때 HTTP 동사 지원과 관련된 문제가 발생하는 경우가 있습니다. 이와 관련하여 두 가지 문제는 이전 웹 브라우저에서 HTTP 동사에 대한 제한된 지원 (즉, HTTP GET 및 HTTP POST 만 지원)과 HTTP GET 또는 HTTP POST가 아닌 트래픽을 차단하는 공격적인 방화벽입니다. 이러한 경우 애플리케이션이 PUT 또는 DELETE를 어떻게 지원합니까? X-HTTP-Method-Override HTTP 헤더가 구출되는 정확한 위치입니다.

X-HTTP-Method-Override HTTP 헤더는 해킹과 다소 유사하게 작동합니다. JavaScript를 통해 또는 XMLHttpRequestHTTP POST 호출을 사용하는 웹 브라우저 의 개체를 통해 웹 API를 호출 할 때 PUT 또는 DELETE 값으로 헤더를 추가 할 수 있습니다 . 그런 다음 위임 처리기가 호출 될 HTTP 메서드를 가로 채서 적절한 작업을 수행하도록 할 수 있습니다.

이 기사에서는 요청-응답 파이프 라인 앞에 위임 처리기를 사용하여 요청을 변경하여 유효한 메시지를 애플리케이션에 전송하거나 응답을 변경하여 클라이언트에 유효한 응답을 다시 보내는 방법에 대해 설명합니다.

HTTP 동사 및 위임 처리기

클라이언트, 웹 브라우저 또는 웹 애플리케이션의 방화벽에 의해 부과 된 제한으로 인해 HTTP 동사 GET 및 POST 만 사용하도록 제한되는 경우 PUT 및 DELETE를 지원하는 해결 방법을 구현해야합니다. 이 해결 방법에는 일반적으로 HTTP POST 호출 내에서 사용할 동사를 지정하는 요청에 X-HTTP-Method-Override HTTP 헤더를 추가하는 것이 포함됩니다. 또한 헤더를 확인하고 헤더가있는 경우 호출하려는 HTTP 메서드를 호출하는 위임 처리기가 애플리케이션에 필요합니다.

구현을 시작하기 전에 위임 처리기가 무엇이며 여기에서 사용하는 이유를 간략히 살펴 보겠습니다. 위임 처리기 및 기타 메시지 처리기는 요청 처리 파이프 라인의 초기에 실행됩니다. HTTP 요청을 수락하고 HTTP 응답을 반환하는 클래스입니다. 위임 처리기는 HttpModulesASP.Net 과 유사합니다 . 그러나과 달리 HttpModules위임 처리기는 연결될 수 있습니다. 하나의 위임 처리기는 다른 위임 처리기를 참조 할 수 있습니다. 이전 기사 인 "Web API에서 메시지 처리기를 사용하는 방법"에서 처리기 위임에 대해 자세히 알아볼 수 있습니다.

웹 API 컨트롤러 만들기

다음과 유사한 Web API 컨트롤러가 있다고 가정합니다.

공용 클래스 AuthorsController : ApiController

    {

        // GET : api / 작성자

        공용 IEnumerable Get ()

        {

            return new string [] {“Joydip”,“Kanjilal”};

        }

        // GET : api / authors / 1

        공개 문자열 Get (int id)

        {

            return“Joydip Kanjilal”;

        }

        // POST API / 작성자

        공개 무효 Post ([FromBody] 저자 값) {}

        // PUT api / author / 1

        public void Put (int id, [FromBody] Author 값) {}

        // api / author / 1 삭제

        public void Delete (int id) {}

    }

X-HTTP-Method-Override에 대한 DelegatingHandler 만들기

이제 X-HTTP-Method-Override 핸들러를 구현해 보겠습니다. 이것은 메시지 핸들러이므로 평소와 같이 DelegatingHandler클래스를 확장해야합니다 .

공용 클래스 CustomMessageHandler : DelegatingHandler

    {

        readonly string [] httpMethodsList = {“DELETE”,“HEAD”,“PUT”};

        const 문자열 httpMethodOverrideheader;

        보호 된 재정의 작업 SendAsync (HttpRequestMessage 요청, CancellationToken 취소 Token)

        {

            if (request.Method == HttpMethod.Post && request.Headers.Contains (httpMethodOverrideheader))

            {               

                var httpMethod = request.Headers.GetValues ​​(httpMethodOverrideheader) .FirstOrDefault ();

                if (httpMethodsList.Contains (httpMethod, StringComparer.InvariantCultureIgnoreCase))

                {                  

                    request.Method = new HttpMethod (httpMethod);

                }

            }

            return base.SendAsync (request, cancelToken);

        }

    }

코드는 매우 자명합니다. X-HTTP-Method-Override 헤더가있는 HTTP POST를 확인합니다. 헤더가 메소드 목록에 있으면 요청 메소드가 변경됩니다.

DelegatingHandler 등록

다음 단계는 핸들러를 등록하는 것입니다. 아래 코드 스 니펫에 표시된대로 WebApiConfig 클래스의 MessageHandlers 콜렉션에이 새 핸들러를 추가하여이를 수행 할 수 있습니다.

public static void Register (HttpConfiguration 구성)

{

    config.MessageHandlers.Add (new CustomMessageHandler ());

     // 웹 API 경로

    config.MapHttpAttributeRoutes ();

     config.Routes.MapHttpRoute (

        이름 :“DefaultApi”,

        routeTemplate :“api / {controller} / {id}”,

        기본값 : new {id = RouteParameter.Optional}

    );

}

또는 Application_Start아래와 같이 Global.asax.cs 파일 의 이벤트 처리기를 사용하여 위임 처리기를 등록 할 수 있습니다.

protected void Application_Start (객체 발신자, EventArgs e)

        {

            RegisterRoutes (RouteTable.Routes);

            GlobalConfiguration.Configuration.MessageHandlers.Add (new CustomMessageHandler ());

        }

이것이 서버 측에서해야 할 전부입니다. 클라이언트 측, 즉 웹 브라우저에서 아래 코드 스 니펫에 표시된대로 재정의 헤더를 추가해야합니다.

$ .ajax ({

  URL :“// localhost : 9820 / api / Authors / 1”,

  유형 :“POST”,

  데이터 : JSON.stringify (authorData),

  헤더 : {

      “Content-Type”:“application / json”,

      “X-HTTP-Method-Override”:“PUT”},

})

이전 코드 스 니펫에서 볼 수 있듯이 요청 헤더에서 호출 할 HTTP 메서드를 지정 X-HTTP-Method-Override : DELETE하거나 X-HTTP-Method-Override : PUT리소스에 POST 호출을 수행하기 만하면 됩니다.