Как я могу отправить cookie с помощью метода контроллера Web.Api
У меня есть служба Web.Api, которая имеет метод, который принимает пользовательский класс и возвращает другой пользовательский класс:
public class TestController : ApiController
{
public CustomResponse Post([FromBody]CustomRequest request)
{
// process request
...
// create response
CustomResponse resp = new CustomResponse() { ... };
return resp;
}
}
Теперь я хочу также отправить cookie обратно как часть ответа Http. Как я могу это сделать?
Ответы
Ответ 1
Мне удалось это сделать, объединив информацию из нескольких разных мест. Во-первых, чтобы легко отправлять куки в ответ, контроллер 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
?
Трюк находится в ответе этому вопросу . Используйте метод 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;
}
}
Ответ 2
Основываясь на этот пост, WebApi получает заголовки и строки и значения cookie и этот пост, api net mvc cookie, я использую следующие коды для получения и установки файлов cookie в asp.net web api
. Он работает, когда сервер находится в IIS Express, он должен работать, когда сервер IIS
тоже. Но я не знаю, как это работает или нет для self-host 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 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);
}
}
}
Ответ 3
Была эта проблема. Я объявил тот же метод на двух контроллерах, что и общедоступный с тем же именем, что и конфликт.
Эти методы не должны быть веб-методами. Поэтому я рад, что это произошло, и у вас появилась еще одна ошибка.