I'm passing an object from client to server. Properties of the object which are represented as string.empty are being converted to null during this process. I was wondering how to prevent this when the objects type supports string.empty.
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); } });
My model includes nullable DateTime objects. I cannot force all nulls to string.empty on the server.
I am using AutoMapper, so I would prefer not to have to inspect properties individually on the server.
This is a MVC feature which binds empty strings to null
s.
This logic is controlled with the ModelMetadata.ConvertEmptyStringToNull property which is used by the DefaultModelBinder
.
You can set the ConvertEmptyStringToNull
with the DisplayFormat
attribute
public class OrderDetailsModel { [DisplayFormat(ConvertEmptyStringToNull = false)] public string Comment { get; set; } //... }
However if you don't want to annotate all the properties you can create a custom model binder 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 the ModelBinderAttribute in your action:
public ActionResult SaveOrderDetails([ModelBinder(typeof(EmptyStringModelBinder))] OrderDetailsModel orderDetailsModel) { }
Or you can set it as the Default ModelBinder globally in your Global.asax:
ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();
You can read more about this feature here.
Instead of creating a ModelBinder which modifies the ModelMetadata as some answers suggested, a cleaner 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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With