2014-05-19 30 views
11

Mam obiekt zawierający parametry wyszukiwania, sortowania i stronicowania oraz identyfikator rekordu do edycji.Asp.Net mvc 5 - Jak mogę przekazać obiekt złożony jako wartość trasy w Html.ActionLink(), aby domyślny segregator modelu mógł go odwzorować?

Chciałbym przekazać ten obiekt do obiektu Html.ActionLink() jako obiektu wartości trasy, tak aby wynikowy ciąg zapytania został poprawnie zmapowany przez domyślny segregator modelu do parametru akcji edycji, który jest EditViewModel.

Chodzi o to, że po zakończeniu akcji Edytuj można przekierować z powrotem do indeksu i zachować tę samą pozycję stronicowania/sortowania, w tym samym zbiorze danych i przefiltrowaną przez ten sam ciąg wyszukiwania.

Edycja Widok Model:

public class EditViewModel 
{ 
    public SearchSortPageViewModel SearchSortPageParams { get; set; } 
    public int Id { get; set; } 

    public EditViewModel() 
    { 
     SearchSortPageParams = new SearchSortPageViewModel(); 
     Id = 0; 
    } 

    public EditViewModel(SearchSortPageViewModel searchSortPageParams, int id) 
    { 
     SearchSortPageParams = searchSortPageParams; 
     Id = id; 
    } 
} 

public class SearchSortPageViewModel 
{ 
    public string SearchString { get; set; } 
    public string SortCol { get; set; } 
    public string SortOrder { get; set; } 
    public int Page { get; set; } 
    public int PageSize { get; set; } 
} 

Edit action:

public ActionResult Edit(EditViewModel evm) 
    { 
     /* ... */ 
    } 

Kiedy zrobić to w widoku:

@model MyApp.Areas.Books.ViewModels.Books.IndexViewModel 
... 
@{EditViewModel evm = new EditViewModel(Model.SearchSortPageParams, item.ID);} 
@Html.ActionLink("Edit", "Edit", evm) 

uzyskać to:

http://localhost:63816/Books/Books/Edit/4?SearchSortPageParams=MyApp.Areas.Base.ViewModels.SearchSortPageViewModel 

Ale chcę to:

http://localhost:63816/Books/Books/Edit/4?SearchSortPageParams.SearchString=abc&SearchSortPageParams.SortCol=name&SearchSortPageParams.SortOrder=asc&SearchSortPageParams.Page=1&SearchSortPageParams.PageSize=3 

Jedynym sposobem udało mi się przekazać obiekt do tej pory ręcznie przygotować ciąg kwerendy, tak:

@{string theQueryString = "?SearchSortPageParams.SearchString=" + @evm.SearchSortPageParams.SearchString + "&SearchSortPageParams.SortCol=" + @evm.SearchSortPageParams.SortCol + "&SearchSortPageParams.SortOrder=" + @evm.SearchSortPageParams.SortOrder + "&SearchSortPageParams.Page=" + @evm.SearchSortPageParams.Page + "&SearchSortPageParams.PageSize=" + @evm.SearchSortPageParams.PageSize;} 
<a href="@Url.Action("Edit", new { evm.Id })@(theQueryString)">Edit</a> 

myślałem pisząc niestandardowy segregator modelu, ale wydaje się to głupie, biorąc pod uwagę, że domyślny segregator modelu obsługuje już zagnieżdżone obiekty, jeśli jest sformatowany jako ciąg zapytania w oczekiwany sposób.

Pomyślałem również o napisaniu serializera obiektów niestandardowych, który wyprowadza format szeregowy, który domyślny model spoiwa oczekuje, ale jeszcze nie przeszedł tej trasy.

Wreszcie, pomyślałem o spłaszczeniu EditViewModel, więc nie ma nic zagnieżdżonego, po prostu wszystkie właściwości są wyszczególnione. Ale nie jest idealny.

Jaki jest najlepszy sposób, aby przejść?

Odpowiedz

9

O ile mi wiadomo, nie można przejść skomplikowany obiekt bezpośrednio, ale można uniknąć konieczności budowania ciąg kwerendy samodzielnie przez przepuszczenie RouteValueDictionary:

@Html.ActionLink("Edit", "Edit", new RouteValueDictionary { 
    {"SearchSortPageParams.SortOrder", evm.SearchSortPageParams.SortOrder }, 
    { /* etc... */ } 
}) 

ten powinien generować ciąg kwerendy jako Potrzebujesz tego.

Jedyną alternatywą byłoby użycie refleksji do iteracji właściwości modelu i wygenerowania tego słownika w ten sposób, ale to, moim zdaniem, byłoby zbyt skomplikowane.

Oczywiście, ja generalnie wskazują, że w tej sytuacji po prostu mają swoje metody działania w oddzielnych parametrów:

public ActionResult Search(string searchString, SortOrder sortOrder, ...) 

bym generalnie uznają to za bardziej odpowiedni sposób przekazać parametry do GET metoda (oczywiście może to stać się nieporęczne, jeśli masz dużo parametrów).Następnie możesz wykonać następujące czynności, które są znacznie bardziej uporządkowane:

@Html.ActionLink("Edit", "Edit", 
    new { sortOrder = evm.SearchSortPageParams.SortOrder, ... }) 
+0

Poszedł z RouteValueDictionary, jest co najmniej lepszy niż ciąg surowych zapytań :-) Dzięki. – user482184