7

Tengo la siguiente clase modelo (despojado por simplicidad):ASP.NET MVC enlazador predeterminado: enteros demasiado tiempo, el mensaje de error de validación vacío

public class Info 
{ 
    public int IntData { get; set; } 
} 

Ésta es mi forma de afeitar que utiliza este modelo:

Ahora si ingreso datos no numéricos en el cuadro de texto, recibo un mensaje de validación correcto, es decir: "Valor 'qqqqq' no es válido para el campo 'IntData'".

Pero si ingreso una secuencia muy larga de dígitos (como 345234775637544), recibo un resumen de validación EMPTY.

En mi código del controlador, veo que es ModelState.IsValidfalse como se esperaba, y ModelState["IntData"].Errors[0] es el siguiente:

{System.Web.Mvc.ModelError} 
ErrorMessage: "" 
Exception: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."} 

(exception itself) [System.InvalidOperationException]: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."} 
InnerException: {"345234775637544 is not a valid value for Int32."} 

Como se puede ver, la validación funciona normalmente, pero no cede un mensaje de error el usuario.

¿Puedo modificar el comportamiento del encuadernador de modelo predeterminado para que muestre un mensaje de error adecuado en este caso? ¿O tendré que escribir una carpeta personalizada?

Respuesta

8

Una forma sería escribir un modelo personalizado de aglutinante:

public class IntModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (value != null) 
     { 
      int temp; 
      if (!int.TryParse(value.AttemptedValue, out temp)) 
      { 
       bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format("The value '{0}' is not valid for {1}.", value.AttemptedValue, bindingContext.ModelName)); 
       bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value); 
      } 
      return temp; 
     } 
     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

que podría estar registrada en Application_Start:

ModelBinders.Binders.Add(typeof(int), new IntModelBinder()); 
+0

Gracias, voy a optar por esta solución si no voy a poder modificar el encuadernador predeterminado. – Zruty

+0

Sugiero cambiar 'bindingContext.ModelName' a' bindingContext.ModelMetadata.DisplayName' si desea el nombre de campo localizado sobre el atributo '[Display (Name = ...)]'. – Gh61

1

Cómo acerca de la configuración MaxLength en el campo de entrada de 10 o así? Haría eso en combinación con establecer un rango en IntData. A menos, por supuesto, que desee permitir que un usuario ingrese 345234775637544. En ese caso, es mejor con una cadena.

+0

ahora eso es algo en lo que no pensé :) Gracias. – Zruty

+0

eso es inteligente :)! – frictionlesspulley

Cuestiones relacionadas