To pytanie zostało zignorowane asked before we wcześniejszych wersjach MVC. Istnieje również this blog entry o sposobie obejścia problemu. Zastanawiam się, czy MVC3 wprowadził coś, co może pomóc, lub jeśli są jakieś inne opcje.Wiązanie modelu polimorficznego
W pigułce. Oto sytuacja. Mam abstrakcyjny model bazowy i 2 konkretne podklasy. Mam mocno napisany widok, który renderuje modele z EditorForModel()
. Następnie mam niestandardowe szablony do renderowania każdego konkretnego typu.
Problem pojawia się w momencie publikacji. Jeśli zrobię metodę post action, przyjmij klasę podstawową jako parametr, wówczas MVC nie będzie w stanie utworzyć jej abstrakcyjnej wersji (której i tak nie chciałbym chcieć, chciałbym, aby tworzył rzeczywisty konkretny typ). Jeśli utworzę wiele metod działania po zmianie, które różnią się tylko sygnaturą parametru, wówczas MVC skarży się, że jest niejednoznaczne.
Tak dalece, jak mogę powiedzieć, mam kilka opcji, jak rozwiązać ten problem. Nie podoba mi się żadna z nich z różnych powodów, ale wymienię je tutaj:
- Utwórz niestandardowy segregator, jak sugeruje Darin w pierwszym wpisie, z którym się łączyłem.
- Utwórz atrybut dyskryminatora jako drugi post, który połączyłem z sugestiami.
- Opublikuj w różnych metodach działania na podstawie typu
- ???
Nie podoba mi się 1, ponieważ jest to w zasadzie konfiguracja, która jest ukryta. Inni deweloperzy pracujący nad kodem mogą o tym nie wiedzieć i tracić dużo czasu, próbując dowiedzieć się, dlaczego rzeczy się psują, gdy zmieniają się rzeczy.
Nie podoba mi się 2, ponieważ wydaje się dość hacky. Ale jestem skłonny do tego podejścia.
Nie podoba mi się 3, ponieważ oznacza to naruszenie DRY.
Jakieś inne sugestie?
Edit:
postanowiłem iść metodą Darin, ale zanotował nieznaczne zmiany. Dodałem to do mojego abstrakcyjnego modelu:
[HiddenInput(DisplayValue = false)]
public string ConcreteModelType { get { return this.GetType().ToString(); }}
Następnie ukryty automatycznie generowany jest w moim DisplayForModel()
. Trzeba tylko pamiętać, że jeśli nie używasz DisplayForModel()
, musisz dodać to sam.
Hmm .. To zdecydowanie poprawia łatwość konserwacji. I działałoby tam, gdzie twoje konkretne modele nie różnią się pod względem podpisów nieruchomości (wada w metodzie Attribute). Nie jestem pewien, czy lubię zanieczyszczać moje poglądy tymi rodzajami dyskryminatorów. –
Wybrałem Twoje rozwiązanie, ale dokonałem niewielkiej zmiany. Zobacz moją edycję. –
Znalazłem też inne rozwiązanie (patrz moja odpowiedź), które okazuje się dużo prostsze i nieco bezpieczniejsze, ponieważ nie wiąże się z ujawnieniem typowi danych klientowi i mając nadzieję, że nie było zhakowany przez hakera. –