C# 如何在 Web API 消息处理程序中提取自定义标头值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14967457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract custom header value in Web API message handler?
提问by atconway
I currently have a message handler in my Web API service that overrides 'SendAsync' as follows:
我目前在我的 Web API 服务中有一个消息处理程序,它覆盖“SendAsync”,如下所示:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//implementation
}
Within this code I need to inspect a custom added request header value named MyCustomID
. The problem is when I do the following:
在这段代码中,我需要检查一个名为MyCustomID
. 问题是当我执行以下操作时:
if (request.Headers.Contains("MyCustomID")) //OK
var id = request.Headers["MyCustomID"]; //build error - not OK
...I get the following error message:
...我收到以下错误消息:
Cannot apply indexing with [] to an expression of type 'System.Net.Http.Headers.HttpRequestHeaders'
无法将 [] 索引应用于“System.Net.Http.Headers.HttpRequestHeaders”类型的表达式
How can I access a singlecustom request header via the HttpRequestMessage
(MSDN Documentation) instance passed into this overridden method?
如何通过传递给此重写方法的(MSDN 文档)实例访问单个自定义请求标头?HttpRequestMessage
采纳答案by Youssef Moussaoui
Try something like this:
尝试这样的事情:
IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID");
var id = headerValues.FirstOrDefault();
There's also a TryGetValues method on Headers you can use if you're not always guaranteed to have access to the header.
如果您不能总是保证可以访问标头,则还可以使用标头上的 TryGetValues 方法。
回答by neontapir
To expand on Youssef's answer, I wrote this method based Drew's concerns about the header not existing, because I ran into this situation during unit testing.
为了扩展 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);
}
Here's an example usage:
这是一个示例用法:
GetFirstHeaderValueOrDefault("X-MyGuid", h => Guid.NewGuid().ToString(), Guid.Parse);
Also have a look at @doguhan-uluca 's answer for a more general solution.
另请查看@doguhan-uluca 的答案以获得更通用的解决方案。
回答by SharpCoder
The line below throws exception
if the key does not exists.
throws exception
如果密钥不存在,则为下面的行。
IEnumerable<string> headerValues = request.Headers.GetValues("MyCustomID");
Work around :
解决:
Include System.Linq;
包括 System.Linq;
IEnumerable<string> headerValues;
var userId = string.Empty;
if (request.Headers.TryGetValues("MyCustomID", out headerValues))
{
userId = headerValues.FirstOrDefault();
}
回答by Doguhan Uluca
To further expand on @neontapir's solution, here's a more generic solution that can apply to HttpRequestMessage or HttpResponseMessage equally and doesn't require hand coded expressions or functions.
为了进一步扩展@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;
}
}
Sample usage:
示例用法:
var myValue = response.GetFirstHeaderValueOrDefault<int>("MyValue");
回答by SRI
Create a new method - 'Returns an individual HTTP Header value' and call this method with key value everytime when you need to access multiple key Values from HttpRequestMessage.
创建一个新方法 - '返回一个单独的 HTTP 标头值'并在每次需要从 HttpRequestMessage 访问多个键值时使用键值调用此方法。
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();
}
回答by Reiner
For ASP.Net Core there is an easy solution if want to use the param directly in the controller method: Use the [FromHeader] annotation.
对于 ASP.Net Core,如果想直接在控制器方法中使用参数,有一个简单的解决方案:使用 [FromHeader] 注释。
public JsonResult SendAsync([FromHeader] string myParam)
{
if(myParam == null) //Param not set in request header
{
return null;
}
return doSomething();
}
Additional Info: In my case the "myParam" had to be a string, int was always 0.
附加信息:在我的情况下,“myParam”必须是一个字符串,int 始终为 0。
回答by Konstantin Salavatov
request.Headers.FirstOrDefault( x => x.Key == "MyCustomID" ).Value.FirstOrDefault()
modern variant :)
现代变体:)
回答by lawrenceagbani
For ASP.NET you can get the header directly from parameter in controller method using this simple library/package. It provides a [FromHeader]
attribute just like you have in ASP.NET Core :). For example:
对于 ASP.NET,您可以使用这个简单的 library/package直接从控制器方法中的参数获取标头。它提供了一个[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}");
...
}
}
回答by Roman Marusyk
One line solution
一条线解决方案
var id = request.Headers.GetValues("MyCustomID").FirstOrDefault();