Asp.net
ASP.NET MVC3 JSON 模型綁定與嵌套類
在 MVC3 中,如果模型具有嵌套對象,是否可以自動將 javascript 對象綁定到模型?我的模型如下所示:
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 { get { return (Latitude != null || Longitude != null); } } }當我將以下 JSON 發佈到我的控制器時,除“座標”之外的所有內容都成功綁定:
{"Text":"test","Id":"testid","User":"testuser","Created":"","Coordinates":{"Latitude":57.69679752892457,"Longitude":11.982091465576104}}這是我的控制器操作的樣子:
[HttpPost] public JsonResult ReTweet(Tweet tweet) { //do some stuff }我在這裡遺漏了什麼還是新的自動綁定功能只支持原始對象?
是的,您可以使用 ASP.NET MVC3 綁定複雜的 json 對象。
Phil Haack最近寫了一篇關於它的文章。
您的 Geo 課程有問題。
不要使用可為空的屬性:
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 { get { return (Latitude != null || Longitude != null); } } }這是我用來測試它的javascript程式碼:
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' });更新
我試圖用模型綁定器做一些實驗,我提出了這個解決方案,它似乎適用於可空類型。
我創建了一個自定義模型綁定器:
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); } }我已經為所有類型的推文註冊了它:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ModelBinders.Binders.Add(typeof(Models.Tweet), new TweetModelBinder()); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); }