2009-02-27 5 views
12

내 mvc 응용 프로그램에서 일부 바인딩 작업을 원합니다. 중첩 된 속성은 asp.net mvc의 RC1 릴리스에서 기본 모델 바인더에 의해 자동으로 바인딩되지 않습니다.asp.net mvc에서 중첩 된 속성의 모델 바인딩

public class Contact{ 
    public int Id { get; set; } 
    public Name Name { get; set; } 
    public string Email { get; set; } 
} 

으로 Name가 정의 :

using(Html.BeginForm()){ 
    Html.Textbox("Name.Forename", Model.Name.Forename); 
    Html.Textbox("Name.Surname", Model.Name.Surname); 
    Html.Textbox("Email", Model.Email); 
    Html.SubmitButton("save", "Save"); 
} 

내 컨트롤러 액션은 다음과 같이 정의된다 : 내 뷰의 라인을 따라 정의된다

public class Name{ 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
} 

나는 다음과 같은 클래스 구조를 가지고 :

public ActionResult Save(int id, FormCollection submittedValues){ 
    Contact contact = get contact from database; 
    UpdateModel(contact, submittedValues.ToValueProvider()); 

    //at this point the Name property has not been successfully populated using the default model binder!!! 
} 

Email 속성은 성공적으로 바인딩되지만 Name.Forename 또는 Name.Surname 속성은 바인딩되지 않습니다. 아무도 이것이 기본 모델 바인더를 사용하여 작동해야하는지 그리고 내가 잘못한 일을하고 있는지, 아니면 작동하지 않고 모델 객체에 중첩 된 속성을 바인딩하기 위해 내 자신의 코드를 롤백해야하는지 알 수 있습니까?

답변

9

문제는 속성의 이름 접두사 때문인 것 같습니다. 두 모델로 그것을 업데이트하고 두 번째 모델의 접두사를 지정해야 할 것 같습니다. 매개 변수에서 FormCollection을 제거하고 기본 제공 값 공급자를 사용하고 고려해야 할 속성의 화이트리스트를 지정하는 UpdateModel의 서명을 사용했습니다.

public ActionResult Save(int id) 
{ 
    Contact contact = db.Contacts.SingleOrDefault(c => c.Id == id); 

    UpdateModel(contact, new string[] { "Email" }); 
    string[] whitelist = new string[] { "Forename", "Surname" }; 
    UpdateModel(contact.Name, "Name", whitelist); 
} 
+0

위대한 작품입니다, 감사합니다 tvanfosson. –

+0

SingleOrDefault는 lamda 표현식으로 직접 호출 할 수 있습니다 –

+0

@PhilippM 당신은 절대적으로 옳았습니다. – tvanfosson

4

그게 매우 흥미로운 내가 큰 성공이 사용하고 당신이

public ActionResult Save(int id, Contact contact) 
{ 
    //contact here would contain the nested values. 
} 

을 수행했다면 때문이다. 다음 두 개의 Contact 객체를 어떻게 든 동기화 할 수 있다고 가정합니다.

UpdateModel과 매개 변수에 대한 바인딩이 배후에서 동일한 호출을 사용한다고 생각했을 것입니다. 참고 : 문제를 재현하려하지 않았습니다.

3

POST에서 전체보기 모델이 아닌 이름을 바인딩하려면 모델 바인더에 접두사가 사용되도록 지시하는 것이 좋습니다. 이 작업은 BindAttribute를 사용하여 수행됩니다.

public ActionResult AddComment([Bind(Prefix = "Name")] Name name) 
{ 
    //do something 
} 
관련 문제