현재 웹 API 서비스에 다음과 같이 ‘SendAsync’를 재정의하는 메시지 핸들러가 있습니다.
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//implementation
}
이 코드 내에서라는 사용자 정의 추가 요청 헤더 값을 검사해야합니다 MyCustomID
. 문제는 내가 다음을 할 때입니다.
if (request.Headers.Contains("MyCustomID")) //OK
var id = request.Headers["MyCustomID"]; //build error - not OK
… 다음과 같은 오류 메시지가 나타납니다.
‘System.Net.Http.Headers.HttpRequestHeaders’유형의 표현식에 []를 사용하여 인덱싱을 적용 할 수 없습니다.
이 재정의 된 메서드에 전달 된 ( MSDN Documentation ) 인스턴스 를 통해 단일 사용자 지정 요청 헤더에 액세스하려면 어떻게 해야합니까?HttpRequestMessage
답변
다음과 같이 해보십시오 :
IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID");
var id = headerValues.FirstOrDefault();
헤더에 대한 액세스 권한이 항상 보장되지 않는 경우 사용할 수있는 헤더에 TryGetValues 메소드도 있습니다.
답변
throws exception
키가없는 경우 아래 줄 입니다.
IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID");
해결 방법 :
System.Linq 포함;
IEnumerable<string> headerValues;
var userId = string.Empty;
if (request.Headers.TryGetValues("MyCustomID", out headerValues))
{
userId = headerValues.FirstOrDefault();
}
답변
Youssef의 답변을 확장하기 위해 단위 테스트 중에이 상황이 발생했기 때문에 헤더가 존재하지 않는 Drew의 우려 사항을 기반 으로이 방법을 작성했습니다.
private T GetFirstHeaderValueOrDefault<T>(string headerKey,
Func<HttpRequestMessage, string> defaultValue,
Func<string,T> valueTransform)
{
IEnumerable<string> headerValues;
HttpRequestMessage message = Request ?? new HttpRequestMessage();
if (!message.Headers.TryGetValues(headerKey, out headerValues))
return valueTransform(defaultValue(message));
string firstHeaderValue = headerValues.FirstOrDefault() ?? defaultValue(message);
return valueTransform(firstHeaderValue);
}
사용법 예는 다음과 같습니다.
GetFirstHeaderValueOrDefault("X-MyGuid", h => Guid.NewGuid().ToString(), Guid.Parse);
또한 더 일반적인 솔루션에 대한 @ doguhan-uluca의 답변을 살펴보십시오.
답변
HttpRequestMessage에서 여러 키 값에 액세스해야 할 때마다 ‘ 개별 HTTP 헤더 값을 리턴합니다 ‘라는 새 메소드를 작성하고 키 값으로이 메소드를 호출하십시오.
public static string GetHeader(this HttpRequestMessage request, string key)
{
IEnumerable<string> keys = null;
if (!request.Headers.TryGetValues(key, out keys))
return null;
return keys.First();
}
답변
@neontapir의 솔루션을 더욱 확장하기 위해 HttpRequestMessage 또는 HttpResponseMessage에 동일하게 적용 할 수 있고 손으로 코딩 된 표현식 또는 함수가 필요하지 않은보다 일반적인 솔루션이 있습니다.
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
public static class HttpResponseMessageExtensions
{
public static T GetFirstHeaderValueOrDefault<T>(
this HttpResponseMessage response,
string headerKey)
{
var toReturn = default(T);
IEnumerable<string> headerValues;
if (response.Content.Headers.TryGetValues(headerKey, out headerValues))
{
var valueString = headerValues.FirstOrDefault();
if (valueString != null)
{
return (T)Convert.ChangeType(valueString, typeof(T));
}
}
return toReturn;
}
}
샘플 사용법 :
var myValue = response.GetFirstHeaderValueOrDefault<int>("MyValue");
답변
ASP.Net Core의 경우 컨트롤러 메소드에서 직접 매개 변수를 사용하려는 경우 쉬운 솔루션이 있습니다. [FromHeader] 주석을 사용하십시오.
public JsonResult SendAsync([FromHeader] string myParam)
{
if(myParam == null) //Param not set in request header
{
return null;
}
return doSomething();
}
추가 정보 : 필자의 경우 “myParam”은 문자열이어야했고 int는 항상 0이었습니다.
답변
ASP.NET의 경우이 간단한 라이브러리 / 패키지를 사용하여 컨트롤러 메서드의 매개 변수에서 직접 헤더를 가져올 수 있습니다 . [FromHeader]
ASP.NET Core에서와 마찬가지로 속성을 제공합니다 . 🙂 예를 들면 다음과 같습니다.
...
using RazHeaderAttribute.Attributes;
[Route("api/{controller}")]
public class RandomController : ApiController
{
...
// GET api/random
[HttpGet]
public IEnumerable<string> Get([FromHeader("pages")] int page, [FromHeader] string rows)
{
// Print in the debug window to be sure our bound stuff are passed :)
Debug.WriteLine($"Rows {rows}, Page {page}");
...
}
}