ASP.NET MVC3 JSON Model-binding with nested class -
in mvc3, possible automatically bind javascript objects models if model has nested objects? model looks this:
public class tweet { public tweet() { coordinates = new geo(); } public string id { get; set; } public string user { get; set; } public datetime created { get; set; } public string text { get; set; } public geo coordinates { get; set; } } public class geo { public geo(){} public geo(double? lat, double? lng) { this.latitude = lat; this.longitude = lng; } public double? latitude { get; set; } public double? longitude { get; set; } public bool hasvalue { { return (latitude != null || longitude != null); } } } when post following json controller except "coordinates" binds successfully:
{"text":"test","id":"testid","user":"testuser","created":"","coordinates":{"latitude":57.69679752892457,"longitude":11.982091465576104}} this controller action looks like:
[httppost] public jsonresult retweet(tweet tweet) { //do stuff } am missing here or new auto-binding feature support primitive objects?
yes, can bind complex json objects asp.net mvc3.
phil haack wrote recently.
you've got problem geo class here.
don't use nullable properties:
public class geo { public geo() { } public geo(double lat, double lng) { this.latitude = lat; this.longitude = lng; } public double latitude { get; set; } public double longitude { get; set; } public bool hasvalue { { return (latitude != null || longitude != null); } } } this javascript code i've use test it:
var jsondata = { "text": "test", "id": "testid", "user": "testuser", "created": "", "coordinates": { "latitude": 57.69679752892457, "longitude": 11.982091465576104} }; var tweet = json.stringify(jsondata); $.ajax({ type: 'post', url: 'home/index', data: tweet, success: function () { alert("ok"); }, datatype: 'json', contenttype: 'application/json; charset=utf-8' }); update
i've tried experiments model binders , came out solutions seems work nullable types.
i've created custom model binder:
using system; using system.web.mvc; using system.io; using system.web.script.serialization; public class tweetmodelbinder : imodelbinder { public object bindmodel(controllercontext controllercontext, modelbindingcontext bindingcontext) { var contenttype = controllercontext.httpcontext.request.contenttype; if (!contenttype.startswith("application/json", stringcomparison.ordinalignorecase)) return (null); string bodytext; using (var stream = controllercontext.httpcontext.request.inputstream) { stream.seek(0, seekorigin.begin); using (var reader = new streamreader(stream)) bodytext = reader.readtoend(); } if (string.isnullorempty(bodytext)) return (null); var tweet = new javascriptserializer().deserialize<models.tweet>(bodytext); return (tweet); } } and i've registered types tweet:
protected void application_start() { arearegistration.registerallareas(); modelbinders.binders.add(typeof(models.tweet), new tweetmodelbinder()); registerglobalfilters(globalfilters.filters); registerroutes(routetable.routes); }
Comments
Post a Comment