2009-04-03 12 views
7

Próbuję napisać niestandardowy segregator modelu, ale mam wielką trudność, próbując dowiedzieć się, jak powiązać złożone obiekty kompozytowe.Własny model spoiwa dla złożonych obiektów POMOC

to jest klasa staram się wiązać:

public class Fund 
{ 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public List<FundAllocation> FundAllocations { get; set; } 
} 

i to jest jak moja próba pisania niestandardowego spoiwo wygląda następująco:

public class FundModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) 
    { 
     var fund = new Fund(); 

     fund.Id = int.Parse(controllerContext.HttpContext.Request.Form["Id"]); 
     fund.Name = controllerContext.HttpContext.Request.Form["Name"]; 

     //i don't know how to bind to the list property :(
     fund.FundItems[0].Catalogue.Id = controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"]; 
     return fund; 
    } 
} 

Any pomysłów

dzięki Tony

+0

Właśnie napisałem pytanie, a następnie w końcu wymyśliłem rozwiązanie tego samego rodzaju problemu. Dla zainteresowanych, możesz sprawdzić poniższy link: [http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult -method-from-jquery-a] (http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult-method-from- jquery-a) –

Odpowiedz

3

Zbyt dużo wydawałem na ten właśnie s ame rzecz ostatnio!

Nie widząc formularza HTML, domyślam się, że po prostu zwraca on wyniki wyboru z listy wielokrotnego wyboru lub czegoś podobnego? Jeśli tak, twoja forma zwraca właśnie kilka liczb całkowitych zamiast zwracania uwodnionego obiektu FundAllocations. Jeśli chcesz to zrobić, w swoim niestandardowym modelu ModelBinder będziesz musiał wykonać własne wyszukiwanie i sam nawilżyć obiekt.

Coś jak:

fund.FundAllocations = 
     repository.Where(f => 
     controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"].Contains(f.Id.ToString()); 

Oczywiście, mój LINQ to tylko przykład i oczywiście można pobrać dane w każdym razie, że chcesz. Nawiasem mówiąc, i wiem, że to nie odpowiada na twoje pytanie, ale po wielu przygnębieniach zdecydowałem, że w przypadku złożonych obiektów, najlepiej użyć ViewModelu i powiązać go domyślny ModelBinder, a następnie, jeśli trzeba, uwodnić model, który reprezentuje moją istotę. Pojawiło się wiele problemów, z którymi się zetknąłem, co sprawiło, że jest to najlepszy wybór. Nie będę Cię teraz zanudzać, ale cieszę się z ekstrapolacji, jeśli chcesz.

Najnowsza rozmowa Herding Code podcast jest świetną dyskusją, podobnie jak K Scott Allen's Putting the M in MVC blog posts.

8

Czy naprawdę musisz zaimplementować niestandardowy moduł ModelBinder? Domyślną spoiwo może robić to, co trzeba (jak można go wypełnić zbiorów i obiektów złożonych):

Powiedzmy twoje działanie kontroler wygląda następująco:

public ActionResult SomeAction(Fund fund) 
{ 
    //do some stuff 
    return View(); 
} 

I html zawiera to:

<input type="text" name="fund.Id" value="1" /> 
<input type="text" name="fund.Name" value="SomeName" /> 

<input type="text" name="fund.FundAllocations.Index" value="0" /> 
<input type="text" name="fund.FundAllocations[0].SomeProperty" value="abc" /> 

<input type="text" name="fund.FundAllocations.Index" value="1" /> 
<input type="text" name="fund.FundAllocations[1].SomeProperty" value="xyz" /> 

Domyślny segregator modelu powinien zainicjować obiekt funduszu za pomocą 2 elementów na liście FundAllocations (nie wiem, jak wygląda twoja klasa FundAllocation, więc utworzyłem jedną właściwość "SomeProperty"). Tylko pamiętaj o włączeniu tych elementów "fund.FundAllocations.Index" (które domyślny segregator patrzy na własny użytek), które dostałem, gdy próbowałem to zrobić).

+0

JonoW - czy masz link do dobrej dokumentacji dla standardowego segregatora, czy po prostu spojrzałeś na źródło? –

+0

Will, przepraszam, nie mam linku do żadnej oficjalnej dokumentacji, tak naprawdę chodziłem po radę Phila Haacka na jego blogu, ponieważ miałem podobny problem - http://haacked.com/archive/2008/10 /23/model-binding-to-a-list.aspx. Może być lepszy sposób na zrobienie tego w wersji 1.0, nie jestem pewien ... – JonoW

+0

Ma rację, nie potrzebujesz niestandardowego segregatora. Możesz to zrobić, manipulując polem nazwy, jak pokazano powyżej. – MedicineMan

Powiązane problemy