Могу ли я передать модель представления в ссылку действия для создания маршрута? - PullRequest
12 голосов
/ 14 октября 2011

Мне нужно создать ссылку, которая будет основана на моих критериях поиска.Например:

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

Параметры в этой ссылке являются значениями свойств в моей SearchViewModel.

В идеале я хотел бы иметь что-то в строках:

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

Поддерживается ли это по умолчанию или мне нужно передать свойства моей модели представления в объект типа RouteValueDictionary и затем использовать это?

Моя цель - написать помощник по подкачке, который будет генерировать номера страниц и добавлятьпараметры критериев поиска для сгенерированных ссылок.

Например,

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

11 голосов
/ 14 октября 2011

В идеале я хотел бы иметь что-то вроде:

@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 голос
/ 14 октября 2011

Вот некоторый код, взятый из примеров Tekpub Стива Сандерсона , который в общем то, что вы ищете. Сначала определите метод расширения для вашего объекта -

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())%>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...