2

私はこれを実装しましたhttps://github.com/maartenba/MvcSiteMapProvider/wiki/Defining-sitemap-nodes-using-IDynamicNodeProvider

編集:これは私のクラスです

public class MyDynamicNodeProvider
: DynamicNodeProviderBase
{

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)

    { 
        webdata storeDB = new webdata();

        var returnValue = new List<DynamicNode>();


        foreach (var article in storeDB.SiteContents) 
        {


            DynamicNode enode = new DynamicNode();
            enode.Title = article.ArticleTitle;
            enode.ParentKey = "ArticleID"; 
            enode.Url = "ArticleDetails/" + article.ArticleID + "/" + article.ArticleAlias;
            //Specify Controller and Action name
            enode.Controller = "SiteContents";
            enode.Action = "ArticleDetails";
            enode.RouteValues.Add("id", article.ArticleID);
            returnValue.Add(enode);

            yield return enode;
        }


    }
}

編集:これは私のサイトマップファイルです

 <mvcSiteMapNode title="Home" controller="Home" action="Index">
 <mvcSiteMapNode title="About Us" controller="Menu" action="AboutUs">
 <mvcSiteMapNode title="Profile" controller="Menu"   action="Profile"/>
 <mvcSiteMapNode title="History" controller="Menu" action="History"/>
 </mvcSiteMapNode>
 <mvcSiteMapNode title="Article" controller="SiteContents"  action="ArticleDetails" key="ArticleID"> 
 <mvcSiteMapNode title="Details"  dynamicNodeProvider="Myproject.Models.MyDynamicNodeProvider, Myproject"  />
 </mvcSiteMapNode>

編集:私が持っている2番目のコントローラー(SiteContentsController)

  public ActionResult ArticleDetails(int? id, string slug)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        SiteContents siteContents = db.SiteContents.Find(id);
        if (siteContents == null)
        {
            return HttpNotFound();
        }
        if (string.IsNullOrWhiteSpace(slug))
        {

            var alias = db.SiteContents.First(p => p.ArticleID == id).ArticleAlias;


            return RedirectToAction("ArticleDetails", new { id = id, slug = alias });
        }

        return View(siteContents);
      }

私が持ちたいURL(これは機能しますが、サイトマップは表示されませんhttp://localhost:xxxx/ArticleDetails/1/Quality_Policy

レイアウトページでサイトマップを呼び出します

@Html.MvcSiteMap().SiteMapPath()

編集:私のroute.config

 public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(name: "Articles", url: "ArticleDetails/{id}/{slug}", defaults: new { controller = "SiteContents", action = "ArticleDetails", id = UrlParameter.Optional, slug = UrlParameter.Optional });

        routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}", defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional});


    }

また、問題なく動作する静的ノードもいくつかあります。問題は、動的ページでは何も返されず、エラーメッセージが表示されないことですありがとう

4

1 に答える 1

2

機能しない理由は、すべてのルート値を考慮していないためです。つまり、slug一致するようにノードを構成する必要があるという名前のルート値があります。

slugの値に関係なく(空白であっても)ノードを一致させたい場合は、 を使用PreservedRouteParametersして一致させる必要があります。それ以外の場合は、ノードを追加する必要があり、ノードは構成した1 つのRouteValues値にのみ一致します (必要に応じて、他の値に一致するようにノードを追加できます)。ここでアプローチを示します。PreservedRouteParameters

さらに、Url動的ノードでプロパティを構成することにより、MVC サポートを効果的に無効にしました。このプロパティは、MVC 以外のページまたは外部 URL を使用する必要がある場合に役立ちますが、MVC にはお勧めしません。

MvcSiteMapProviderMVC ルーティング構成に直接依存します。ここで、URL をどのように表示するかを構成します。予想される URL ( http://localhost:xxxx/ArticleDetails/1/Quality_Policy) が機能するには、以下のように、このパターンに一致する対応するルートが必要です。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Route to match the URL /ArticleDetails/1/Quality_Policy
        routes.MapRoute(
            name: "ArticleDetails",
            url: "ArticleDetails/{id}/{slug}",
            defaults: new { controller = "SiteContents", action = "ArticleDetails", slug = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

もう 1 つの問題は、動的ノードを接続するノードです。現在ノードを構成している方法は、アクションに進みますArticleDetails。ここで何をしようとしているのかわかりません。通常、すべての記事ページのリスト (インデックス) を表示し、ユーザーが記事をクリックすると表示します。ここに例があります。

// NOTE: Normally, you would put all of your Article stuff
// into an ArticleController
public class SiteContentsController
{
    // NOTE: Normally, this would be named ArticleController.Index()
    public ActionResult ArticleIndex()
    {
        // NOTE: You may want to use a view model here
        // rather than using the SiteContents directly.
        var siteContents = db.SiteContents.ToList();
        return View(siteContents);
    }

    // NOTE: Normally, this would be named ArticleController.Details()
    public ActionResult ArticleDetails(int? id, string slug)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        SiteContents siteContents = db.SiteContents.Find(id);
        if (siteContents == null)
        {
            return HttpNotFound();
        }
        if (string.IsNullOrWhiteSpace(slug))
        {

            var alias = db.SiteContents.First(p => p.ArticleID == id).ArticleAlias;


            return RedirectToAction("ArticleDetails", new { id = id, slug = alias });
        }

        return View(siteContents);
    }
}

Mvc.sitemapファイルは次のようになります (記事はホームページの下にあります) 。これが主な問題だと思います。XML ファイルにはルート ノードを 1 つだけ含める必要があります (通常、ルート ノードはサイトのホームページです)。

<mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="About Us" controller="Menu" action="AboutUs">
    <mvcSiteMapNode title="Profile" controller="Menu"   action="Profile">
        <mvcSiteMapNode title="Quality Policy" controller="Menu" action="Policy"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="History" controller="Menu" action="History"/>
    <mvcSiteMapNode title="Articles" controller="SiteContents"  action="ArticleIndex" key="Articles"> 
        <mvcSiteMapNode title="Details" dynamicNodeProvider="Myproject.Models.MyDynamicNodeProvider, Myproject"  />
    </mvcSiteMapNode>
</mvcSiteMapNode>

最後に、修正されDynamicNodeProviderた .

public class MyDynamicNodeProvider
    : DynamicNodeProviderBase
{
    public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
    { 
        webdata storeDB = new webdata();

        foreach (var article in storeDB.SiteContents) 
        {
            DynamicNode enode = new DynamicNode();
            enode.Title = article.ArticleTitle;
            enode.ParentKey = "Articles";

            // Don't use the Url property unless you have a 
            // non-MVC page/external URL
            //enode.Url = "ArticleDetails/" + article.ArticleID + "/" + article.ArticleAlias;

            // Specify Controller, Action name, and id.
            // These values all must match the request in order 
            // for the node to be considered the "current" node
            enode.Controller = "SiteContents";
            enode.Action = "ArticleDetails";
            enode.RouteValues.Add("id", article.ArticleID);

            // Match the slug (we don't really care what its value is here)
            enode.PreservedRouteParameters.Add("slug");

            yield return enode;
        }
    }
}
于 2016-02-25T16:03:58.923 に答える