문제

Web.Sitemap에서 "대략적인"일치와 일치하고 싶습니다.

Web.sitemap 정적 사이트 맵 제공 업체는 한 가지를 제외하고 잘 작동합니다. 정적입니다!

따라서 내 페이지의 10,000 개의 기사 각각에 대한 SiteemapNode가 있어야한다면 다음과 같습니다.

  • site.com/articles/1/article-title
  • site.com/articles/2/another-article-title
  • site.com/articles/3/another-article-again
  • ...
  • site.com/articles/9999/the-rast-article

기사 아래에있는 일에 맞게 사이트 맵으로 할 수있는 야생 카드 매핑이 있습니까?

아니면 내 WebForms 페이지에 현재 노드를 수동으로 설정하는 방법이 있습니까?

나는 "비트"의 도움을 찾았습니다 이 페이지 ASP.NET MVC 프레임 워크 에서이 작업을 수행 할 때 여전히 WebForms를위한 좋은 솔루션을 찾고 있습니다.

내가해야 할 일은 사용자 정의 사이트 맵 제공 업체를 만드는 것입니다.

도움이 되었습니까?

해결책

이것은 위의 의견에 대한 응답입니다. 전체 코드를 게시 할 수는 없지만 기본적으로 제공자가 작동하는 방식입니다.

페이지 article.aspx가 있다고 가정하고 쿼리 문자열 매개 변수 "ID"를 사용하여 기사 제목과 본문을 검색하고 표시합니다. 그런 다음 이것은 web.sitemap에 있습니다.

<siteMapNode url="/article.aspx" title="(this will be replaced)" param="id" />

그런 다음이 수업을 만듭니다.

public class DynamicSiteMapPath : SiteMapPath
{
  protected override void InitializeItem(SiteMapNodeItem item)
  {
    if (item.ItemType != SiteMapNodeItemType.PathSeparator)
    {
      string url = item.SiteMapNode.Url;
      string param = item.SiteMapNode["param"];

      // get parameter value
      int id = System.Web.HttpContext.Current.Request.QueryString[param];

      // retrieve article from database using id
      <write your own code>

      // override node link
      HyperLink link = new HyperLink();
      link.NavigateUrl = url + "?" + param + "=" + id.ToString();
      link.Text = <the article title from the database>;
      link.ToolTip = <the article title from the database>;
      item.Controls.Add(link);
    }
    else
    {
      // if current node is a separator, initialize as usual
      base.InitializeItem(item);
    }
  }
}

마지막으로, 정적 제공 업체를 사용하는 것처럼 코드 에서이 공급자를 사용합니다.

<mycontrols:DynamicSiteMapPath ID="dsmpMain" runat="server" />

내 수업은 이것보다 더 복잡하지만 이것들은 기본입니다. QueryString 매개 변수를 사용하는 대신 사용중인 우호적 인 URL을 분석하여 올바른 컨텐츠를 검색하는 데 사용할 수 있습니다. 모든 요청마다 추가 DB 조회를 최소화하려면 제공 업체에 캐싱 메커니즘을 추가 할 수 있습니다 (기사 제목은 일반적으로 자주 변경되지 않습니다).

도움이 되었기를 바랍니다.

다른 팁

이것은 내가 생각하는 당신의 질문에 대한 대답은 아니지만 아마도 당신에게 아이디어를 줄 수 있습니다. 한 번은 DynamicSitemAppath 클래스를 상속받는 SetemAppath를 작성했습니다. 각각에 사용자 정의 속성을 사용합니다 <siteMapNode> Web.sitemap에서 태그 : 다음과 같습니다.

<siteMapNode url="dynamicpage.aspx" title="blah" params="id" />

그런 다음 DynamicSitemAppath 클래스는 "ID"매개 변수 값을 가져오고 데이터베이스에서 컨텐츠를 검색하며 현재 렌더링 된 SiteMap 항목 노드를 올바른 제목 및 링크로 무시합니다. 약간의 작업이 필요하지만 올바르게 수행하면 동적 페이지 지원을 제공하는 매우 깔끔한 방법입니다.

나는이 문제에 빠졌고 솔직히, 나를 행복하게하는 솔루션을 찾지 못했습니다 ... 그래서 나는 여기저기서 아이디어를 빌 렸습니다. 내 솔루션은 멀티 부문입니다. a) SiteemApprovider가 실제 페이지를 찾아 요청을 처리하고 노드를 사용하고 b) 표준 기술을 사용하여 사이트에서 사이트를 업데이트하십시오.

a) 내가 계속 실행 한 문제는 올바른 가상 경로가 없다면 Sitemap.currentNode가 NULL이고 SiteMapResolve 기능의 화재가된다는 것입니다. 이것을 해결하려면 XMLSITEMAPPROVIDER를 하위 클래스하고 CurrentNode를 무시합니다.

 namespace WebFormTools
{
    class RouteBaseSitemapProvider : XmlSiteMapProvider
    {
        public override SiteMapNode CurrentNode
        {
            get
            {
                var node = base.CurrentNode;


                if (node == null) 
                {
                    // we don't have a node, see if this is from a route
                    var page = HttpContext.Current.CurrentHandler as System.Web.UI.Page;

                    if (page != null && page.RouteData != null)
                    {
                        // try and get the Virtual path associated with this route
                        var handler = page.RouteData.RouteHandler as PageRouteHandler;

                        if (handler != null) {
                            // try and find that path instead.
                            node = FindSiteMapNode(handler.VirtualPath);
                        }
                    }

                }

                return node;
            }
        }
    }
}

기본적으로 기본 구현에 아무것도 찾지 못하면 경로를 찾아서 (있는 경우) 핸들러의 가상 경로를 사용하여 노드를 찾으십시오.

참조는 여기 내 web.config, global.asax 및 siteemap 파일의 일부입니다.

제공자 추가

    <siteMap defaultProvider="RouteBaseSitemapProvider">
  <providers>
    <add name="RouteBaseSitemapProvider" type="WebFormTools.RouteBaseSitemapProvider" siteMapFile="Web.sitemap" />
  </providers>
</siteMap>

경로:

            routes.MapPageRoute("EvalRoutes",
            "Evals/{type}/New.aspx",
            "~/Evals/New.aspx");

그리고 사이트 맵 :

        <siteMapNode url="~/Evals/New.aspx" title="New Eval - {type}"  description="" />

b) I 서브 클래스 System.web.ui.page, 적절하게 이름이 지정된 BaseClass는 SiteemapResolve 이벤트에 핸들러를 등록하는 메소드를 추가합니다.

public System.Web.SiteMapNode Process(System.Web.SiteMapNode currentNode)
    {
        if (currentNode == null) return currentNode;

        var page = HttpContext.Current.CurrentHandler as System.Web.UI.Page;

        if (page != null && page.RouteData != null)
        {

            Dictionary<Regex, string> replacements = new Dictionary<Regex, string>();

            // build a list of RegEx to aid in converstion, using RegEx so I can ignore class.  Technically I could also
            foreach (var key in page.RouteData.Values.Keys)
            {
                replacements.Add(new Regex(string.Format("\\{{{0}\\}}", key), RegexOptions.IgnoreCase), page.RouteData.Values[key].ToString());              
            }


            // navigate up the nodes
            var activeNode = currentNode;
            while (activeNode != null)
            {
                // to the replacements
                foreach(var replacement in replacements)
                {
                    activeNode.Title =  replacement.Key.Replace(activeNode.Title, replacement.Value);
                }

                activeNode = activeNode.ParentNode;
            }

        }

        return currentNode;
    }

여전히 URLS 맵을 적절하게 가져와야합니다 (경로를 수신하는 페이지의 URL을 사용합니다). 아마도 사이트 맵에서 사용자 정의 속성을 사용하여 노드에 URL을 렌더링하는 방법을 알려줄 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top