我有一个Web.Api服务,它有一个接受自定义类并返回另一个自定义类的方法:
public class TestController : ApiController
{
public CustomResponse Post([FromBody]CustomRequest request)
{
// process request
...
// create response
CustomResponse resp = new CustomResponse() { ... };
return resp;
}
}
现在我想在Http响应中发回一个cookie。我怎么能这样做?
答案 0 :(得分:28)
我设法通过组合来自几个不同地点的信息来实现这一目标。首先,为了能够轻松地在响应中发送cookie,Web.Api控制器应该返回System.Net.Http.HttpResponseMessage
类(link)的实例:
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;
}
}
但是,我如何确保我可以轻松地发回CustomResponse
?
诀窍在answer到question。在请求对象上使用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;
}
}
答案 1 :(得分:0)
根据this post, WebApi getting headers and querystring and cookie values和this post, api net mvc cookie implementation,我使用以下代码来获取和设置asp.net web api
下的Cookie。当服务器在IIS Express上时它可以工作,当服务器也是IIS
时它应该工作。但我不知道自我主持人 web-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);
}
}
}
答案 2 :(得分:0)
使用最新版本的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);
}
答案 3 :(得分:-2)
有这个问题。我在两个控制器上声明了相同的方法,使用相同的名称导致冲突。
这些方法不应该是web方法。所以我很高兴发生了另一个错误。