我可以将视图模型传递给动作链接以生成路线吗?

时间:2011-10-14 09:39:56

标签: asp.net-mvc-3 asp.net-mvc-2

我需要创建一个基于我的搜索条件的链接。例如:

localhost/Search?page=2&Location.PostCode=XX&Location.Country=UK&IsEnabled=true 

此链接中的参数是我的SearchViewModel中的属性值。

理想情况下,我希望有以下几点:

@Html.ActionLink("Search","User", Model.SearchCriteria)

这是默认支持还是我需要将视图模型的属性传递给RouteValueDictionary类型对象然后使用它?

我的目标是编写一个分页助手,它将生成页码并将搜索条件参数附加到生成的链接。

E.g。

@Html.GeneratePageLinks(Model.PagingInfo, x => Url.Action("Index"), Model.SearchCriteria)

我已将您的解决方案与PRO ASP.NET MVC 3书中的建议结合起来,最终得到以下结论:

帮助生成链接。有趣的部分是pageUrlDelegate参数,稍后用于调用Url.Action以生成链接:

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

然后在视图模型中:

@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}
    }))
)

我仍然对字符串中的属性名称不满意,但现在必须这样做。

谢谢:)

2 个答案:

答案 0 :(得分:11)

  

理想情况下,我希望有以下几点:

     

@Html.ActionLink("Search","User", Model.SearchCriteria)

不幸的是,这是不可能的。您必须逐个传递属性。你确实可以使用带有RouteValueDictionary

的重载
@Html.ActionLink(
    "Search",
    "User",
    new RouteValueDictionary(new Dictionary<string, object>
    {
        { "Location.PostCode", Model.SearchCriteria.PostCode },
        { "Location.Country", Model.SearchCriteria.Country },
        { "IsEnabled", Model.IsEnabled },
    })
)

当然,编写自定义ActionLink帮助程序可能更好:

public static class HtmlExtensions
{
    public static IHtmlString GeneratePageLink(this HtmlHelper<MyViewModel> htmlHelper, string linkText, string action)
    {
        var model = htmlHelper.ViewData.Model;
        var values = new RouteValueDictionary(new Dictionary<string, object>
        {
            { "Location.PostCode", model.SearchCriteria.PostCode },
            { "Location.Country", model.SearchCriteria.Country },
            { "IsEnabled", model.IsEnabled },
        });
        return htmlHelper.ActionLink(linkText, action, values);
    }
}

然后:

@Html.GeneratePageLink("some page link text", "index")

另一种可能性是仅传递id并让控制器操作从最初在呈现此视图的控制器操作中获取它的任何位置获取相应的模型和值。

答案 1 :(得分:1)

这里有一些代码来自史蒂夫桑德森的Tekpub samples,这是你正在寻找的广泛代码。首先在对象上定义一个扩展方法 -

public static RouteValueDictionary DetailsRouteValues(this JobAd jobAd)
{
    return new RouteValueDictionary
    {
        { "controller", "Jobs" },
        { "action", "Details" },
        { "id", jobAd.JobAdId },
        { "country", MakeSimpleUrlSegment(jobAd.LocationCountry) },
        { "city", MakeSimpleUrlSegment(jobAd.LocationCity) },
        { "title", MakeSimpleUrlSegment(jobAd.Title) }
    };
}

然后使用该方法调用Html.RouteLink -

<%= Html.RouteLink(ad.Title, ad.DetailsRouteValues())%>