2011-04-18 10 views
46

Por alguna razón, cuando envío este JSON para una acción:defecto ASP.NET MVC carpeta de 3 modelo no se une propiedades decimales

{"BaseLoanAmount": 5000} 

que se supone debe estar vinculado a un modelo con una propiedad decimal llamado "BaseLoanAmount", que no se une, que sólo se queda 0. pero si yo envío:

{"BaseLoanAmount": 5000.00} 

que no se une la propiedad, pero ¿por qué? ¿No se puede convertir 5000 a un evento decimal si no tiene números decimales?

Respuesta

71

Después de entrar en el código fuente de asp.net mvc, que seemsd el problema es que para el asp.net mvc conversión utiliza convertidor de tipos del marco, que por alguna razón devuelve false para un int a la conversión decimal, que terminé usando un proveedor de ligante modelo personalizado y un aglutinante modelo para los decimales, se puede ver aquí:

public class DecimalModelBinder : DefaultModelBinder 
{ 
    #region Implementation of IModelBinder 

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 

     if (valueProviderResult.AttemptedValue.Equals("N.aN") || 
      valueProviderResult.AttemptedValue.Equals("NaN") || 
      valueProviderResult.AttemptedValue.Equals("Infini.ty") || 
      valueProviderResult.AttemptedValue.Equals("Infinity") || 
      string.IsNullOrEmpty(valueProviderResult.AttemptedValue)) 
      return 0m; 

     return Convert.ToDecimal(valueProviderResult.AttemptedValue); 
    }  

    #endregion 
} 

para registrar este ModelBinder, sólo hay que poner la siguiente línea en el interior Application_Start():

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()); 
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder()); 
+4

Expresión booleana en 'return' La declaración 'valueProviderResult == null' no se puede evaluar como verdadera, ya que' valueProviderResult.AttemptedValue' antes de eso generaría una excepción de null-ref. – Diego

+2

nota: Phil Haack también recomienda esto, http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx –

+2

He estado utilizando su solución original para resolver exactamente este problema, ¡gracias! Un problema: ¿nulos destinados a decimal? los campos se asignan cero en su lugar. Finalmente opté por verificar 'valueProviderResult.RawValue == null' para determinar si asignar el valor predeterminado del tipo. – Matt

12

intente enviarlo de esta manera:

{ "BaseLoanAmount": "5000" } 
+2

Uso JSON.stringify para preparar el JSON, ¿hay alguna solución del lado del servidor para esto? No quiero tener que meterme con el código del cliente, ya que ASP.NET MVC no está haciendo bien su trabajo. – ryudice

+2

@ryudice, me temo que así es como el serializador javascript se ocupa de los formatos numéricos. Las cosas pueden ser aún más complicadas cuando comienzas a usar decimales, flotadores, nulables ... Encontrarás muchas discrepancias. De todos modos, de acuerdo con la especificación JSON, las citas deben usarse siempre, así que no estoy seguro de quién no está haciendo su trabajo correctamente. Por lo tanto, es posible que deba convertir el valor numérico en una cadena antes de codificarlo en el lado del cliente. –

+0

Acabo de enterarme de que si cambio el tipo de propiedad para doblar, se une bien, ¿sabe si el problema podría estar en el proveedor de valores o en la carpeta de modelo? y ¿sabes si hay un proveedor de valor que utiliza JSON.net en lugar del deserializador de JavaScript de frameworks? – ryudice

Cuestiones relacionadas