String.empty converts to null when passing a JSON object to the MVC Controller

I am passing the object from client to server. The properties of the object, which are represented as string.empty, are converted to zero during this process. I was wondering how to prevent this when the type of objects supports string.empty.

enter image description here

console.log("DataToPost:", dataToPost); $.ajax({ type: "POST", contentType: 'application/json' url: "../../csweb/Orders/SaveOrderDetails/", data: dataToPost, success: function (result) { console.log(result); }, error: function (e) { console.error(e); } }); 

enter image description here

My model includes DateTime objects with a null value. I cannot force all zeros to string.empty on the server.

I use AutoMapper, so I would prefer not to check the properties on the server.

+32
javascript jquery c # asp.net-mvc
Oct 04
source share
5 answers

This is an MVC function that associates empty strings with null s.

This logic is controlled using the ModelMetadata.ConvertEmptyStringToNull property, which is used by DefaultModelBinder .

You can set ConvertEmptyStringToNull using the DisplayFormat attribute

 public class OrderDetailsModel { [DisplayFormat(ConvertEmptyStringToNull = false)] public string Comment { get; set; } //... } 

However, if you do not want to comment on all the properties, you can create a custom mediator where you set it to false:

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

And you can use ModelBinderAttribute in your action:

 public ActionResult SaveOrderDetails([ModelBinder(typeof(EmptyStringModelBinder))] OrderDetailsModel orderDetailsModel) { } 

Or you can set it as the default global ModelBinder in your Global.asax:

 ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder(); 

Read more about this feature here .

+64
04 Oct
source share

Instead of creating a ModelBinder that modifies ModelMetadata as some of the suggested answers, a simpler alternative is to provide a custom ModelMetadataProvider.

 public class EmptyStringDataAnnotationsModelMetadataProvider : System.Web.Mvc.DataAnnotationsModelMetadataProvider { protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); modelMetadata.ConvertEmptyStringToNull = false; return modelMetadata; } } 

Then in Application_Start ()

 ModelMetadataProviders.Current = new EmptyStringDataAnnotationsModelMetadataProvider(); 
+10
Dec 01 '13 at 14:39
source share

The accepted answer did not work for me using MVC4. However, the next workaround does, and I thought this would help others.

 public class CustomModelBinder : DefaultModelBinder { public bool ConvertEmptyStringToNull { get; set; } public CustomModelBinder () { } public CustomModelBinder (bool convertEmptyStringToNull) { this.ConvertEmptyStringToNull = convertEmptyStringToNull; } protected override bool OnModelUpdating(ControllerContext controllerContext, ModelBindingContext bindingContext) { // this little bit is required to override the ConvertEmptyStringToNull functionality that we do not want! foreach (string propertyKey in bindingContext.PropertyMetadata.Keys) { if(bindingContext.PropertyMetadata[propertyKey] != null) bindingContext.PropertyMetadata[propertyKey].ConvertEmptyStringToNull = this.ConvertEmptyStringToNull; } return base.OnModelUpdating(controllerContext, bindingContext); } } 

This will fix the problem in MVC4 +. It would seem that bindingContext.ModelMetadata.ConvertEmptyStringToNull is completely ignored, and this is because this parameter exists in the PropertyMetadata object for each associated property. PropertyMetadata is recreated in BindProperty (), so if you set it before calling this method, it will be overwritten if it does not exist as a property attribute of the associated object (for example, [DisplayFormat (ConvertEmptyStringToNull = false)]). No one wants to do this on every property as stupid.

+2
Oct 10 '13 at 18:29
source share

The problem is that AutoMapper turns nullables to null when the row is empty. This other question was answered by what, in my opinion, satisfies your needs: Automatic empty string for empty

0
04 Oct '12 at 19:16
source share

When sending data with $.ajax , null not a possible value for the data parameter property. If you look at the request using the HTTP debugger, you will see that it is converted to an empty string.

Therefore, I assume that your MVC controller uses the opposite conversion.

What I am doing in an ajax application to solve this problem is that I do not use the data $.ajax() parameter, but I serialize everything in JSON and put it in one option's β€œdata” field. For example, you have no problem with null values. Of course, you must deserialize on the server side.

0
04 Oct
source share



All Articles