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:
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:
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With