如何从Web.Api控制器方法发送cookie

时间:2013-05-31 09:43:10

标签: c# cookies asp.net-web-api

我有一个Web.Api服务,它有一个接受自定义类并返回另一个自定义类的方法:

public class TestController : ApiController
{
    public CustomResponse Post([FromBody]CustomRequest request)
    {
        // process request
        ...
        // create response
        CustomResponse resp = new CustomResponse() { ... };
        return resp;
    }
}

现在我想在Http响应中发回一个cookie。我怎么能这样做?

4 个答案:

答案 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

诀窍在answerquestion。在请求对象上使用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 valuesthis 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,asyncIHttpActionResult,我们现在可以轻松地做到这一点:

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方法。所以我很高兴发生了另一个错误。