Генерация правильного URL внутри метода HtmlHelper - PullRequest
3 голосов
/ 20 декабря 2011

Я создал грубый метод HTML Helper с целью создания двух ссылок на страницы (Next и Previous).

Ниже приведен код для ViewModel (DTO), передаваемый в метод Helper:

public class PaginationVM
{
    public int TotalItems { get; set; }
    public int ItemsPerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages
    {
        get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
    }
}

А вот код для HTML Helper Method:

public static MvcHtmlString Paginator(this HtmlHelper htmlHelper, PaginationVM pInfo)
{
    StringBuilder result = new StringBuilder();

    var nextPage = pInfo.CurrentPage + 1;
    var prevPage = pInfo.CurrentPage - 1;

    if (pInfo.CurrentPage < pInfo.TotalPages)
    {
        TagBuilder tagA = new TagBuilder("a");
        tagA.MergeAttribute("href", "page/" + nextPage);
        tagA.InnerHtml = "Prev";
        tagA.AddCssClass("prev");
        result.Append(tagA.ToString());
    }
    else
    {
        TagBuilder tagB = new TagBuilder("a");
        tagB.MergeAttribute("href", "page/" + prevPage);
        tagB.InnerHtml = "Next";
        tagB.AddCssClass("next");
        result.Append(tagB.ToString());
    }

    return MvcHtmlString.Create(result.ToString());
}

Кажется, что вышеприведенная комбинация кода работает, но только с домашней страницы, если я нажимаю ссылку Prev [localhost: xxxx / page / 2] и перейдите на страницу 2, затем ссылки станут [localhost: xxxx / page / page / 2].

Моя маршрутизация выглядит следующим образом

routes.MapRoute(
    "PagingPosts/param", // Route name
    "page/{pageId}", // /page/3
    new { controller = "Home", action = "Index", pageId = UrlParameter.Optional }, // Parameter defaults
    new { pageId = @"\d+" } // Constraints: pageId must be numerical
);

Как видите, страница слова теперь продублирована.Я могу придумать, как решить эту проблему, и сказать, что нужно создать ActionLink из корня и создать свой URL таким образом, но я не уверен, как это сделать в помощнике HTML, и чтолучший способ сделать это будет.

Любая помощь будет принята с благодарностью .

Спасибо.

1 Ответ

4 голосов
/ 20 декабря 2011

Хорошим способом является определение помощника, который принимает делегат Func<int, string>, которому можно передать номер страницы и вернуть сгенерированную строку URL. Таким образом, помощник paginator не привязан к какой-либо конкретной маршрутизации и может быть легко повторно использован в вашем приложении.

Что-то вроде

public static MvcHtmlString Paginator(this HtmlHelper htmlHelper, 
                                      PaginationVM pInfo, 
                                      Func<int, string> pageUrl)
{
    StringBuilder result = new StringBuilder();

    if (pInfo.TotalPages > 1)
    {
        TagBuilder tag;

        // previous link
        if (pInfo.CurrentPage > 1)
        {
            tag = new TagBuilder("a");
            tag.MergeAttribute("href", pageUrl(pInfo.CurrentPage - 1));
            tag.AddCssClass("Prev");
            tag.InnerHtml = "previous";

            result.AppendLine(tag.ToString());
        }

        // numbered links
        for (int i = 1; i <= pInfo.TotalPages; i++)
        {
            if (i == pInfo.CurrentPage)
            {
                tag = new TagBuilder("span");
            }
            else 
            {
                tag = new TagBuilder("a");
                tag.MergeAttribute("href", pageUrl(i));
            }

            tag.InnerHtml = i.ToString();

            result.AppendLine(tag.ToString());
        }

        // next page link
        if (pInfo.CurrentPage < pInfo.TotalPages)
        {
            tag = new TagBuilder("a");
            tag.MergeAttribute("href", pageUrl(pInfo.CurrentPage + 1));
            tag.AddCssClass("Next");
            tag.InnerHtml = "next";
            result.AppendLine(tag.ToString());
        }
    }

    return MvcHtmlString.Create(result.ToString());
}

Теперь, на ваш взгляд, вы бы использовали его как

@Html.Paginator(pageInfo, pageId => Url.Action("Index", "Home", new { pageId }))
...