2014-05-19 3 views
11

Ho un oggetto contenente parametri di ricerca, ordinamento e paging nonché un ID di un record da modificare.Asp.Net mvc 5 - Come posso passare un oggetto complesso come valore di instradamento in Html.ActionLink() in modo che il modello predefinito possa mapparlo?

Vorrei passare questo oggetto in Html.ActionLink() come oggetto valore di percorso, in modo che la stringa di query risultante venga mappata correttamente dal raccoglitore modello predefinito nel parametro Modifica azione, che è un EditViewModel.

L'idea è che dopo aver completato l'azione Modifica, è possibile reindirizzare nuovamente all'Indice e mantenere la stessa posizione di paging/ordinamento, nello stesso set di dati e filtrata dalla stessa stringa di ricerca.

Modifica vista Modello:

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

Modifica azione:

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

Quando faccio questo nella vista:

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

ottengo questo:

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

Ma voglio questo:

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

L'unico modo che ho potuto passare l'oggetto finora è stato per preparare manualmente la stringa di query, in questo modo:

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

ho pensato scrivere un modello personalizzato, ma sembra sciocco dato che il raccoglitore modello predefinito gestisce già oggetti nidificati se formattato come stringa di query nel modo previsto.

Ho anche pensato di scrivere un serializzatore di oggetto personalizzato che emette un formato seriale che il raccoglitore modello predefinito si aspetta, ma non ha ancora percorso quella via.

Infine, ho pensato di appiattire EditViewModel in modo che non vi sia nulla di nidificato, ma solo avere tutte le proprietà elencate in modo piatto. Ma non è l'ideale.

Quindi, qual è il modo migliore per andare?

risposta

9

Per quanto ne so, non è possibile passare l'oggetto complesso direttamente, ma si può evitare di dover costruire la stringa di query da soli passando un RouteValueDictionary:

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

Questo dovrebbe generare la stringa di query come ne hai bisogno.

L'unica altra alternativa sarebbe utilizzare la riflessione per scorrere le proprietà del modello e generare questo dizionario in quel modo, ma a mio avviso sarebbe troppo ingegnerizzato.

Naturalmente, vorrei suggerire di solito in questa situazione che basta il metodo di azione prendere parametri distinti:

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

avrei generalmente che questo sia un modo più appropriato per passare parametri a un GET metodo (ovviamente, questo potrebbe diventare poco pratico se si hanno molti parametri).Quindi è sufficiente fare quanto segue, che è molto più ordinato:

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

È andato con RouteValueDictionary, è almeno migliore della stringa di query non elaborata :-) Grazie. – user482184

Problemi correlati