Online courses in ASP.NET MVC / Core, jQuery, Angular, and Design Patterns conducted by Bipin Joshi. Read more...
Learn ASP.NET MVC / Core, jQuery, Angular, and Design Patterns through our online training programs. Courses conducted by Bipin Joshi on weekends. Read more details here.

Multiple Instances of Partial Pa

Working with Cookies in Web API and HttpClient

ASP.NET applications often use cookies to store user specific pieces of information. Not just web forms and MVC applications, Web API too can use cookies. Sometimes developers device an authentication scheme revolving around cookie as an authentication ticket. Although this article won't show you how to develop such a scheme, it illustrates how cookies can be issued and used in Web API. Specifically you will learn:

  • How to set cookies from a Web API controller and read those cookies in a client application.
  • How to set cookies from a client application (HttpClient) and read those cookies in a Web API controller.

Setting cookie from Web API controller and reading it in the client

To work through the code shown in this section create a new Web API project and write a Get() method as shown below:

public HttpResponseMessage Get()
{
    CookieHeaderValue serverCookie = new CookieHeaderValue
                                   ("server_cookie", "hello from server");
    serverCookie.Expires = DateTimeOffset.Now.AddDays(2);
    serverCookie.Domain = Request.RequestUri.Host;
    serverCookie.Path = "/";
            
    HttpResponseMessage response = Request.CreateResponse
                                 ("This is response from the Web API.");

    response.Headers.AddCookies(new CookieHeaderValue[] { serverCookie });
    return response;
}

The above code shows Get() method that handles GET requests. The method returns HttpResponseMessage. Inside, the code creates an instance of CookieHeaderValue class. This class represents a cookie header that goes as a part of HTTP headers. The constructor of the CookieHeaderValue class accepts a cookie name (server_cookie in this case) and its value (hello from server - in this case). The code then sets Expires, Domain and Path properties of the cookie. The Expires property sets the expiration date and time for the cookie (2 days from now in this case). The Domain property is set to the Hose of the request and the Path property is set to the root ("/").

Then the code creates a instance of HttpResponseMessage class using the CreateResponse() method of the Request object. The CreateResponse() method accepts the response data (a string message in this case) and returns it wrapped in a HttpResponseMessage.

The CookieHeaderValue object created earlier is then added to the Headers collection of the HttpResponseMessage. This is done using the AddCookies() method and then passing an array of CookieHeaderValue objects. In this case we are issuing just one cookie and hence the array contains just a single element.

Finally, the HttpResponseMessage is returned to the caller.

Now, let's see how this cookie can be read in the client code. It is assumed that the client application is a separate ASP.NET MVC application and uses HttpClient to invoke the Web API. The client code to read the cookie is shown below:

public ActionResult Index()
{
    WebRequestHandler handler = new WebRequestHandler();
    handler.CookieContainer = new System.Net.CookieContainer();
    handler.UseCookies = true;
    handler.UseDefaultCredentials = true;

    HttpClient client = new HttpClient(handler);
    client.BaseAddress = new Uri("http://localhost:49308/");
    HttpResponseMessage response = client.GetAsync("/api/mywebapi").Result;
    string data = response.Content.ReadAsAsync<string>().Result;

    int count = handler.CookieContainer.Count;
    Cookie serverCookie = handler.CookieContainer.
                          GetCookies(new Uri("http://localhost:49308/"))
                          ["server_cookie"];

    ViewBag.CookieCount = count;
    ViewBag.ServerResponse = data;
    ViewBag.ServerCookieValue = Server.UrlDecode(serverCookie.Value);

    return View();
}

The Index() action method shown above creates an instance of WebRequestHandler class. This class is required because it wraps a CookieContainer object that stores the cookies during the communication. The CookieContainer object is instantiated to a new instance of the CookieContainer. The UseCookies and UseDefaultCredentials properties of the WebRequestHandler are set to true.

Then an instance of HttpClient is created by passing the WebRequestHandler object in its constructor. This way the HttpClient object uses the handler object to store cookies. The BaseAddress property of the HttpClient is set to the base address of the Web API. Make sure to change this address to reflect your development environment.

Then GetAsync() method of HttpClient is used to invoke the Get() Web API method. Note that the above code assumes that the Web API controller is MyWebAPI. Change the Web API name to match your environment. To read the response sent by the Web API ReadAsAsync() method is used. In this case the response will be a string - This is response from the Web API (refer the Web API earlier).

To access the cookie issued by the Web API controller the CookieContainer object of the WebRequestHandler is used. The Count property of the CookieContainer returns the number of cookies present in the container. The GetCookies() method is used to retrieve the server_cookie from the container. The cookie is returned as Cookie object. The Value property of the Cookie object returns the value of the cookie. In this case the value will be - hello from server (see Web API code earlier).

The cookie count, response data and the cookie value are sent to the View through the respective ViewBag properties. If you output these ViewBag properties on the Index view you should get the values as expected. 

Setting Cookie through HttpClient and reading it in the Web API

In the preceding example the cookie was set in the Web API and was read in the client application. In this section we will do the opposite - we will set a cookie from the client application and read it in the Web API.

The following code shows the client side code in the form of an action method (recollect that our client is an MVC application).

public ActionResult Index()
{
    WebRequestHandler handler = new WebRequestHandler();
    handler.CookieContainer = new System.Net.CookieContainer();
    handler.UseCookies = true;
    handler.UseDefaultCredentials = true;

    Cookie clientCookie = new Cookie("client_cookie", "hello from client");
    clientCookie.Expires = DateTime.Now.AddDays(2);
    clientCookie.Domain = Request.Url.Host;
    clientCookie.Path = "/";
    handler.CookieContainer.Add(clientCookie);

    HttpClient client = new HttpClient(handler);
    client.BaseAddress = new Uri("http://localhost:49308/");
    HttpResponseMessage response = client.GetAsync("/api/mywebapi").Result;
    string data = response.Content.ReadAsAsync<string>().Result;

    ViewBag.ServerResponse = data;

    return View();
}

Notice the code marked in bold letters. This code creates a Cookie instace named client_cookie and sets its value to - hello from client. The Expires, Domain and Path properties of the cookie are set as before. This Cookie is then added to the CookieContainer object. Finally, Web API is invoked using a GET request. The response from the Web API is stored in a ViewBag property and outputted on the view.

The Web API Get() method in this case is modified as follows:

public HttpResponseMessage GetCustomers()
{
    CookieHeaderValue clientCookie = Request.Headers.GetCookies
                                   ("client_cookie").SingleOrDefault();
    string clientCookieValue = clientCookie["client_cookie"].Value;
            
    HttpResponseMessage response = Request.CreateResponse
                                 ("Client cookie said - " + clientCookieValue);

    return response;
}

Notice the code shown in bold letters. The cookie issued from the client side is retrieved using the GetCookies() method of the Headers collection. The cookie is returned as CookieHeaderValue. The value of the cookie can then be read using the Value property. Just to conform that the value is retrieved successfully the same value is appended to the response message.

If you wish to access the same cookie across multiple Web API calls (and in most cases you would need this) you must preserve the WebRequestHandler instance somewhere (such as a Session variable). This way you can use the same CookieContainer across multiple Web API calls.

That's it! Run the sample code shown above and test both the scenarios.




Bipin Joshi is a software consultant, trainer, author and a yogi having 21+ years of experience in software development. He conducts online courses in ASP.NET MVC / Core, jQuery, AngularJS, and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also teaches Ajapa Meditation to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 10 Jun 2014



Tags : ASP.NET MVC C#