Alcuni anni fa ci siamo occupati di come impostare la culture per la validazione client side con jQuery.Validate e, in particolare, Globalize.js. Questo framework nel tempo è stato completamente rivoluzionato, e oggi è interamente basato su CLDR (acronimo di Common Locale Data Repository), un progetto di Unicode Consortium che contiene un enorme numero di regole di localizzazione, non solo per numeri e date, ma anche nomi degli stati, delle lingue, della pluralizzazione, ecc.
Il sito ufficiale di questo progetto è raggiungibile a questo URL: http://cldr.unicode.org/
Come possiamo sfruttare questa enorme mole di dati nella nostra applicazione ASP.NET? Il primo passo è quello di includere i necessari script e il modo più semplice per farlo è aggiungere due package NuGet:
install-package cldrjs
install-package jquery-globalize
Questi sono i componenti infrastrutturali, che richiedono però una serie di informazioni addizionali specifiche per le culture che vogliamo supportare. I metadati di CLDR sono implementati sotto forma di file JSON, che vengono combinati tra di loro fino a generare il modello a oggetti vero e proprio. Essi sono disponibili in una serie di repository su GitHub, che possiamo raggiungere a partire da questo indirizzo: https://github.com/unicode-cldr/cldr-json
Come possiamo intuire, si tratta di un gran numero di file, e il rischio di perdersi nei meandri di GitHub è davvero molto alto. Un tool che ci viene in aiuto per capire quali siano quelli che effettivamente dobbiamo includere è questa pagina web, nella quale possiamo selezionare le funzioni che effettivamente vogliamo supportare: http://johnnyreilly.github.io/globalize-so-what-cha-want/
Immaginiamo, per esempio, di voler supportare solo la globalization delle date, il risultato sarà simile a quello dello screenshot in basso e includerà, oltre all'infrastruttura già aggiunta tramite NuGet, alcuni elementi globali nella cartella "supplemental" più altri che variano a seconda della culture.

Questi sono i file che dovremo scaricare da GitHub e aggiungere nella nostra cartella scripts, fino ad avere una struttura simile a quella della figura in basso, nella quale abbiamo aggiunto il supporto alla sola cultura italiana.

Ora che abbiamo aggiunto tutti i file necessari, possiamo creare un nuovo bundle in BundleConfig che comprenda i file JavaScript di cui abbiamo bisogno:
bundles.Add(new ScriptBundle("~/bundles/globalize").Include(
"~/Scripts/cldr.js",
"~/Scripts/cldr/event.js",
"~/Scripts/cldr/supplemental.js",
"~/Scripts/globalize.js",
"~/Scripts/globalize/number.js",
"~/Scripts/globalize/date.js"));
Ora rechiamoci sulla nostra layout view, e carichiamo anche questo nuovo bundle:
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/globalize")
@RenderSection("scripts", required: false)
@if (!this.IsSectionDefined("scripts"))
{
@Scripts.Render("~/bundles/jqueryval")
}
I componenti così caricati non sono ancora idonei ad assolvere il loro compito, perchè non abbiamo associato le definizioni JSON relative alla culture. Pertanto, al caricamento della pagina, dobbiamo ricordarci di effettuare il download dal server delle definizioni necessarie con alcune chiamate AJAX:
<script>
@{
var culture = "it";
}
$(function () {
$.when(
$.get('@Url.Content("~/Scripts/cldr/supplemental/likelySubtags.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content($"~/Scripts/cldr/main/{culture}/numbers.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content("~/Scripts/cldr/supplemental/numberingSystems.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content($"~/Scripts/cldr/main/{culture}/ca-gregorian.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content($"~/Scripts/cldr/main/{culture}/timeZoneNames.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content("~/Scripts/cldr/supplemental/timeData.json")')
.success(function (data) { Globalize.load(data); }),
$.get('@Url.Content("~/Scripts/cldr/supplemental/weekData.json")')
.success(function (data) { Globalize.load(data); })
).then(function () {
Globalize.locale('@culture');
});
})
</script>
Nel codice in alto abbiamo prima creato una variabile server side, culture, in questo esempio forzatamente impostata su "it", e poi l'abbiamo sfruttata per generare il path corretto per gli script da caricare. In un sito multilingua, invece, potremo determinare questo dato da Thread.CurrentThread.CurrentUICulture.
Ora che il tutto è configurato, manca un ultimo passaggio, ossia impostare l'uso di Globalize.js nelle funzioni di validazione di jQuery.Validate. Lo script necessario è concettualmente banale (non dobbiamo far altro che impostare i validator per i diversi tipi di dato), ma richiede una certa conoscenza di come jQuery.Validate funzioni internamente. L'alternativa più semplice è replicare lo snippet presente in questo blog post: http://blog.johnnyreilly.com/2015/10/jquery-validation-globalize-hits-10.html
(function ($, Globalize) {
if (!$.validator) {
return;
}
// Clone original methods we want to call into
var originalMethods = {
min: $.validator.methods.min,
max: $.validator.methods.max,
range: $.validator.methods.range
};
// Globalize options - initially just the date format used for parsing
// Users can customise this to suit them
$.validator.methods.dateGlobalizeOptions = {
dateParseFormat: { skeleton: "yMd" }
};
// Tell the validator that we want numbers parsed using Globalize
$.validator.methods.number = function (value, element) {
var val = Globalize.parseNumber(value);
return this.optional(element) || ($.isNumeric(val));
};
// Tell the validator that we want dates parsed using Globalize
$.validator.methods.date = function (value, element) {
var val = Globalize.parseDate(value,
$.validator.methods.dateGlobalizeOptions.dateParseFormat);
return this.optional(element) || (val instanceof Date);
};
// Tell the validator that we want numbers parsed using Globalize,
// then call into original implementation with parsed value
$.validator.methods.min = function (value, element, param) {
var val = Globalize.parseNumber(value);
return originalMethods.min.call(this, val, element, param);
};
$.validator.methods.max = function (value, element, param) {
var val = Globalize.parseNumber(value);
return originalMethods.max.call(this, val, element, param);
};
$.validator.methods.range = function (value, element, param) {
var val = Globalize.parseNumber(value);
return originalMethods.range.call(this, val, element, param);
};
}(jQuery, Globalize));
Finalmente i passaggi sono terminati! Se abbiamo svolto tutto correttamente, dovremmo essere in grado di validare client side, una data inserita in formato italiano senza alcun ulteriore intervento. Per provarlo ci basta creare una semplice pagina di esempio:

Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Paginare i risultati con QuickGrid in Blazor
Triggerare una pipeline su un altro repository di Azure DevOps
Utilizzare DeepSeek R1 con Azure AI
Generare una User Delegation SAS in .NET per Azure Blob Storage
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Collegare applicazioni server e client con .NET Aspire
Disabilitare le run concorrenti di una pipeline di Azure DevOps
Creare una libreria CSS universale: i bottoni
Definire stili a livello di libreria in Angular
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Utilizzare Copilot con Azure Cosmos DB
I più letti di oggi
- Windows 8 Developer Event e Lab - Milano
- Microsoft Cloud and ASP.NET Developer Day 2014 - Milano
- Dal MIX08 la Preview2 di ASP.NET MVC
- Annunciata la modalità di uscita di ADO.NET Entity Framework e dei Data Services
- .NET Framework 4.0 e VS 2010: beta1 per tutti
- Da oggi è possibile sviluppare per Windows Phone 7 anche in Visual Basic
- Presentata la nuova versione di C#
- Avalon ed Indigo beta1 RC ISO
- Visual Studio Online e continuous deployment con Azure