2013-07-10 24 views
8

Bir GET isteğinde bir MVC eylem yöntemine uri iç içe yerleştirilmiş dizi ile karmaşık bir nesne göndermek istiyorum.[FromUri] özniteliğini kullanma - karmaşık nesneyi iç içe geçmiş dizeyle bağlama

Aşağıdaki kodu düşünün:

public ActionResult AutoCompleteHandler([FromUri]PartsQuery partsQuery){ ... } 

public class PartsQuery 
{ 
    public Part[] Parts {get; set; } 
    public string LastKey { get; set; } 
    public string Term { get; set; } 
} 

$.ajax({ 
    url: "Controller/AutoCompleteHandler", 
    data: $.param({           
         Parts: [{ hasLabel: "label", hasType: "type", hasIndex : 1 }], 
         LastKey : "Last Key", 
         Term : "Term"        
        }), 
    dataType: "json", 
    success: function(jsonData) { ... } 
}); 

Bu sadece iyi çalışır ve doğru olarak MVC Web Api varsayılan modeli cilt kullanarak bağlanır.

Ancak aşağı düz MVC değil WebAPI ve varsayılan modeli bağlayıcı sonları için bu geçiş ve iç içe dizide nesnelerde özelliklerini bağlanılamıyor:

partsQuery  != null   //Good 
--LastKey  == "Last Key" //Good 
--Term   == "Term"  //Good 
--Parts[]  != null   //Good 
----hasLabel == null   //Failed to bind 
----hasType  == null   //Failed to bind 
----hasIndex == 0    //Failed to bind 
Ben

istiyorum

İzleme Listesi Bu neden düz MVC'de bozulduğunu ve FromUriAttribute nesnesinin bu nesneyi doğru olarak nasıl oluşturduğunu bilmek için MVC

+0

'Parça [] Parçalarını' ICollection Parts' olarak değiştirirseniz ne olur? Ve 'Part' için sınıf tanımını gösterebilir misin? –

+0

Şimdi bunu deniyorum. Kısmen halka açık basit POCO'dur {get; set; } sahne – parliament

+0

'Part' parametresiz bir kurucu var mı? –

cevap

9

Buradaki temel sorun, MVC ve WebApi'nin farklı model b kullanmasıdır. inders. Taban arayüzleri bile farklıdır.

Mvc - System.Web.Mvc.IModelBinder 
Web API - System.Web.Http.ModelBinding.IModelBinder 

Eğer $ .ajax çağrısı ile veri göndermek

, aşağıdaki sorgu dizesi parametrelerini gönderiyor:

Parts[0][hasLabel]:label 
Parts[0][hasType]:type 
Parts[0][hasIndex]:1 
LastKey:Last Key 
Term:Term 

While, MVC varsayılan model bağlayıcı ile bağlanacaktır uygun biçimi için farklı bir adlandırma kuralı vardır parametre isimleri:

Parts[0].hasLabel:label 
Parts[0].hasType:type 
Parts[0].hasIndex:1 
LastKey:Last Key 
Term:Term 

Yani, bu yöntem çağrısı çalışacak:

$.ajax({ 
      url: "Controller/AutoCompleteHandler?Parts[0].hasLabel=label&Parts[0].hasType=type&Parts[0].hasIndex=1&LastKey=Last+Key&Term=Term", 
      dataType: "json", 
      success: function(jsonData) { ... } 
     }); 

MVC model bağlayıcı adlandırma kurallarına uygun sorgu dizginizi oluşturmanız gerekir. MVC DefaultModelBinder tarafından bilinmediği için, örnek eyleminizde [FromUri] özniteliği de tamamen yok sayılır.

+0

Cevabınız için teşekkürler, ancak bunu çoktan biliyordum. 2 olası çözüm, url dizgisini istemci tarafındaki doğru sözleşmeye zorlamak olabilir, benim sorum şu: http://stackoverflow.com/questions/17580471/javascript-regex-to-coerce-url-string-returned-from -param-içine-mvc-model-bindi, VEYA varsayılan $ .param() kuralı işlemek için özel bir model bağlayıcı yapmak, benim soru şu: http://stackoverflow.com/q/17558735/1267778 .. Ama ben ' En temiz çözümün düşünülmesi MVC desteğini FromUri yapmaktır, bu da bu soru için. Eğer hiç kimse cevabınızı işaretleyemezse cevabınız – parliament

+0

Regex yeterince temiz bir çözümdür, bu yüzden sizin de cevabınızı cevap olarak işaretleyeceğim, çünkü yine de değerlidir.Ama eğer birisi FromUri'nin MVC'de nasıl çalışacağına dair asıl soruya cevap verebilirse bunu işaretleyeceğim. Thanky ou – parliament

+1

Web API bağlayıcısını MVC denetleyicisinde çalıştırmayı çok büyük bir çaba olacağını düşünüyorum. Boru hatları tamamen farklıdır ve Web API bağlayıcısını çağırmak için, alt düzey web-api'ye özgü nesnelerin (HttpControllerDescriptor, HttpActionDescriptor, ModelBindingContext, vb) düzgün bir şekilde toplanması gerekir. – Nenad

İlgili konular