.NET API에서 HttpContext에 액세스하는 방법
.NET API에서 HTTP 요청 및 HTTP 응답과 관련된 모든 정보는
HttpContext
라는 전역 개체에 저장됩니다. 어떻게 액세스할 수 있습니까?이 문서에서는 오래된 코드
HttpContext.Current
를 제거하는 방법과 더 테스트 가능한 코드를 작성하기 위해 수행할 수 있는 작업에 대해 알아봅니다.HttpContext를 직접 사용하지 않는 이유
몇 년 전에는 코드에서 직접
HttpContext
에 액세스했습니다.예를 들어 Cookies 컬렉션에 액세스해야 하는 경우
var cookies = HttpContext.Current.Request.Cookies;
효과가 있었습니다. 그러나 이 접근 방식에는 큰 문제가 있습니다. 테스트를 설정하기 어렵게 만듭니다.
사실 우리는 클라이언트 클래스와 HttpContext 사이에 직접적인 종속성을 추가한 정적 인스턴스를 사용하고 있었습니다.
이것이 .NET 팀이 해당 클래스의 검색을 추상화하기로 결정한 이유입니다. 이제
IHttpContextAccessor
를 사용해야 합니다.IHttpContextAccessor 추가
이제 HTTP 헤더 "데이터 위치"에 이름이 저장되어 있는 특정 도시의 현재 날씨를 반환하는 엔드포인트/WeatherForecast를 노출하는 이 .NET 프로젝트가 있습니다.
실제 계산(음, 진짜... 모든 것이 가짜입니다. 😅)은 WeatherService에서 수행합니다. 특히
GetCurrentWeather
방법으로.public WeatherForecast GetCurrentWeather()
{
string currentLocation = GetLocationFromContext();
var rng = new Random();
return new WeatherForecast
{
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)],
Location = currentLocation
};
}
현재 위치를 검색해야 합니다.
우리가 말했듯이, 우리는 더 이상 이전
HttpContext.Current.Request
에 의존할 수 없습니다.대신 생성자에
IHttpContextAccessor
를 주입하고 이를 사용하여 Request
개체에 액세스해야 합니다.public WeatherService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
IHttpContextAccessor
인스턴스가 있으면 이를 사용하여 현재 HttpContext 헤더에서 정보를 검색할 수 있습니다.string currentLocation = "";
if (_httpContextAccessor.HttpContext.Request.Headers.TryGetValue("data-location", out StringValues locationHeaders) && locationHeaders.Any())
{
currentLocation = locationHeaders.First();
}
return currentLocation;
쉽죠? 거의 끝났습니다.
시작 클래스 구성
이런 방식으로 애플리케이션을 실행하면 현재 HTTP 요청에 액세스할 수 없습니다.
애플리케이션에서 서비스로 추가
IHttpContextAccessor
를 지정하지 않았기 때문입니다.이를 위해 다음 명령어를 추가하여
ConfigureServices
클래스를 업데이트해야 합니다.services.AddHttpContextAccessor();
Microsoft.Extensions.DependencyInjection
네임스페이스에서 가져온 것입니다.이제 프로젝트를 실행할 수 있습니다!
data-location
헤더에서 도시를 지정하는 끝점을 호출하면 반환된 WeatherForecast
개체의 Location
필드에서 해당 값을 볼 수 있습니다.추가 개선 사항
충분한가?
이런 식으로 사용하면 HTTP 컨텍스트에 액세스해야 하는 모든 클래스는 여러 객체를 모의해야 하기 때문에 설정하기 매우 어려운 테스트를 갖게 됩니다.
실제로
HttpContext.Request.Headers
를 모의하기 위해 HttpContext
, Request
, Headers
에 대한 모의를 만들어야 합니다.이것은 테스트를 작성하고 이해하기 어렵게 만듭니다.
따라서 제 제안은
HttpContext
액세스를 별도의 클래스로 래핑하고 실제로 필요한 메서드만 노출하는 것입니다.예를 들어
GetValueFromRequestHeader
서비스의 IHttpContextWrapper
에서 HTTP 요청 헤더에 대한 액세스를 래핑할 수 있습니다.public interface IHttpContextWrapper
{
string GetValueFromRequestHeader(string key, string defaultValue);
}
이는
IHttpContextAccessor
인스턴스에 액세스하는 유일한 서비스입니다.public class HttpContextWrapper : IHttpContextWrapper
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextWrapper(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string GetValueFromRequestHeader(string key, string defaultValue)
{
if (_httpContextAccessor.HttpContext.Request.Headers.TryGetValue(key, out StringValues headerValues) && headerValues.Any())
{
return headerValues.First();
}
return defaultValue;
}
}
이러한 방식으로 HttpRequest 빌드에 집중하여
HttpContextWrapper
클래스와 WeatherService
클래스 모두에 대해 더 나은 테스트를 작성할 수 있으므로 복잡한 구조 설정에 대한 걱정 없이 테스트를 작성할 수 있습니다. 값을 검색하기 위해서만.그러나 종속성 수명 범위에 주의하십시오! HTTP 요청 정보는 내부에 있습니다. 무엇을 추측하세요? - 그들의 HTTP 요청. 따라서
Startup
클래스에서 종속성을 정의할 때 IHttpContextWrapper
를 Transient 또는 Scoped로 주입해야 합니다. 차이점이 기억나지 않는다면 제가 도와드리겠습니다here !마무리
이 문서에서는
IHttpContextAccessor
를 사용하여 현재 HTTP 요청에 액세스할 수 있음을 배웠습니다. 물론 예를 들어 HTTP 헤더를 추가하여 응답을 업데이트하는 데 사용할 수도 있습니다.즐거운 코딩하세요!
🐧
Reference
이 문제에 관하여(.NET API에서 HttpContext에 액세스하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bellonedavide/how-to-access-the-httpcontext-in-net-api-k70텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)