user212218
user212218

Reputation:

DataPager controls use Sitecore layout URL instead of item URL

To implement a search results page on a Sitecore 6.3.1 site, I created a content item at /sitecore/content/Home/Search and added a Search Results sublayout to its presentation controls. The sublayout uses a ListView to display the search results and a DataPager to handle pagination.

Here is an excerpt from Search Results.ascx:

<asp:ListView ID="SearchResults" runat="server">
  <LayoutTemplate>
    <asp:DataPager ID="Pager" QueryStringField="page" runat="server">
      <Fields>
        <asp:NumericPagerField ButtonCount="10" />
      </Fields>
    </asp:DataPager>

    <asp:Placeholder ID="itemPlaceholder" runat="server" />
  </LayoutTemplate>

  ...
</asp:ListView>

Note that the DataPager's QueryStringField parameter is set to a non-empty value.

When the sublayout is rendered, the search results and pagination controls appear correctly. However, the pagination hyperlinks go to the wrong URL. Instead of going to the page URL, they link to the layout's URL.

For example, if the user clicks on the link for page 2, one would expect his browser to go to e.g., http://www.example.com/Search.aspx?query=xyz&page=2. But his browser actually links to http://www.example.com/layouts/Generic%20Browser%20Layout.aspx?query=xyz&page=2.

Where is the DataPager getting the bogus URL, and how do I fix this?

Upvotes: 2

Views: 936

Answers (2)

user212218
user212218

Reputation:

Here's the solution I ultimately went with. It's not pretty, but it does work:

/// <summary>
///   Fixes any HyperLinks that point to the layout .aspx file to point to
///     the Sitecore context item.
/// </summary>
/// <param name="control">
///   The control to fix (its child controls will be processed).
/// </param>
protected void FixLayoutHyperLinks(Control control)
{
  var currentPath = LinkManager.GetItemUrl(Sitecore.Context.Item);
  foreach (Control c in control.Controls)
  {
    foreach (Control d in c.Controls)
    {
      if (d is HyperLink)
      {
        var link = (HyperLink)d;

        /* Change just the path of the existing URL.
         * @see http://stackoverflow.com/questions/5276324/modifying-just-the-path-part-of-a-hyperlinks-navigateurl-in-c/5276375#5276375
         */
        var url = new UriBuilder(Request.Url.Host + link.NavigateUrl);
        url.Path = currentPath;

        /* For consistency (and because ASP.Net will strip the leading
         *  "http://" during PreRender), do not add the hostname/schema to
         *  the resulting URI.
         * 
         * @see http://sobot-software.blogspot.com/2009/02/asphyperlink-navigateurl-problem.html
         */
        link.NavigateUrl = url.Uri.PathAndQuery;
      }
    }
  }
}

I use it like so:

private void Page_Load(object sender, EventArgs e)
{
  ...

  var Pager = MyListView.FindControl("Pager") as DataPager;
  FixLayoutHyperLinks(Pager);
}

Upvotes: 0

Holger
Holger

Reputation: 2271

I'm think it's because DataPager just uses standard asp.net URLs and doesn't know about Sitecore or the way Sitecore creates URLs.

I think you are gonna have to do this in another way (a simple repeater) or create a DataPager that uses Sitecore.Links.LinkManager.GetItemUrl(Sitecore.Context.Item); for the basis of the links.

Upvotes: 0

Related Questions