jquery - WebAPI instantiating objects even if they are null in JSON -


when posting json models webapi controller methods i've noticed if there null objects in json model model binder instantiate these items instead of keeping them null in server side object.

this in contrast how normal mvc controller bind data...it not instantiate object if null in json.

mvc controller

public class homecontroller : controller {     [httppost]     public actionresult test(model model)     {         return json(model);     } } 

webapi controller

public class apicontroller : apicontroller {     [httppost]     public model test(model model)     {         return model;     } } 

model class posted

public class model {     public int id { get; set; }     public widget mywidget { get; set; } } 

class used in model class

public class widget {     public int id { get; set; }     public string name { get; set; } } 

here results when post json model each controller:

$.post('/home/test', { id: 29, mywidget: null }) //results in: {"id":29,"mywidget":null}  $.post('/api/api/test', { id: 29, mywidget: null }) //results in: {"id":29,"mywidget":{"id":0,"name":null}} 

as can see, webapi method instantiated mywidget property object, whereas mvc action left null.

it doesn't seem intuitive me webapi function way. why this? can make behave mvc action in regard?

i think similar issues experienced in our projects.

you have change post code jquery following one:

$.ajax({             type: 'post',             url: '/api/api/test',             data: json.stringify({ id: 29, mywidget: null }),             contenttype: "application/json",             datatype: 'json',             timeout: 30000         })         .done(function (data) {         })         .fail(function() {         }); 

by default jquery 'posts' sends parameters form-url-encoded data.

application/x-www-form-urlencoded
id 29
mywidget

id=29&mywidget=

so deserialized absolutely correctly. mywidget empty string, have empty value of widget class.

in addition recommend add formatters configuration webapi controllers:

public static void register(httpconfiguration config)     {         // web api configuration , services          // web api routes         config.maphttpattributeroutes();          config.routes.maphttproute(             name: "defaultapi",             routetemplate: "api/{controller}/{id}",             defaults: new { id = routeparameter.optional }         );          // formatters         jsonmediatypeformatter json = config.formatters.jsonformatter;          config.formatters.clear();         config.formatters.add(json);     } 

so use json-formatter api calls.

update

main difference form-url-encoded data passed mvc controller processed runtime , handled defaultmodelbinder (if custom binder not available). data encoded form-url usual mvc because data generated html form post. web api not rely on specific encoding design. uses specific mechanism (formatters) parse data... example json above. formurlencodedmediatypeformatter system.net.http.formatting , defaultmodelbinder system.web.mvc handle empty string differently.

for defaultmodelbinder empty string converted null. analyzing code can decide bindmodel method firstly creates empty model:

 if (model == null)  {      model = createmodel(controllercontext, bindingcontext, modeltype);  } 

after fill properties:

// call property's model binder         imodelbinder propertybinder = binders.getbinder(propertydescriptor.propertytype);         object originalpropertyvalue = propertydescriptor.getvalue(bindingcontext.model);         modelmetadata propertymetadata = bindingcontext.propertymetadata[propertydescriptor.name];         propertymetadata.model = originalpropertyvalue;         modelbindingcontext innerbindingcontext = new modelbindingcontext()         {             modelmetadata = propertymetadata,             modelname = fullpropertykey,             modelstate = bindingcontext.modelstate,             valueprovider = bindingcontext.valueprovider         };         object newpropertyvalue = getpropertyvalue(controllercontext, innerbindingcontext, propertydescriptor, propertybinder); 

and getbinder return fallbackbinder widget type (type of property). , fallbackbinder call convertsimpletype string processed following:

        string valueasstring = value string;         if (valueasstring != null && string.isnullorwhitespace(valueasstring))         {             return null;         } 

i guess there no standards describing conversion url-encoded strings c# objects. not know 1 correct. in case sure need pass json through ajax calls not form-url-encoded data.


Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -