Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check for a response cookie in Asp.net Core MVC (aka Asp.Net 5 RC1)?

I'm converting a web forms application to asp.net core mvc. In my web forms application sometimes after I set some response cookies other code needs to see if they were set, and if so, access the cookie's properties (i.e. value, Expires, Secure, http). In webforms and MVC 5 it's possible to iterate over the cookies and return any particular cookies like so (old school I know)

       for(int i = 0; i < cookies.Count; i++) {
            if(cookies[i].Name == cookieName) {
                return cookies[i];
            }
        }

But the interface for accessing response cookies in asp.net core mvc looks like this:

response cookies interface

Based on this interface I don't see a way to check to see if a response cookie exists and obtain it's properties. But there has gotta be some way to do it?

In an action method I tried setting two cookies on the response object and then immediately trying to access them. But intellisense doesn't show any methods, properties or indexers that would allow me to access them:

enter image description here

For a moment, I thought that perhaps I could use Response.Cookies.ToString(); and just parse the information to find my cookie info, but alas, the ToString() call returns "Microsoft.AspNet.Http.Internal.ResponseCookies" because the object doesn't override the default implementation.

Just for fun I also checked the current dev branch of GitHub to see if the interface has changed since RC1 but it has not. So given this interface, how do I check for the existence of a response cookie and get it's properties? I've thought about trying to hack in via the response headers collection but that seems pretty lame.

like image 649
RonC Avatar asked Apr 27 '16 20:04

RonC


1 Answers

There is an extension method available in Microsoft.AspNetCore.Http.Extensions called GetTypedHeaders(). This can be called on HttpContext.Response to read Set-Cookie headers. For example in middleware perhaps we want to intercept a Set-Cookie response header and replace it:

  public async Task Invoke(HttpContext httpContext)
        {
            httpContext.Response.OnStarting(state =>
            {
                var context = (HttpContext)state;

                var setCookieHeaders = context.Response.GetTypedHeaders().SetCookie;

                // We assume only one cookie is found. You could loop over multiple matches instead.
                // setCookieHeaders may be null if response doesn't contain set-cookie headers
                var cookie = setCookieHeaders?.FirstOrDefault(x => x.Name == "mycookiename");

                if (cookie == null)
                {
                    return Task.CompletedTask;
                }

                var opts = new CookieOptions
                {
                    HttpOnly = true,
                    Expires = DateTimeOffset.Now.AddHours(12),
                    SameSite = SameSiteMode.Lax,
                    Secure = true
                };

                context.Response.Cookies.Delete(cookie.Name.Value);
                context.Response.Cookies.Append(cookie.Name.Value, "mynewcookievalue", opts);
                
                return Task.CompletedTask;

            }, httpContext);

            await _next(httpContext);
        }
like image 177
Simon B Avatar answered Nov 01 '22 07:11

Simon B