2011-07-03 46 views
13

Trong MVC3, có thể tự động liên kết các đối tượng javascript với các mô hình nếu mô hình có các đối tượng lồng nhau không? Mô hình của tôi trông như thế này:Mô hình JSON MVC3 JSON ràng buộc với lớp lồng nhau

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); 
     } 
    } 
} 

Khi tôi đăng JSON sau vào tất cả mọi thứ điều khiển của tôi ngoại trừ "Tọa độ" liên kết thành công:

{"Text":"test","Id":"testid","User":"testuser","Created":"","Coordinates":{"Latitude":57.69679752892457,"Longitude":11.982091465576104}} 

Đây là những gì hành động điều khiển của tôi trông giống như:

[HttpPost] 
    public JsonResult ReTweet(Tweet tweet) 
    { 
     //do some stuff 
    } 

Tôi có thiếu gì đó ở đây hay tính năng tự động ràng buộc mới chỉ hỗ trợ các đối tượng nguyên thủy?

Trả lời

18

Có, bạn có thể liên kết các đối tượng json phức tạp với ASP.NET MVC3.

Phil Haack đã viết về nó recently.
Bạn gặp sự cố với lớp Geo của mình tại đây.
Không sử dụng tính nullable:

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); 
     } 
    } 
} 

Đây là mã javascript Tôi đã sử dụng để kiểm tra nó:

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' 
}); 

CẬP NHẬT

Tôi đã cố gắng để làm một số thử nghiệm với các chất kết dính mô hình và tôi đã đưa ra các giải pháp này có vẻ hoạt động đúng với các loại có thể vô hiệu hóa.

tôi đã tạo ra một mô hình tùy chỉnh chất kết dính:

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); 
    } 
} 

và tôi đã đăng ký cho tất cả các loại tweet:

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     ModelBinders.Binders.Add(typeof(Models.Tweet), new TweetModelBinder()); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 
+0

Loại bỏ giá trị rỗng thực sự hiệu quả nhưng làm hỏng mô hình vì gửi giá trị trống sẽ dẫn đến 0 là giá trị lat/lng hợp lệ. Đoán cách duy nhất là tự deserialize json của tôi. – jul

+0

Tôi chỉ nhận thấy rằng nếu tôi đặt các giá trị trong dấu ngoặc kép, nó liên kết tốt với các thuộc tính không có giá trị. Chắc chắn đây phải là một lỗi? – jul

+0

@jul: bạn nói đúng. Tôi đã làm một số thử nghiệm cố gắng ràng buộc hành động của bạn bằng cách sử dụng một mô hình tùy chỉnh chất kết dính (ActionResult InsertTweet ([ModelBinder (typeof (TweetModelBinder))] Models.Tweet tweet)) và các giá trị ở đó, trong DictionaryValueProvider. – LeftyX

0

tôi có kinh nghiệm cùng một vấn đề, tuy nhiên trong trường hợp của tôi này là liên quan đến cách dữ liệu được truyền từ phía máy khách. Đảm bảo yêu cầu AJAX đang sử dụng tiêu đề và định dạng phù hợp. Ví dụ:

dataType: 'json', 
    contentType: 'application/json; charset=UTF-8', 
    data: JSON.stringify({ 
     MemberId : '123', 
     UserName: '456', 
     Parameters: [ 
      { Value : 'testing' }, 
      { Value : 'test2' } 
     ] 
    }), 
Các vấn đề liên quan