C# 如何从 Web.Api 控制器方法发送 cookie
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16854376/
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 can I send a cookie from a Web.Api controller method
提问by user1429080
I have a Web.Api service which has a method that accepts a custom class and returns another custom class:
我有一个 Web.Api 服务,它有一个接受自定义类并返回另一个自定义类的方法:
public class TestController : ApiController
{
public CustomResponse Post([FromBody]CustomRequest request)
{
// process request
...
// create response
CustomResponse resp = new CustomResponse() { ... };
return resp;
}
}
Now I want to also send a cookie back as part of the Http response. How can I do that?
现在我还想将 cookie 作为 Http 响应的一部分发回。我怎样才能做到这一点?
回答by user1429080
I managed to do this by combining information from a few different locations. First, in order to easily be able to send cookies in the response, the Web.Api controller should return an instance of the System.Net.Http.HttpResponseMessageclass (link):
我通过结合来自几个不同位置的信息设法做到了这一点。首先,为了能够轻松地在响应中发送 cookie,Web.Api 控制器应该返回一个System.Net.Http.HttpResponseMessage类的实例(链接):
public class TestController : ApiController
{
public HttpResponseMessage Post([FromBody]CustomRequest request)
{
var resp = new HttpResponseMessage();
...
//create and set cookie in response
var cookie = new CookieHeaderValue("customCookie", "cookieVal");
cookie.Expires = DateTimeOffset.Now.AddDays(1);
cookie.Domain = Request.RequestUri.Host;
cookie.Path = "/";
resp.Headers.AddCookies(new CookieHeaderValue[] { cookie });
return resp;
}
}
But then how do I make sure that I can easily ALSO send back the CustomResponse?
但是,我如何确保我也可以轻松地将CustomResponse.
The trick is in the answerto this question. Use the Request.CreateResponse<T>method on the request object. The whole deal then becomes:
诀窍在于这个问题的答案。在请求对象上使用该方法。整个交易就变成了:Request.CreateResponse<T>
public class TestController : ApiController
{
public HttpResponseMessage Post([FromBody]CustomRequest request)
{
// process request
...
var resp = Request.CreateResponse<CustomResponse>(
HttpStatusCode.OK,
new CustomResponse() { ... }
);
//create and set cookie in response
var cookie = new CookieHeaderValue("customCookie", "cookieVal");
cookie.Expires = DateTimeOffset.Now.AddDays(1);
cookie.Domain = Request.RequestUri.Host;
cookie.Path = "/";
resp.Headers.AddCookies(new CookieHeaderValue[] { cookie });
return resp;
}
}
回答by AechoLiu
Based on this post, WebApi getting headers and querystring and cookie valuesand this post, api net mvc cookie implementation, I use following codes to get and set cookies under asp.net web api. It works when the server is on IIS Express, it should work when the server is IIStoo. But I don't know it works or not for self-hostweb-api.
基于这篇文章,WebApi 获取标题和查询字符串和 cookie 值以及这篇文章,api net mvc cookie 实现,我使用以下代码在asp.net web api. 当服务器在 IIS Express 上时它可以工作,当服务器也是IIS如此时它也应该工作。但我不知道它是否适用于self-hostweb-api。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
namespace System.Web.Http
{
/// <summary>
/// Extends the HttpRequestMessage collection
/// </summary>
public static class HttpRequestMessageExtensions
{
/// <summary>
/// Returns a dictionary of QueryStrings that's easier to work with
/// than GetQueryNameValuePairs KevValuePairs collection.
///
/// If you need to pull a few single values use GetQueryString instead.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static Dictionary<string, string> GetQueryStrings(this HttpRequestMessage request)
{
return request.GetQueryNameValuePairs()
.ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Returns an individual querystring value
/// </summary>
/// <param name="request"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string GetQueryString(this HttpRequestMessage request, string key)
{
// IEnumerable<KeyValuePair<string,string>> - right!
var queryStrings = request.GetQueryNameValuePairs();
if (queryStrings == null)
return null;
var match = queryStrings.FirstOrDefault(kv => string.Compare(kv.Key, key, true) == 0);
if (string.IsNullOrEmpty(match.Value))
return null;
return match.Value;
}
/// <summary>
/// Returns an individual HTTP Header value
/// </summary>
/// <param name="request"></param>
/// <param name="key"></param>
/// <returns></returns>
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();
}
/// <summary>
/// Retrieves an individual cookie from the cookies collection
/// </summary>
/// <param name="request"></param>
/// <param name="cookieName"></param>
/// <returns></returns>
public static string GetCookie(this HttpRequestMessage request, string cookieName)
{
CookieHeaderValue cookie = request.Headers.GetCookies(cookieName).FirstOrDefault();
if (cookie != null)
return cookie[cookieName].Value;
return null;
}
public static void SetCookie(this ApiController controller, string cookieName, string cookieValue)
{
HttpCookie cookie = new HttpCookie(cookieName, cookieValue);
HttpContext.Current.Response.Cookies.Add(cookie);
}
}
}
回答by Simon Mourier
With recent versions of Web API, async, and IHttpActionResult, we can now simply do this:
使用最新版本的 Web API、async、 和IHttpActionResult,我们现在可以简单地执行以下操作:
public async Task<IHttpActionResult> MyMethod(... myParameters ...)
{
...
var cookie = new CookieHeaderValue("myCookie", "myValue");
...
var resp = new HttpResponseMessage();
resp.StatusCode = HttpStatusCode.OK;
resp.Headers.AddCookies(new[] { cookie });
return ResponseMessage(resp);
}

