2012-01-26 7 views
9

Mam model widok tak:Czy możesz usunąć prefiks pola HTML z mocno wpisanych modeli w MVC 3?

public class EditVM 
{ 
    public Media.Domain.Entities.Movie Movie  { get; set; } 
    public IEnumerable<Genre>   Genres  { get; set; } 
} 

Film jest prawdziwym podmiotem życzę edytować. Gatunki są po prostu obecne, aby zapełnić pole rozwijane. Wolałbym, że kiedy zadzwonić:

@Html.TextBoxFor(m => m.Movie.Title) 

wewnątrz mojego silnie typami zdania, że ​​kontrola wprowadzania mieć nazwę = "Title" zamiast "Movie.Title"

Nie chciałbym podzielić mój pogląd na częściowym widokiem lub stracić mój mocno napisany widok za pomocą ViewData lub tym podobnych.

Czy istnieje sposób wyrażenia w widoku, że nie chcę mieć prefiksu Movie.? Zauważyłem, że można ustawić:

ViewData.TemplateInfo.HtmlFieldPrefix = "x"; 

w sterowniku, ale niestety wydaje się tylko, aby umożliwić dodanie dodatkowe prefiks. Ustawienie go na "" nic nie robi.

Czy są jakieś prace? Czy utknąłem z niefortunnym przedrostkiem, który nie jest konieczny w tym przypadku, jeśli chcę zachować mocno wpisane widoki i lambdy?

Dzięki za pomoc.

Aktualizacja:

Oto działania kontrolera do może dokonać rzeczy nieco jaśniejsze.

public ActionResult Edit(int? id) 
{ 
    var vm = new EditVM 
    { 
    Movie = id.HasValue ? _movieSvc.Find(id.Value) : new Movie(), 
    Genres = AppData.ListGenres()  
    }; 
    return View(vm); 
} 

[HttpPost] 
public void Edit([Bind(Prefix = "Movie")]Movie m) 
{ 
    _movieSvc.AddOrUpdateMovie(m); //Exceptions handled elsewhere 
} 

Odpowiedz

5

Nie, aby zrobić to, co chcesz trzeba by przepisać pomocników HTML, a następnie trzeba by napisać własny spoiwo modelu. Wydaje się, że dużo pracy przy minimalnym zysku.

Jedynym wyborem jest widok częściowy, w którym przekazujesz obiekt filmu jako model. Wymagałoby to jednak napisania własnego segregatora, aby został rozpoznany.

Powodem, dla którego musisz zrobić m.Movie.Title, jest to, że identyfikator ma poprawną nazwę, więc segregator modelu może rozpoznać go jako członka Twojego modelu.

Na podstawie aktualizacji:

wyboru są następujące opcje:

  1. użytku innego niż silnie wpisane pomocników.
  2. Użyj częściowego widoku.
  3. Przepisz Stronly wpisywanych pomocników
  4. w ogóle nie wolno używać pomocników i napisać wartości do HTML

Osobiście, chciałbym po prostu użyć 1 lub 2, chyba 2.

EDYTOWANIE:

Na podstawie powyższej aktualizacji.Zmienić swój kod do tego (uwaga, Gatunki nie zostanie wysłane z powrotem do serwera, więc m.Genres będzie tylko zerowy na odświeżenie strony):

[HttpPost] 
public void Edit(EditVM m) 
{ 
    _movieSvc.AddOrUpdateMovie(m.Movie); //Exceptions handled elsewhere 
} 

EDIT:

I nie tylko myśleć o alternatywę do tego. Po prostu można to zrobić:

@{ var Movie = Model.Movie; } 
@Html.TextBoxFor(m => Movie.Title) 

Jeśli jednak wystąpił błąd sprawdzania poprawności, konieczne będzie ponowne utworzenie pliku EditVM.

+1

Nie sądzę, żebym musiał napisać segregator. Wersja 'GET' mojej akcji edycyjnej używa EditVM, ponieważ wymaga wszystkich danych. Ale wersja 'POST' oczekuje tylko na otrzymanie obiektu Movie. Jeśli atrybuty nazwy byłyby po prostu "tytułem" itp., Wiązałoby się to dobrze. –

+0

Używasz więc innego posta w swoim poście niż w przypadku zdobycia i wyświetlenia. To może być mylące i dlatego masz problemy. To nie jest "szczęśliwa ścieżka".Będziesz musiał pójść na kompromis. Zobacz moją aktualizację. –

+1

Tak, to jest kompromis, którego zamierzam uniknąć. BTW Myślę, że masz na myśli powiedzieć, że jest to właściwość nazwy, a nie id, z którego korzysta segregator modelu. Mam wrażenie, że myślisz, że robię coś z rezerwacji tutaj, jeśli chodzi o sposób, w jaki zamierzam stworzyć akcję edycji. Myślałem, że to, co robię, jest dość powszechne. Czy nigdy nie masz drop-downów jako części edytowanych przez ciebie jednostek? Jak inaczej podchodzisz do problemu? Czy zazwyczaj tworzysz widoki częściowe tylko dla kontrolki rozwijanej? W jaki sposób wypełniasz drop-downy i czy akcje GET/POST nie mają innych parametrów? –

1

Mam model widok jak ten

myślę, że może mieć jakieś nieporozumienie na temat tego, co jest model widok. Model widoku nie powinien zawierać żadnych odniesień do modeli domen, które wydają się być klasami Movie i Genre. Mam na myśli tworzenie nowej klasy, która ma sufiks z VM i w której wypychasz wszystkie swoje modele domen, ponieważ właściwości nie są tak naprawdę modelem widoku. Model widoku to klasa zaprojektowana specjalnie pod kątem wymagań Twojego widoku.

Znacznie bardziej poprawne widok model ten wygląda następująco:

public class EditVM 
{ 
    public string MovieTitle { get; set; } 
    public IEnumerable<GenreViewModel> Genres { get; set; } 
} 

i Pana zdaniem trzeba:

@Html.EditorFor(x => x.MovieTitle) 
@Html.EditorFor(x => x.Genres) 
+0

Nie jestem pewien, czy zgadzam się z Tobą na temat modeli widoku. Być może używam tego określenia luźniej niż Ty, ale wybieram połączenie danych wymaganych przez widok, aby sam się "wyświetlić model". Niezależnie od tego, co wybierzesz, ale jeśli klasa może zostać utworzona z istniejących klas w mojej domenie, które pasują do tej potrzeby, nie widzę, aby były one "niepoprawne". –

+1

@ C.J. - nie jest "niepoprawne" używanie ich w widoku (cóż, nie jest to zalecane, ale na pewno można to zrobić), "niewłaściwe" jest nazywanie ich modelem widoku. Darin jest absolutnie poprawny, Model Widok to model dostosowany do widoku, a nie tylko wspólne pakowanie modeli Domeny. W najlepszym razie nazwałbym to modelem Pseudo-View. Nie ma co się z tym zgadzać ani się z tym nie zgadzać, definicja modelu widoku jest całkiem jasna. –

+0

Czy powiedziałbyś, że Steven Walther, który był starszym menedżerem programu w zespole Microsoft ASP.NET, również źle się spisał w tym poście? http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx –

1

Innym rozwiązaniem jest użyć przeciążenie TextBox(string name, object value) zamiast TextBoxFor :

@Html.TextBox("Title", Model.Movie.Title) 

Można również określić wejście g HTML zamiast korzystać z helpera.

Inną opcją jest użycie EditVM jako parametru odświeżania. Oto co bym zrobił. Mój parametr działania postu jest zawsze tym samym typem modelu .cshtml. Tak, będą właściwości, takie jak listy, które są puste, ale po prostu je ignorujesz. Pozwala również na grube obsługiwanie błędów postów, ponieważ jeśli wystąpi błąd, musisz mimo to zwrócić instancję tego modelu widoku i uwzględnić zawarte w nim wartości. Zwykle mam prywatne metody lub warstwę DB, która obsługuje pobieranie różnych list, które trafiają do ViewModel, ponieważ te będą puste na poczcie zwrotnej i będą musiały zostać ponownie wypełnione, nie dotykając właściwości, które były w poście.

Przy użyciu tej samej metody wpisu, jeśli chcesz przywrócić ten sam widok, musisz utworzyć nową EditVM, a następnie skopiować wszystkie zaksięgowane wartości i nadal wypełniać listy. Dzięki mojej metodzie eliminujesz jeden z tych kroków mapowania. Jeśli publikujesz więcej niż jedną rzecz, czy będziesz mieć kilka różnych parametrów w swojej akcji postu? Po prostu pozwól im w naturalny sposób przejść do jednego parametru wpisanego w EditVM widoku. Chociaż może mieć te właściwości null w VM podczas postback czuje icky, dostajesz ładną przewidywalną spójność między View i zwrotnym IMO. Nie musisz spędzać dużo czasu zastanawiając się, jaka kombinacja parametrów w twojej metodzie postu dostarczy Ci wszystkich danych z formularza.

Powiązane problemy