2014-05-19 3 views
11

Ich habe ein Objekt mit Such-, Sortier- und Paging-Parametern sowie einer ID eines zu bearbeitenden Datensatzes.Asp.Net mvc 5 - Wie kann ich ein komplexes Objekt als Routenwert in Html.ActionLink() übergeben, so dass das Standardmodellbinder es zuordnen kann?

Ich möchte dieses Objekt in Html.ActionLink() als ein Route-Wert-Objekt übergeben, so dass die resultierende Abfragezeichenfolge von der Standardmodellmappe in den Edit-Aktionsparameter, der ein EditViewModel ist, ordnungsgemäß zugeordnet wird.

Die Idee ist, dass nach Abschluss der Aktion Bearbeiten kann es zurück in den Index umleiten und die gleiche Paging/Sortierung Position in der gleichen Datei beibehalten und gefiltert durch die gleiche Suchzeichenfolge.

Bearbeiten Ansicht Modell:

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; } 
} 

Aktion bearbeiten:

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

Wenn ich dies tun in der Ansicht:

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

bekomme ich diese:

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

Aber ich mag dies:

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

Der einzige Weg, ich in der Lage gewesen, so das Objekt passiert weit wurde manuell den Query-String erstellen, wie folgt aus:

@{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> 

Ich dachte an Schreiben eines benutzerdefinierten Modellbinders, aber es scheint albern, da der Standardmodellordner bereits verschachtelte Objekte verarbeitet, wenn er wie erwartet in einer Abfragezeichenfolge formatiert wird.

Ich dachte auch daran, einen benutzerdefinierten Objekt-Serializer zu schreiben, der ein serielles Format ausgibt, das vom Standardmodellbinder erwartet wird, aber noch nicht diesen Weg gegangen ist.

Schließlich dachte ich daran, das EditViewModel flach zu machen, so dass nichts verschachtelt ist, einfach alle Eigenschaften aufgelistet haben. Aber es ist nicht ideal.

Also, was ist der beste Weg zu gehen?

Antwort

9

Soweit ich weiß, kann man nicht das komplexe Objekt direkt übergeben, aber Sie können vermeiden, dass die Query-String selbst, indem ein RouteValueDictionary bauen zu müssen: wie sollte die Abfrage-String erzeugen

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

Diese du brauchst es.

Die einzige andere Alternative wäre die Verwendung von Reflektion, um über die Eigenschaften des Modells zu iterieren und dieses Wörterbuch auf diese Weise zu generieren, aber das wäre meiner Meinung nach überentwickelt.

Natürlich würde ich vorschlagen, im Allgemeinen in dieser Situation, die Sie gerade Ihre Aktion-Methode nehmen separate Parameter haben:

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

ich in der Regel betrachten würde dies eine geeignetere Weg, um Parameter zu übergeben GET ein Methode (das könnte natürlich unhandlich werden, wenn Sie viele Parameter haben).Dann kannst du einfach folgendes machen, das ist viel aufgeräumter:

+0

War mit dem RouteValueDictionary, es ist mindestens besser als die rohe Abfrage :-) Danke. – user482184

Verwandte Themen