2011-07-03 23 views
13

MVC3'te, model iç içe nesneler varsa, javascript nesnelerini modellere otomatik olarak bağlamak mümkün mü? Ben "Koordinatlar" dışında benim denetleyicisi her şeyi aşağıdaki JSON yayınladığınızdaASP.NET MVC3 JSON Yuvalanmış sınıfla model bağlama

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

başarıyla bağlanır:

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

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

Bu benim denetleyicisi eylem neye benzediği Benim modeli şöyle

Burada bir şey eksik mi yoksa yeni otomatik bağlama özelliği yalnızca ilkel nesneleri destekliyor mu?

cevap

18

Evet, karmaşık json nesnelerini ASP.NET MVC3 ile bağlayabilirsiniz.

Phil Haack bu konuda yazdı recently.
Burada Geo sınıfınızla ilgili bir sorun var. Bazı yapmaya çalıştık

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

Güncelleme: Bunu test etmek için kullanılmasını ettik bu javascript kodudur

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

:
null özelliklerini kullanmayın model bağlayıcılarla yapılan deneyler ve nullable tiplerle düzgün çalıştığı görülen bu çözümlerle ortaya çıktım.

Bir özel modeli cilt oluşturduk:

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

ve ben tweet her türlü bunu tescil ettik:

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

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

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

NULL çıkarılması gerçekten işe yaramaz ancak boş değerleri gönderdiğinden geçerli bir lat/lng değeriyle sonuçlanacağından, modeli bozar. Json'umu elimden çıkarmak için tek yol sanırım. – jul

+0

Sadece değerleri tırnaklara koyduğumda null özelliklerle ince bağladığını fark ettim. Elbette bu bir böcek olmalı? – jul

+0

@jul: Haklısınız. İşleminizi özel bir model ciltleyici (ActionResult InsertTweet ([ModelBinder (typeof (TweetModelBinder))] Modeller.Tweet tweet ile) kullanarak bağlamaya çalışırken bazı denemeler yaptım. DictionaryValueProvider. – LeftyX

0

Ben aynı sorunu yaşadı ancak benim durumumda bu oldu Verilerin istemci tarafından nasıl iletildiği ile ilgili. AJAX isteğinin uygun üstbilgileri ve biçimlendirmeyi kullandığından emin olun. Örneğin:
dataType: 'json', 
    contentType: 'application/json; charset=UTF-8', 
    data: JSON.stringify({ 
     MemberId : '123', 
     UserName: '456', 
     Parameters: [ 
      { Value : 'testing' }, 
      { Value : 'test2' } 
     ] 
    }), 
İlgili konular