2012-03-19 4 views
8

목록이 들어있는 복잡한 JSON 객체를 바인딩하기 위해 ASP.NET MVC3을 가져 오는 데 문제가 있습니다.MVC3 복잡한 JSON 목록 바인딩

여기 내 개체에 대한 구조가 있습니다.

public class PageModel 
{ 
    public PageModel() { } 
    public CustomObject1 CustomObject { get; set; } 
    public IEnumerable<CustomObject2> Objects { get; set; } 

} 

public class CustomObject1 
{ 
    public CustomObject1() { } 
    [Required] 
    public int CustomId1 { get; set; } 
    public string CustomName { get; set; } 
} 

public class CustomObject2 
{ 
    public CustomObject2() { } 
    [Required] 
    public int Custom2Id { get; set; } 
    public CustomObject3 SubItem { get; set; } 
    public int SubItemId { get; set; } 
} 

당신은 CustomObject3을 가정 할 수는 유사한 구조이다 - 또 다른 만들어 클래스를 복제 할 필요가 없습니다, 그래서 당신은 당신의 상상력 :

을 사용할 수 있습니다 파악 여기에 POST 호출을 자바 스크립트/jQuery를의 (가정이 모든 것이 정확한 데이터 제공에 이르기까지의 JS) : 마지막으로

//$obj1 has all data for the first object 
var firstObj = { }; 
firstObj.CustomId1 = $obj1.Id; 
firstObj.CustomName = $obj1.Name; 

var i = 0; 

//$objects is an array with all the data 
$.each($objects, function() { 
    objsArray[i] = { 
    Custom2Id: $(this).Id, 
    SubItemId: $(this).itemId 
    }; 

    ++i; 
}); 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

그리고 (나는 알고있다, 꽤 코드) 여기에 방법에 대한 개요 내가 가진 :

public class ActionController : Controller { 
    public JsonResult Method(PageModel model) { 
     //Gets here - model.CustomObject is filled correctly, and model.Objects has a correct count of whatever data I passed to the method - but all of the properties are empty! 
    } 
} 

내가 말했듯이 첫 번째 객체는 채워지고 디버깅 및 단계를 거치면 모든 데이터가 저장됩니다. JSON 객체의 Objects 배열에있는 두 객체를 전달하면 컨트롤러에 Count의 2가 표시되지만 Custom2IdSubItemId은 비어 있습니다. 뭐라 구요?

$.ajax 호출에서 contentType'application/json'으로 지정되면 MVC는 전달되는 데이터에 대해 불만을 토로합니다. 또한 MVC 메서드에서 model 매개 변수를 두 개의 개별 매개 변수로 분할하려고했지만 도움이되지 않습니다.

어떤 도움을 주셔서 감사합니다 -이 하나가 저를 곤혹스럽게했습니다!

답변

5

그래서이 특정 문제에 대한 해결책은 SO의 다른 곳에서 발견 된 둘 이상의 솔루션의 조합입니다 (그 중 하나는 일반 컬렉션 유형 인 IEnumerable 사용과 관련하여 Jakub의 답변 일 가능성이 있음) 하나 - List).

먼저 서버 측 코드를 변경할 필요는 없습니다. 모두 앞면에 있습니다. 변경해야 할 모든 사항은 클라이언트 측, 특히 jQuery와 Javascript가 어떻게 서버로 데이터를 보내는 지에 대한 것입니다.

여기에 기존의 자바 스크립트입니다 : 여기

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

첫 번째 문제는 자바 스크립트가 '/Action/Method'에서 서버를 알리는되지 않는 것입니다 정확히 당신이 이진,이 매개 변수의 혼합이다, 또는이다 (보내는 그것 JSON?) 따라서 contentType: 'application/json' 행을 추가하면 그 목적을 달성 할 수 있습니다. 이렇게하면 서버는 JSON을 디코딩해야한다는 것을 알게됩니다. ...

그러나 이제는 코드가 사용자의 메서드에 들어가기 전에 예외가 발생하여 디코딩이 실패합니다 ("Invalid JSON primitive"). MVC는 디코딩과 바인딩을 처리한다. 위 AJAX 호출에서 $.ajax 옵션으로 새 JSON 객체를 작성했지만 JSON이 JSON 유효성 검사기를 통과하지 못합니다 (James Kyburz는 훌륭한 JSON 유효성 검사기 : JSONLint Validator). 대신 $.ajax 호출 전에 JSON 객체를 만들고 객체를 적절한 JSON 형식으로 문자열을 지정하십시오. 전부, 여기에 AJAX 호출이 어떻게 보일지입니다 : -`IEnumerable`가`IList`는`List`는 모두 같은 결과를 -

var dataObj = { CustomObject: firstObj, Objects: objsArray }; 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    contentType: 'application/json', 
    data: JSON.stringify(dataObj), 
    //Success/error handlers here 
}); 
+0

덕분에 많은 도움이되었습니다 :)! – Rookian

+0

완전한 기능 코드를 원하는 시간 이후,이게 내 문제를 해결했습니다! 감사!! –

3

모델 바인더는 IEnumerable 인터페이스의 인스턴스를 생성하는 방법을 알고하지 않습니다 public IEnumerable<CustomObject2> Objects { get; set; }

List<CustomObject2>에 변경, 그것은 뭔가 더 구체적인 필요합니다.

당신은이를 변경해야

data: { CustomObject: firstObj, Objects: objsArray }

data: { model: { CustomObject: firstObj, Objects: objsArray } }

model 부분은 액션의 매개 변수의 이름과 일치합니다.

+0

나는이 주변에 연주 한 객체의 정확한 번호 목록을 그 가치가 없다. – Mattygabe

+0

두 번째 부분에 동의하지 않습니다. 특정 인스턴스에서 도움이 될 수도 있지만, MVC3은 전달할 데이터가 내 '모델'매개 변수에 속하는지 식별 할만큼 충분히 똑똑합니다. 위에서 설명한 작업 솔루션은 MVC를 달래기 위해 추가 객체 레이어를 지정하지 않습니다. 이는 내가하는 작업을 식별 할 수 있습니다. – Mattygabe