2012-12-22 8 views
7

Czy istnieje sposób radzenia sobie z tym bez niestandardowego wiązania modelu?ASP.NET MVC 4 ViewModel z interfejsem podrzędnym

public class MyViewModel { 
    public string UserId { get; set; } 
    public IJob Job { get; set; } 
} 

public interface IJob { 
    public long Id { get; set; } 
    public string CompanyName { get; set; } 
} 

public class FullTimeJob : IJob { 
    // omitted for brevity 
} 

public class Internship : IJob { 
    // omitted for brevity 
} 

Problem Mam to pojawia się błąd w domyślnej spoiwa modelu, ponieważ nie rozumieją który wdrożenie IJob instancji. Po utworzeniu MyViewModel ustawiłem instancję klasy FullTimeJob w jej właściwości zadania. Chyba ASP.NET nie może zachować typu implementacji?

Jakie jest najlepsze rozwiązanie w tym zakresie?

Odpowiedz

1

Widoki to tylko nośniki danych między interfejsem użytkownika a kontrolerem. Możesz więc po prostu dodać właściwości Id i CompanyName do swojego widoku. Ponieważ wszystko, co chcesz zrobić, to pobranie identyfikatora i wartości firmy z interfejsu użytkownika. Może nie być ważne, czy jest to praca stażowa czy praca w pełnym wymiarze czasu, podczas pobierania danych z interfejsu użytkownika. Może to być ważne podczas przetwarzania danych pobranych z interfejsu użytkownika, ale nie jest to odpowiedzialność firmy View.

+0

Chcę móc utrzymać hierarchię obiektów, więc zdecydowanie chcę * uniknąć * umieszczania pól związanych z pracą bezpośrednio na modelu widoku. Jeśli to robię, ViewModel nic mi nie kupuje. –

+0

Tak, zrobiłem to w niestandardowym segregatorze, ale miałem nadzieję, że będzie mniej niestandardowa odpowiedź. –

+0

Możesz uczynić swój ViewModel generycznym czymś w rodzaju 'class MyViewModel gdzie T: IJob, new()' i w konstruktorze możesz utworzyć instancję niestandardowego Job Type 'Job = new T();' ale nadal zależy to od konkretnego typu Job. –

0

Jedną z opcji, choć nie jest szczególnie elegancki, może być następująca:

public class MyViewModel { 
    public string UserId { get; set; } 
    public FulltimeJob FulltimeJob { get; set; } 
    public InternJob InternJob { get; set; } 

    public IJob Job { get { return FulltimeJob ?? InternJob; } } 
} 

To daje łatwy dostęp do wspólnych właściwości poprzez właściwość Job, zachowując dostęp do wszystkich właściwości klasy specyficzne.

Następnie można sprawdzić, która właściwość jest wypełniona w metodach kontrolera POST i odpowiednio postępować.

+0

To jest fajny pomysł na rozwiązanie, i widzę, dokąd zmierzasz, chociaż problem jest taki, że kiedy dodam nowa implementacja IJob (z której mam już 6), musiałbym zmodyfikować tę klasę. Nie byłoby strasznie, gdyby te dwa dodatkowe pola, które dodałeś, były na mapie lub kolekcji, ale nadal wydaje się trochę niezgrabne. –

+0

Zgadzam się; Sądzę, że sprowadza się to do tego, jak podobne są te klasy i czy naprawdę powinniśmy dzielić się poglądami i metodami kontrolującymi je. Inną (choć podobną) trasą jest spłaszczenie modelu widoku i uwzględnienie tylko pól (unii wszystkich pól ze wszystkich klas zadań) oraz JobType, aby poinformować w kontrolerze, jakie pola mogą być wypełnione. Użyj AutoMapper lub Fasterflect, aby uprościć/zautomatyzować mapowanie właściwości, aby było to nieco łatwiejsze. –