I need to create a link that will be based on my search criteria. For example:
localhost/Search?page=2&Location.PostCode=XX&Location.Country=UK&IsEnabled=true
Parameters in this link are the values of properties in my SearchViewModel.
Ideally I’d like to have something on the lines of:
@Html.ActionLink("Search","User", Model.SearchCriteria)
Is this supported by default or do I need to pass properties of my view model into RouteValueDictionary type object and then use that?
My goal is to write a paging helper which would generate page numbers and append the search criteria parameters to the generated links.
E.g.
@Html.GeneratePageLinks(Model.PagingInfo, x => Url.Action("Index"), Model.SearchCriteria)
I’ve combined your solutions with suggestion from PRO ASP.NET MVC 3 book and ended up with the following:
Helper for generating links. Interesting part is pageUrlDelegate parameter which is later used to invoke Url.Action for generating links:
public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfoViewModel pagingInfo,
Func<int,String> pageUrlDelegate)
{
StringBuilder result = new StringBuilder();
for (int i = 1; i <= 5; i++)
{
TagBuilder tagBuilder = new TagBuilder("a");
tagBuilder.MergeAttribute("href", pageUrlDelegate(i));
tagBuilder.InnerHtml = i.ToString();
result.Append(tagBuilder.ToString());
}
return MvcHtmlString.Create(result.ToString());
}
Then in the view model:
@Html.PageLinks(Model.PagingInfo, x => Url.Action("Index","Search", new RouteValueDictionary()
{
{ "Page", x },
{ "Criteria.Location.PostCode", Model.Criteria.Location.PostCode },
{ "Criteria.Location.Town", Model.Criteria.Location.Town},
{ "Criteria.Location.County", Model.Criteria.Location.County}
}))
)
I’m still not happy with property names in Strings, but It’ll have to do for now.
Thank you 🙂
Unfortunately that’s not possible. You will have to pass properties one by one. You could indeed use the overload which takes a
RouteValueDictionary:Of course it’s probably better to write a custom ActionLink helper to do this:
and then:
Another possibility is to pass only the
idand have the controller action fetch the corresponding model and values from wherever you fetched it initially in the controller action that rendered this view.