2013-05-31 26 views
12

Tôi có một dịch vụ Web.Api trong đó có một phương pháp mà chấp nhận một lớp tùy chỉnh và trả về một lớp tùy chỉnh:Làm thế nào tôi có thể gửi một cookie từ một phương pháp điều khiển Web.Api

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

Bây giờ tôi muốn cũng gửi một cookie trở lại như một phần của phản hồi Http. Làm thế nào tôi có thể làm điều đó?

Trả lời

21

Tôi đã thực hiện điều này bằng cách kết hợp thông tin từ một vài địa điểm khác nhau. Thứ nhất, để dễ dàng có thể gửi các tập tin cookie trong phản ứng, bộ điều khiển Web.Api nên trở về một thể hiện của lớp 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; 
    } 
} 

Nhưng sau đó làm thế nào để đảm bảo rằng tôi có thể dễ dàng CSONG gửi lại CustomResponse?

Bí quyết nằm trong số answer đến số question này. Sử dụng phương thức Request.CreateResponse<T> trên đối tượng yêu cầu. Toàn bộ thỏa thuận sau đó trở thành:

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

Điều đó có vẻ đúng. Nếu bạn đang làm điều này trong rất nhiều phương pháp hành động, bạn có thể đặt nó vào một bộ lọc hành động. –

+1

Tôi đã được tất cả "wow này tuyệt vời này api web" cho đến khi tôi thấy điều này. Thật đáng tiếc, bạn không thể chỉ cần thêm một cookie mà không phải trả lại một HttpResponseMessage. Tôi nghĩ ý tưởng là làm cho Web API dễ dàng hơn WCF. Tôi sợ tôi không thấy điều đó. Làm thế nào một bộ lọc hành động có thể trợ giúp ở đây mà không cần thêm độ phức tạp hơn cho một yêu cầu đơn giản như vậy. Đừng hiểu. – ianbeks

+0

Xin lỗi nếu tôi có thể hỏi, tôi hơi bối rối. Tôi có cần lấy cookie phản hồi trong ứng dụng khách và đặt nó hay trình duyệt nhận tiêu đề phản hồi cookie đã đặt tự động thực hiện việc này không? –

1

Dựa trên this post, WebApi getting headers and querystring and cookie valuesthis post, api net mvc cookie implementation, tôi sử dụng mã sau đây để có được và cài đặt cookie dưới asp.net web api. Nó hoạt động khi máy chủ trên IIS Express, nó sẽ hoạt động khi máy chủ là IIS. Nhưng tôi không biết nó hoạt động hay không cho tự lưu trữ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); 
     } 
    } 
} 
0

Đã xảy ra sự cố này. Tôi đã tuyên bố cùng một phương thức trên hai bộ điều khiển là công khai có cùng tên gây ra xung đột.

Những phương pháp này không được coi là phương pháp web. Vì vậy, tôi vui mừng điều này đã xảy ra nhặt một lỗi khác.

Các vấn đề liên quan