2011-09-20 25 views
11

esASP.Net MVC 3 se unen propiedad de cadena como String.Empty en lugar de null modelo

public partial class BilingualString 
{ 
    public string RuString { get; set; } 
    public string EnString { get; set; } 
} 

public partial class Member 
{ 
    public Member() 
    { 
     this.DisplayName = new BilingualString(); 
    } 
    public BilingualString DisplayName { get; set; } 
} 

si el usuario no se debe rellenar los valores de las entradas RuString y EnString es nulo. Necesito cadena. Vacío en lugar de nulo.

Usando CustomModelBinder así:

public class EmptyStringModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     bindingContext.ModelMetadata.ConvertEmptyStringToNull = false; 
     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

no ayudan.

Respuesta

15

Utilice esta:

[DisplayFormat(ConvertEmptyStringToNull=false)] 
    public string RuString { get; set; } 

O

private string _RuString; 
    public string RuString { 
     get { 
      return this._RuString ?? ""; 
     } 
     set { 
      this._RuString = value ?? ""; 
     } 
    } 
+1

¿Qué pasa si no queremos marcar cada campo de cadena como '[DisplayFormat (ConvertEmptyStringToNull = false)]'? – AlexBBB

+1

¡puede usar la segunda manera! –

+0

La pregunta es cómo decirle a MVC 3 que enlace la entrada html vacía como cadena. Vacío, no como nulo (como en MVC 1). BilingualString es un ejemplo para mostrar que EmptyStringModelBinder personalizado no hace el truco. – AlexBBB

2

vieja pregunta, pero aquí es una respuesta de todos modos :)

El problema parece ser que el ConvertEmptyStringToNull se establece en el modelo de unión contexto, no el contexto vinculante de la propiedad.

Dentro de DefaultModelBinder, llama a BindProperty para cada propiedad del modelo, y no recursa objetos simples como cadenas/decimales a su propia llamada de BindModel.

Afortunadamente, podemos anular GetPropertyValue en su lugar y establecer la opción en el contexto allí.

public class EmptyStringModelBinder : DefaultModelBinder 
{ 
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 
    { 
     bindingContext.ModelMetadata.ConvertEmptyStringToNull = false; 
     return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); 
    } 
} 

trabajado para mí :)

[editar] Como se señaló en los comentarios .. Esta carpeta modelo sólo funcionará si está registrada, así que después de la adición de la clase, asegúrese de llamar

ModelBinders.Binders.Add(typeof(string), new EmptyStringModelBinder()); 

en el método Application_Start() de Global.asax.cs

+1

Para que esto funcione, también necesita agregar 'ModelBinders.Binders.Add (typeof (cadena), nuevo EmptyStringModelBinder());' en 'Application_Start()'. Después de agregar esta línea, funcionó para mí también. – Manfred

+0

Lo siento, mi mal, respondí la pregunta de OP en la suposición de que sabían hacer esto dado que ya habían intentado una carpeta personalizada. ¡No pensé en nadie más! – Mike

Cuestiones relacionadas