Come ben sappiamo, in linea generale una action di ASP.NET MVC può accettare qualsiasi tipo di parametro. Per esempio, nel caso in cui dobbiamo gestire una richiesta in cui ci viene fornito un'intervallo di date, è assolutamente possibile scrivere un metodo di questo tipo:
public ActionResult Search(DateTime from, DateTime to) { // .. codice qui .. }
E' poi compito del framework, e nello specifico dell'accoppiata value provider e model binder, trasformare il dato proveniente dal browser nei due oggetti DateTime; ciò avviene recuperando le informazioni dal contenuto della form, nel caso in cui la richiesta sia di tipo POST, o dalla querystring se ci troviamo al cospetto di una chiamata di tipo GET.
Quando i parametri sono sensibili alla culture dell'utente (come nel caso del tipo DateTime), bisogna prestare particolare attenzione al formato in cui vengono inviati, perché il comportamento del framework varia sensibilmente a seconda della tipologia della richiesta. Infatti, se in caso di POST, il parse avviene in base alla cultura dell'utente, quando la richiesta è in GET viene forzata la InvariantCulture, che prevede per le date il formato americano. Questa scelta ha una ragione di fondo, ossia che gli URL devono essere invarianti rispetto alla culture dell'utente che li genera, e pertanto è consigliabile utilizzare sempre una sola culture per interpretare le richieste.
Purtroppo, però, l'uso della invariant culture può creare problemi nel caso in cui generiamo un URL dall'input dell'utente che, verosimilmente, sarà in formato italiano. Per esempio, immaginiamo di invocare la action vista in precedenza con la seguente form:
@using (Html.BeginForm("Search", null, FormMethod.Get)) { <span>Data da:</span> @Html.TextBox("from")<br /> <span>Data a:</span> @Html.TextBox("to")<br /> <input type="submit" value="Cerca" /> }
Come possiamo notare, questa form è inviata in GET con i due parametri from e to in querystring e, in condizioni normali, trasformati in DateTime secondo la invariant culture. Il risultato sarà che, se per esempio inseriamo la data "10/07/2012", questa sarà interpretata erroneamente:

Per ovviare a questo problema, possiamo creare un value provider personalizzato. Si tratta di un'operazione assolutamente banale, perchè tutta la logica di parsing è contenuta nella classe base NameValueCollectionValueProvider, e quindi possiamo limitarci semplicemente a specificare in maniera esplicita la culture da utilizzare.
internal class CultureQueryStringValueProvider : NameValueCollectionValueProvider { public CultureQueryStringValueProvider( ControllerContext context, CultureInfo culture) : base(context.HttpContext.Request.QueryString, culture) { } }
Questo oggetto accetta nel costruttore un parametro di tipo CultureInfo, che sarà fornito dall'oggetto CultureQueryStringValueProviderFactory, responsabile di istanziarlo:
internal class CultureQueryStringValueProviderFactory : ValueProviderFactory { private CultureInfo _culture; public CultureQueryStringValueProviderFactory(CultureInfo culture) { if (culture == null) throw new ArgumentNullException("culture"); _culture = culture; } public override IValueProvider GetValueProvider( ControllerContext controllerContext) { return new CultureQueryStringValueProvider(controllerContext, _culture); } }
A questo punto non ci resta che l'ultimo passo, ossia sostituire, nel Global.asax, la nostra factory personalizzata a quella di default di ASP.NET MVC, specificando che vogliamo usare la culture italiana:
protected void Application_Start() { // rimuovo il value provider factory di default var toRemove = ValueProviderFactories.Factories .OfType<QueryStringValueProviderFactory>() .Single(); ValueProviderFactories.Factories.Remove(toRemove); // aggiungo il value provider custom var culture = CultureInfo.GetCultureInfo("it-IT"); ValueProviderFactories.Factories.Add( new CultureQueryStringValueProviderFactory(culture)); }
Se ora proviamo a ricaricare la pagina precedente, essa mostrerà le date interpretate correttamente.

Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Ottimizzare le performance usando Span<T> e il metodo Split
Proteggere le risorse Azure con private link e private endpoints
Eseguire i worklow di GitHub su runner potenziati
Filtering sulle colonne in una QuickGrid di Blazor
Usare i settings di serializzazione/deserializzazione di System.Text.Json di ASP.NET all'interno di un'applicazione non web
Gestione file Javascript in Blazor con .NET 9
Migliorare la sicurezza dei prompt con Azure AI Studio
Documentare i servizi REST con Swagger e OpenAPI con .NET 9
Introduzione ai web component HTML
Usare il colore CSS per migliorare lo stile della pagina
Testare l'invio dei messaggi con Event Hubs Data Explorer