refactor add culture midleware

This commit is contained in:
tekh 2025-08-22 22:26:23 +02:00
parent 3394a580f4
commit 6778d8e3e7
4 changed files with 81 additions and 82 deletions

View File

@ -1,27 +1,25 @@
using EnvelopeGenerator.Web.Services; using DigitalData.Core.Abstraction.Application.DTO;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using DigitalData.Core.API; using DigitalData.Core.API;
using EnvelopeGenerator.Extensions;
using Microsoft.Extensions.Localization;
using Microsoft.AspNetCore.Localization;
using EnvelopeGenerator.Web.Models;
using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using Ganss.Xss;
using Newtonsoft.Json;
using EnvelopeGenerator.Application.Dto;
using DigitalData.Core.Client; using DigitalData.Core.Client;
using OtpNet; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Application.Interfaces.Services; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using static EnvelopeGenerator.Domain.Constants;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using EnvelopeGenerator.Application.Interfaces.Services;
using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Extensions;
using EnvelopeGenerator.Web.Models;
using Ganss.Xss;
using MediatR;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using OtpNet;
using System.Security.Claims;
using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Web.Controllers; namespace EnvelopeGenerator.Web.Controllers;
@ -58,17 +56,8 @@ public class HomeController : ViewControllerBase
} }
[HttpGet("/")] [HttpGet("/")]
public IActionResult Main([FromQuery] string? culture = null) public IActionResult Main()
{ {
//TODO: add a middelware or use an asp.net functionality insead of this code-smell
culture = culture is not null ? _sanitizer.Sanitize(culture) : null;
if (UserLanguage is null && culture is null)
{
UserLanguage = _cultures.Default.Language;
return Redirect($"{Request.Headers["Referer"]}?culture={_cultures.Default.Language}");
}
ViewData["UserCulture"] = _cultures[UserLanguage]; ViewData["UserCulture"] = _cultures[UserLanguage];
return View(new MainViewModel() return View(new MainViewModel()
@ -79,20 +68,10 @@ public class HomeController : ViewControllerBase
[HttpGet("EnvelopeKey/{envelopeReceiverId}")] [HttpGet("EnvelopeKey/{envelopeReceiverId}")]
[Obsolete("Use MediatR")] [Obsolete("Use MediatR")]
public async Task<IActionResult> MainAsync([FromRoute] string envelopeReceiverId, [FromQuery] string? culture = null) public async Task<IActionResult> MainAsync([FromRoute] string envelopeReceiverId)
{ {
try try
{ {
//TODO: add a middelware or use an asp.net functionality insead of this code-smell
culture = culture is not null ? _sanitizer.Sanitize(culture) : null;
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
if (UserLanguage is null && culture is null)
{
UserLanguage = _cultures.Default.Language;
return Redirect($"{Request.Headers["Referer"]}?culture={_cultures.Default.Language}");
}
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId); envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
if (!envelopeReceiverId.TryDecode(out var decoded)) if (!envelopeReceiverId.TryDecode(out var decoded))
@ -560,7 +539,17 @@ public class HomeController : ViewControllerBase
if (!_cultures.Languages.Contains(language)) if (!_cultures.Languages.Contains(language))
return BadRequest(); return BadRequest();
UserLanguage = language; var cookieOptions = new CookieOptions()
{
Secure = false,
SameSite = SameSiteMode.Strict,
HttpOnly = true
};
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(language)),
cookieOptions);
return Redirect(Request.Headers["Referer"].ToString()); return Redirect(Request.Headers["Referer"].ToString());
} }
@ -574,39 +563,7 @@ public class HomeController : ViewControllerBase
[HttpGet("lang")] [HttpGet("lang")]
public IActionResult GetLanguages() => Ok(_cultures.Languages); public IActionResult GetLanguages() => Ok(_cultures.Languages);
private string? UserLanguage private string? UserLanguage => Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
{
get
{
var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
if (string.IsNullOrEmpty(cookieValue))
return null;
var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures[0];
return culture?.Value ?? null;
}
set
{
if(value is null)
Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);
else
{
var cookieOptions = new CookieOptions()
{
Expires = DateTimeOffset.UtcNow.AddYears(1),
Secure = false,
SameSite = SameSiteMode.Strict,
HttpOnly = true
};
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)),
cookieOptions);
}
}
}
public IActionResult Error404() => this.ViewError404(); public IActionResult Error404() => this.ViewError404();
} }

View File

@ -1,5 +1,4 @@
using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Resources;
using Ganss.Xss;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
@ -10,14 +9,10 @@ namespace EnvelopeGenerator.Web.Controllers
public class LocalizationController : ControllerBase public class LocalizationController : ControllerBase
{ {
private readonly IStringLocalizer<Resource> _localizer; private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<LocalizationController> _logger;
private readonly HtmlSanitizer _sanitizer;
public LocalizationController(IStringLocalizer<Resource> localizer, ILogger<LocalizationController> logger, HtmlSanitizer sanitizer) public LocalizationController(IStringLocalizer<Resource> localizer)
{ {
_localizer = localizer; _localizer = localizer;
_logger = logger;
_sanitizer = sanitizer;
} }
[HttpGet] [HttpGet]

View File

@ -0,0 +1,46 @@
using EnvelopeGenerator.Web.Models;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Options;
using System.Globalization;
namespace EnvelopeGenerator.Web.Middleware;
public class CultureMiddleware
{
private readonly RequestDelegate _next;
private readonly Cultures _cultures;
public CultureMiddleware(RequestDelegate next, IOptions<Cultures> culturesOpt)
{
_next = next;
_cultures = culturesOpt.Value;
}
public async Task InvokeAsync(HttpContext context)
{
var cookieName = CookieRequestCultureProvider.DefaultCookieName;
var cookieValue = context.Request.Cookies[cookieName];
if (string.IsNullOrEmpty(cookieValue))
{
var culture = new RequestCulture(_cultures.Default.Language);
var cookieOptions = new CookieOptions
{
Secure = false,
SameSite = SameSiteMode.Strict,
HttpOnly = true
};
context.Response.Cookies.Append(
cookieName,
CookieRequestCultureProvider.MakeCookieValue(culture),
cookieOptions);
CultureInfo.CurrentCulture = new CultureInfo(_cultures.Default.Language);
CultureInfo.CurrentUICulture = new CultureInfo(_cultures.Default.Language);
}
await _next(context);
}
}

View File

@ -201,6 +201,7 @@ try
var app = builder.Build(); var app = builder.Build();
app.UseMiddleware<ExceptionHandlingMiddleware>(); app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseMiddleware<CultureMiddleware>();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())