Ho appena rivisitato il problema in un progetto reale e finalmente ho trovato una soluzione funzionante. soluzione adeguata è quella di avere un modello personalizzato legante per il tipo di decimal
(e decimal?
se si sta utilizzando loro):
using System.Globalization;
using System.Web.Mvc;
public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
object result = null;
// Don't do this here!
// It might do bindingContext.ModelState.AddModelError
// and there is no RemoveModelError!
//
// result = base.BindModel(controllerContext, bindingContext);
string modelName = bindingContext.ModelName;
string attemptedValue =
bindingContext.ValueProvider.GetValue(modelName).AttemptedValue;
// Depending on CultureInfo, the NumberDecimalSeparator can be "," or "."
// Both "." and "," should be accepted, but aren't.
string wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;
string alternateSeperator = (wantedSeperator == "," ? "." : ",");
if (attemptedValue.IndexOf(wantedSeperator) == -1
&& attemptedValue.IndexOf(alternateSeperator) != -1)
{
attemptedValue =
attemptedValue.Replace(alternateSeperator, wantedSeperator);
}
try
{
if (bindingContext.ModelMetadata.IsNullableValueType
&& string.IsNullOrWhiteSpace(attemptedValue))
{
return null;
}
result = decimal.Parse(attemptedValue, NumberStyles.Any);
}
catch (FormatException e)
{
bindingContext.ModelState.AddModelError(modelName, e);
}
return result;
}
}
Poi nel Global.asax.cs in Application_Start():
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
Nota che il codice non è mio, l'ho trovato sul blog di Kristof Neirynck here. Ho appena modificato alcune righe e sto aggiungendo il raccoglitore per un tipo di dati specifico, non sostituendo il raccoglitore predefinito.
fonte
2011-02-25 12:51:14
Ho appena aggiornato la mia risposta aggiungendo un codice di controllo aggiuntivo per far sì che gestisca correttamente le proprietà nullable. Ho scoperto che se ha trovato una stringa vuota come valore tentato, genererebbe un'eccezione anche se la proprietà vincolata è nullable. Ora dovrebbe funzionare bene. –
C'è una correzione complementare lato client che dovrebbe essere applicata a questa. Lo troverai qui: http://stackoverflow.com/a/8102159/41420 –
Non funziona con la stringa come input – Furtiro