I have a login page that goes off to the server gets a bunch of data, then I want to take some of that data and save it into a cookie using Blazor on the client.
So To start I have successfully injected IHttpContextAccessor. and for now in my Blazor function I have:
httpContextAccessor.HttpContext.Response.Cookies.Append("test", "ddd");
in debug when I hit the above line of code it errors with:
"Headers are read-only, response has already started."
Of course I will not be saving "test" with "ddd" in the cookie, I'm just trying to get a cookie to save at the moment.
The Blazor web framework allows Razor components to be hosted in different ways. They can run server-side in ASP.NET Core (Blazor Server) and client-side in the browser on a WebAssembly-based . NET runtime (Blazor WebAssembly or Blazor WASM).
You can use this way without any script:
First define this service:
using Microsoft.JSInterop;
namespace MyProject.Utils
{
public interface ICookie
{
public Task SetValue(string key, string value, int? days = null);
public Task<string> GetValue(string key, string def = "");
}
public class Cookie : ICookie
{
readonly IJSRuntime JSRuntime;
string expires = "";
public Cookie(IJSRuntime jsRuntime)
{
JSRuntime = jsRuntime;
ExpireDays = 300;
}
public async Task SetValue(string key, string value, int? days = null)
{
var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : expires;
await SetCookie($"{key}={value}; expires={curExp}; path=/");
}
public async Task<string> GetValue(string key, string def = "")
{
var cValue = await GetCookie();
if (string.IsNullOrEmpty(cValue)) return def;
var vals = cValue.Split(';');
foreach (var val in vals)
if(!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
if(val.Substring(1, val.IndexOf('=') - 1).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
return val.Substring(val.IndexOf('=') + 1);
return def;
}
private async Task SetCookie(string value)
{
await JSRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\"");
}
private async Task<string> GetCookie()
{
return await JSRuntime.InvokeAsync<string>("eval", $"document.cookie");
}
public int ExpireDays
{
set => expires = DateToUTC(value);
}
private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
}
}
You can set default expire by ExpireDays
, and in SetValue()
set null
to days
for use default or set to 0
for session or number of days.
Then import to _import.razor
and add to service in Program.cs
:
builder.Services.AddScoped<ICookie, Cookie>();
For use:
@inject ICookie cookie
...
await cookie.SetValue("mytest20", "Hello Mohsen!");
_message = await cookie.GetValue("mytest20");
Enjoy it.
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