I have an object containing searching, sorting and paging parameters as well as an id of a record to be edited.
I'd like to pass this object into Html.ActionLink() as a route value object, so that the resulting query string will be correctly mapped by the default model binder into the Edit action's parameter, which is an EditViewModel.
The idea is that after the Edit action completes, it can redirect back to the Index and maintain the same paging/sorting position, in the same data set, and filtered by the same search string.
Edit View 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)
{
/* ... */
}
When I do this in the view:
@model MyApp.Areas.Books.ViewModels.Books.IndexViewModel
...
@{EditViewModel evm = new EditViewModel(Model.SearchSortPageParams, item.ID);}
@Html.ActionLink("Edit", "Edit", evm)
I get this:
http://localhost:63816/Books/Books/Edit/4?SearchSortPageParams=MyApp.Areas.Base.ViewModels.SearchSortPageViewModel
But I want this:
http://localhost:63816/Books/Books/Edit/4?SearchSortPageParams.SearchString=abc&SearchSortPageParams.SortCol=name&SearchSortPageParams.SortOrder=asc&SearchSortPageParams.Page=1&SearchSortPageParams.PageSize=3
The only way I have been able to pass the object so far has been to manually prepare the query string, like this:
@{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>
I thought of writing a custom model binder, but it seems silly given that the default model binder already handles nested objects if formatted as a query string in the way it expects.
I also thought of writing a custom object serializer which outputs a serial format which the default model binder expects, but haven't yet gone down that route.
Finally, I thought of flattening out the EditViewModel so there is nothing nested, just have all the properties listed out flatly. But, it's not ideal.
So, what is the best way to go?