J'ai un service Web.Api qui a une méthode qui accepte une classe personnalisée et retourne une autre classe personnalisée:
public class TestController : ApiController
{
public CustomResponse Post([FromBody]CustomRequest request)
{
// process request
...
// create response
CustomResponse resp = new CustomResponse() { ... };
return resp;
}
}
Maintenant, je souhaite également renvoyer un cookie dans le cadre de la réponse Http. Comment puis je faire ça?
J'ai réussi à faire cela en combinant des informations provenant de plusieurs endroits différents. Premièrement, pour pouvoir envoyer facilement des cookies dans la réponse, le contrôleur Web.Api doit renvoyer une instance de la classe 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;
}
}
Mais alors, comment puis-je m'assurer que je peux facilement AUSSI renvoyer la CustomResponse
?
Le truc est dans la réponse à cette question . Utilisez la méthode Request.CreateResponse<T>
sur l'objet de requête. L'ensemble devient alors:
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;
}
}
Avec les versions récentes de l'API Web, async
et IHttpActionResult
, nous pouvons maintenant le faire simplement:
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);
}
Basé sur ce post, WebApi obtenant des en-têtes, des chaînes de requête et des valeurs de cookie et ce post, api net mvc cookie implementation , j’utilise les codes suivants pour obtenir et définir les cookies sous asp.net web api
. Cela fonctionne lorsque le serveur est sur IIS Express, il devrait fonctionner également lorsque le serveur est à IIS
. Mais je ne sais pas si cela fonctionne ou non pour 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'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);
}
}
}