EU General Data Protection Regulation (GDPR) support in ASP.NET Core Blazor
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the .NET and .NET Core Support Policy. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
This article explains how to implement support for EU General Data Protection Regulation (GDPR) requirements.
In the Program
file:
- Add CookiePolicyOptions configuration to require user consent for non-essential cookies and set the same-site policy to none. For more information, see Work with SameSite cookies in ASP.NET Core.
- Add the default implementation for the IHttpContextAccessor service by calling AddHttpContextAccessor.
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
builder.Services.AddHttpContextAccessor();
In the Program
file before the call to MapRazorComponents, add Cookie Policy Middleware by calling UseCookiePolicy:
In the Program
file before the call to MapBlazorHub, add Cookie Policy Middleware by calling UseCookiePolicy:
app.UseCookiePolicy();
Add the following CookieConsent
component to handle cookie policy consent.
The component uses a collocated JavaScript file, named CookieConsent.razor.js
, to load a module. Confirm or adjust the path to the collocated file in the OnAfterRenderAsync
method. The following component assumes that the component and its companion JavaScript file are in the Components
folder of the app.
CookieConsent.razor
:
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Http
@implements IAsyncDisposable
@inject IHttpContextAccessor Http
@inject IJSRuntime JS
@if (showBanner)
{
<div id="cookieConsent" class="alert alert-info alert-dismissible fade show"
role="alert">
Use this space to summarize your privacy and cookie use policy.
<a href="/privacy">Privacy Policy</a>
<button type="button" @onclick="AcceptPolicy" class="accept-policy close"
data-bs-dismiss="alert" aria-label="Close"
data-cookie-string="@cookieString">
Accept
</button>
</div>
}
@code {
private IJSObjectReference? module;
private ITrackingConsentFeature? consentFeature;
private bool showBanner;
private string? cookieString;
protected override void OnInitialized()
{
consentFeature = Http.HttpContext?.Features.Get<ITrackingConsentFeature>();
showBanner = !consentFeature?.CanTrack ?? false;
cookieString = consentFeature?.CreateConsentCookie();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/CookieConsent.razor.js");
}
}
private async Task AcceptPolicy()
{
if (module is not null)
{
await module.InvokeVoidAsync("acceptPolicy", cookieString);
showBanner = false;
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
Add the following collocated JavaScript file to maintain the acceptPolicy
function in a JavaScript module.
CookieConsent.razor.js
:
export function acceptPolicy(cookieString) {
document.cookie = cookieString;
}
Within <main>
Razor markup of the MainLayout
component (MainLayout.razor
), add the CookieConsent
component:
<CookieConsent />
Customize the cookie consent value
Specify the cookie consent value by assigning a custom string to CookiePolicyOptions.ConsentCookieValue. The following example changes the default value of "yes
" to "true
":
options.ConsentCookieValue = "true";
In Blazor WebAssembly apps, local storage is a convenient approach for maintaining a user's acceptance of a site's cookie policy. The following approach demonstrates the approach.
If the app doesn't already have a Shared
folder for shared components, add a Shared
folder to the app.
Add the namespace for shared components to the _Imports.razor
file. In the following example, the app's namespace is BlazorSample
, and the shared folder's namespace is BlazorSample.Shared
:
@using BlazorSample.Shared
Add the following CookieConsent
component to handle cookie policy consent.
Shared/CookieConsent.razor
:
@implements IAsyncDisposable
@inject IJSRuntime JS
@if (showBanner)
{
<div id="cookieConsent" class="alert alert-info alert-dismissible fade show"
role="alert">
Use this space to summarize your privacy and cookie use policy.
<a href="/privacy">Privacy Policy</a>
<button type="button" @onclick="AcceptPolicy" class="accept-policy close"
data-bs-dismiss="alert" aria-label="Close">
<span aria-hidden="true">Accept</span>
</button>
</div>
}
@code {
private IJSObjectReference? module;
private bool showBanner = false;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Shared/CookieConsent.razor.js");
showBanner = !await module.InvokeAsync<bool>("getCookiePolicyAccepted");
StateHasChanged();
}
}
private async Task AcceptPolicy()
{
if (module is not null)
{
await module.InvokeVoidAsync("setCookiePolicyAccepted");
showBanner = false;
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
Add the following collocated JavaScript file to maintain the setCookiePolicyAccepted
and getCookiePolicyAccepted
functions in a JavaScript module.
Shared/CookieConsent.razor.js
:
export function getCookiePolicyAccepted() {
const cookiePolicy = localStorage.getItem('CookiePolicyAccepted');
return cookiePolicy === 'yes' ? true : false;
}
export function setCookiePolicyAccepted() {
localStorage.setItem('CookiePolicyAccepted', 'yes');
}
In the preceding example, you can change the name of the local storage item and value from "CookiePolicyAccepted
" and "yes
" to any preferred values. If you change one or both values, update both functions.
Within <main>
Razor markup of the MainLayout
component (Layout/MainLayout.razor
), add the CookieConsent
component:
<CookieConsent />
Additional resources
ASP.NET Core