programing

웹 API의 모든 응답에 사용자 정의 헤더 추가

goodsources 2023. 6. 15. 21:49
반응형

웹 API의 모든 응답에 사용자 정의 헤더 추가

간단한 질문이고, 답이 간단한 것은 확실하지만 찾을 수가 없습니다.

WebAPI를 사용하고 있으며 모든 응답(동기화 목적으로 개발자가 요청한 서버 날짜/시간)에 사용자 지정 헤더를 다시 보내고 싶습니다.

저는 현재 (global.asax 또는 다른 중앙 위치를 통해) 한 곳에서 모든 응답에 대해 사용자 지정 헤더를 표시할 수 있는 방법에 대한 명확한 예를 찾는 데 어려움을 겪고 있습니다.


답변에 동의합니다. 여기 제 필터(거의 동일)와 제가 WebApi 구성의 Register 기능에 추가한 줄이 있습니다.

참고: DateTime은 NodaTime입니다. 단지 그것을 보는 데 관심이 있었던 실제 이유는 없습니다.

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        actionExecutedContext.Response.Content.Headers.Add("ServerTime", Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()).ToString());
    }

구성 선:

config.Filters.Add(new ServerTimeHeaderFilter());

이를 위해 사용자 정의 Action Filterm)를 사용할 수 있습니다.System.Web.Http.Filters)

public class AddCustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       actionExecutedContext.Response.Headers.Add("customHeader", "custom value date time");
    }
}

그런 다음 Global.asax의 구성에 다음과 같은 필터를 추가하여 컨트롤러의 모든 작업에 적용할 수 있습니다.

GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderFilter());

글로벌 구성 줄 없이 원하는 작업에 필터 특성을 적용할 수도 있습니다.

이 질문에 대한 이전 답변에서는 컨트롤러 작업에서 예외가 발생할 경우 수행할 작업에 대해 설명하지 않습니다.이 작업을 수행하는 데는 두 가지 기본적인 방법이 있습니다.

예외 필터 추가:

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

public class HeaderAdderExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (context.Response == null)
            context.Response = context.Request.CreateErrorResponse(
                HttpStatusCode.InternalServerError, context.Exception);

        context.Response.Content.Headers.Add("header", "value");
    }
}

WebApi 설정에서 다음을 수행합니다.

configuration.Filters.Add(new HeaderAdderExceptionFilter());

이 접근 방식은 WebApi의 기본 예외 처리기가 자체적으로 작성하는 대신 필터에 작성된 HttpResponseMessage를 전송하기 때문에 작동합니다.

기본 예외 처리기 교체:

using System.Net;
using System.Net.Http;
using System.Web.Http.ExceptionHandling;
using System.Web.Http.Results;

public class HeaderAdderExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        HttpResponseMessage response = context.Request.CreateErrorResponse(
            HttpStatusCode.InternalServerError, context.Exception);
        response.Headers.Add("header", "value");

        context.Result = new ResponseMessageResult(response);
    }
}

WebApi 설정에서 다음을 수행합니다.

configuration.Services.Replace(typeof(IExceptionHandler), new HeaderAdderExceptionHandler());

둘 다 같이 사용할 수 없습니다.좋아요, 할 수는 있지만 필터가 이미 예외를 응답으로 변환했기 때문에 처리기는 아무것도 하지 않을 것입니다.

기록된 대로 이 코드는 모든 예외 세부 정보를 클라이언트로 전송합니다.운영 환경에서는 이 작업을 수행하지 않을 수 있으므로 CreateErrorResponse()에서 사용 가능한 모든 오버로드를 확인하고 필요에 맞는 것을 선택하십시오.

Julian의 답변으로 인해 필터를 생성해야 했지만 시스템만 사용해야 했습니다.웹(v4) 및 시스템.Web.Http(v5) 네임스페이스(MVC 패키지는 이 프로젝트에 사용된 특정 프로젝트의 일부가 아닙니다.)

using System.Web;
using System.Web.Http.Filters;
...
public class AddCustomHeaderActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
        actionExecutedContext.ActionContext.Response.Headers.Add("name", "value");
    }
}

그리고 global.asax에 추가하여 모든 컨트롤러/액션에 사용할 수 있습니다.

        GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderActionFilterAttribute());

위의 두 가지 해결책 모두 저에게는 효과가 없었습니다.그들은 컴파일조차 하지 않았습니다.제가 한 일은 이렇습니다.추가됨:

filters.Add(new AddCustomHeaderFilter());

RegisterGlobalFilters(GlobalFilterCollection filters).cs 에 다음 addedFiltersConfig.cs 에 .

public class AddCustomHeaderFilter : ActionFilterAttribute
{
   public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
   {
       actionExecutedContext.HttpContext.Response.Headers.Add("ServerTime", DateTime.Now.ToString());
   }
}

메시지 핸들러가 쉽게 수행할 수 있으며, OK 응답과 예외 사례를 모두 처리합니다.

 public class CustomHeaderHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
       // add header to request if you want
        var response = await base.SendAsync(request, cancellationToken);
        response.Headers.Add("cutomKey", "cutomValue");
        return response;
    }
}

구성에 추가

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

제 요구 사항에 따르면 아래의 코드 한 줄이 목적에 부합합니다.

System.Web.HttpContext.Current.Response.Headers.Add("Key", "Value")

일반 경로와 예외 경로를 한 클래스에 결합했습니다.

public class CustomHeaderAttribute : FilterAttribute, IActionFilter, IExceptionFilter
{
    private static string HEADER_KEY   { get { return "X-CustomHeader"; } }
    private static string HEADER_VALUE { get { return "Custom header value"; } }

    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        return (new CustomHeaderAction() as IActionFilter).ExecuteActionFilterAsync(actionContext, cancellationToken, continuation);
    }

    public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
    {
        return (new CustomHeaderException() as IExceptionFilter).ExecuteExceptionFilterAsync(actionExecutedContext, cancellationToken);
    }

    private class CustomHeaderAction: ActionFilterAttribute
    {
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Response != null)
            { 
                actionExecutedContext.Response.Content.Headers.Add(HEADER_KEY, HEADER_VALUE);
            }
        }
    }

    private class CustomHeaderException : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            if (context.Response == null)
            {
                context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, context.Exception);
            }

            context.Response.Content.Headers.Add(HEADER_KEY, HEADER_VALUE);
        }
    }
}

화려하지는 않지만 적어도 추가 헤더를 제어할 수 있는 한 곳을 제공합니다.지금은 정적인 컨텐츠일 뿐이지만 언제든지 사전 생성기/공장에 연결할 수 있습니다.

컨트롤러 전체에 새 헤더를 추가하려고 할 때도 동일한 문제가 발생했습니다. "서비스"만 추가하십시오.startup.cs 에 HttpContextAccessor();"를 추가한 다음 컨트롤러를 만듭니다.

public class EnController : Controller{

        public EnController(IHttpContextAccessor myHttpAccessor)
        {

            myHttpAccessor.HttpContext.Response.Headers.Add("Content-Language", "en-US");

        }

       ... more methods here... 

}

언급URL : https://stackoverflow.com/questions/20349447/add-custom-header-to-all-responses-in-web-api

반응형