Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC 3 bind string property as string.Empty instead of null

model is

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; } 
} 

if user don't fill inputs the values of RuString and EnString is null. I need string.Empty instead of null.

Using CustomModelBinder like this:

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

don't help.

like image 782
AlexBBB Avatar asked Sep 20 '11 18:09

AlexBBB


2 Answers

Use this:

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

OR

    private string _RuString;
    public string RuString {
        get {
            return this._RuString ?? "";
        }
        set {
            this._RuString = value ?? "";
        }
    }
like image 144
amiry jd Avatar answered Oct 06 '22 01:10

amiry jd


old question, but here's an answer anyway :)

The issue seems to be that the ConvertEmptyStringToNull is set on the model binding context, not the property binding context.

Inside the DefaultModelBinder, it calls BindProperty for each property of the model, and doesn't recurse simple objects like strings/decimals down to their own call of BindModel.

Luckily we can override the GetPropertyValue instead and set the option on the context there.

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);
   }
} 

Worked for me :)

[edit] As pointed out in comments.. This model binder will only work if registered, so after adding class, be sure to call

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

in the Application_Start() method of Global.asax.cs

like image 31
Mike Avatar answered Oct 06 '22 01:10

Mike