ehd*_*hdv 41 c# asp.net asp.net-web-api
在ASP.NET Web API 2中,它IHttpActionResult
在简化控制器代码方面提供了很多价值,我不愿意停止使用它,但我遇到了问题.
我需要在传出响应上设置一个ETag,我找不到任何可以访问响应头的属性.目前我正在使用Ok<T>(T content)
来自的helper方法ApiController
,它返回一个OkNegotiatedContentResult<T>
对象.这似乎没有暴露任何可以让我修改标题的东西.
我错过了什么,或者在使用股票IHttpActionResult
类型时是否真的没有办法做到这一点?我考虑过一个消息处理程序,但后来我必须弄清楚如何将ETag从动作中传出(对于不同的动作,ETag的生成方式不同,所以这不是为所有动作制作通用处理程序的问题).
我想避免使用原始的HttpResponseMessage,但此刻看起来很难.
Kir*_*lla 34
对于您的方案,您需要创建自定义IHttpActionResult
.以下是我OkNegotiatedContentResult<T>
在运行时派生Content-Negotiation
并设置Ok
状态代码的示例.
public class CustomOkResult<T> : OkNegotiatedContentResult<T>
{
public CustomOkResult(T content, ApiController controller)
: base(content, controller) { }
public CustomOkResult(T content, IContentNegotiator contentNegotiator, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
: base(content, contentNegotiator, request, formatters) { }
public string ETagValue { get; set; }
public override async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = await base.ExecuteAsync(cancellationToken);
response.Headers.ETag = new EntityTagHeaderValue(this.ETagValue);
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public class ValuesController : ApiController
{
public IHttpActionResult Get()
{
return new CustomOkResult<string>(content: "Hello World!", controller: this)
{
ETagValue = "You ETag value"
};
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您也可以从中派生NegotiatedContentResult<T>
,在这种情况下,您需要自己提供StatusCode.希望这可以帮助.
你可以找到的源代码OkNegotiatedContentResult<T>
和NegotiatedContentResult<T>
,正如你可以想像是简单的实际.
小智 29
您可以HttpResponseMessage
根据需要创建,添加标头,然后ResponseMessageResult
从中创建:
HttpResponseMessage response =new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add("MyHeader", "MyHeaderValue");
return ResponseMessage(response);
Run Code Online (Sandbox Code Playgroud)
这是我没有ActionFilterAttributes的简单实现,类似于AlexACD的响应.我的解决方案使用ResponseMessageResult来实现IHttpActionResult接口.
HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
responseMessage.Headers.Add("Headername", "Value");
ResponseMessageResult response = new ResponseMessageResult(responseMessage);
return response;
Run Code Online (Sandbox Code Playgroud)
public static class HttpExtentions
{
public static IHttpActionResult AddHeader(this IHttpActionResult action,
string headerName, IEnumerable<string> headerValues)
{
return new HeaderActionResult(action, headerName, headerValues);
}
public static IHttpActionResult AddHeader(this IHttpActionResult action,
string headerName, string header)
{
return AddHeader(action, headerName, new[] {header});
}
private class HeaderActionResult : IHttpActionResult
{
private readonly IHttpActionResult action;
private readonly Tuple<string, IEnumerable<string>> header;
public HeaderActionResult(IHttpActionResult action, string headerName,
IEnumerable<string> headerValues)
{
this.action = action;
header = Tuple.Create(headerName, headerValues);
}
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = await action.ExecuteAsync(cancellationToken);
response.Headers.Add(header.Item1, header.Item2);
return response;
}
}
}
Run Code Online (Sandbox Code Playgroud)
很老的问题。当时其他答案可能是有意义的,但今天您可以简单地添加这一行,而无需更改或扩展IHttpActionResult
。它完美地在您的响应中添加标头。还要确保格式化为RFC 1123标准,如下所示。否则,虽然 Last-Modified 出现在标头中,但客户端无法使用HttpClient
.
System.Web.HttpContext.Current.Response.Headers.
Add(Microsoft.Net.Http.Headers.HeaderNames.LastModified, DBdateModified.Value.ToString("r"));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
29453 次 |
最近记录: |