来自数据库的动态站点地图不显示节点
Dynamic sitemap from database doesn't display the nodes
编辑:这是我的class
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>
编辑:我拥有的第二个控制器 (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});
}
我还有一些工作正常的静态节点。问题是在动态页面 returns 中什么都没有,我没有收到任何错误消息
谢谢
它不起作用的原因是您没有考虑所有路由值,即您有一个名为 slug
的路由值,您需要配置节点以匹配它。
如果你想让节点匹配而不考虑slug
的值(即使它是空白),你应该使用PreservedRouteParameters
来匹配它。否则,您应该将其添加到 RouteValues
并且该节点将仅匹配您为其配置的 one 值(如果需要,您可以添加其他节点以匹配其他值)。我在这里展示 PreservedRouteParameters
方法。
此外,您通过在动态节点上配置 Url
属性 有效地禁用了 MVC 支持。如果您需要使用非 MVC 页面或外部 URL,此 属性 很有用,但不推荐用于 MVC。
MvcSiteMapProvider
直接依赖MVC路由配置。这是您配置 URLs 以查看您希望它们的外观的地方。为了使您预期的 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 }
);
}
}
您遇到的另一个问题是要将动态节点附加到的节点。当前配置节点的方式转到 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 文件中必须只有一个根节点(通常,它是站点的主页)。
<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;
}
}
}
编辑:这是我的class
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>
编辑:我拥有的第二个控制器 (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});
}
我还有一些工作正常的静态节点。问题是在动态页面 returns 中什么都没有,我没有收到任何错误消息 谢谢
它不起作用的原因是您没有考虑所有路由值,即您有一个名为 slug
的路由值,您需要配置节点以匹配它。
如果你想让节点匹配而不考虑slug
的值(即使它是空白),你应该使用PreservedRouteParameters
来匹配它。否则,您应该将其添加到 RouteValues
并且该节点将仅匹配您为其配置的 one 值(如果需要,您可以添加其他节点以匹配其他值)。我在这里展示 PreservedRouteParameters
方法。
此外,您通过在动态节点上配置 Url
属性 有效地禁用了 MVC 支持。如果您需要使用非 MVC 页面或外部 URL,此 属性 很有用,但不推荐用于 MVC。
MvcSiteMapProvider
直接依赖MVC路由配置。这是您配置 URLs 以查看您希望它们的外观的地方。为了使您预期的 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 }
);
}
}
您遇到的另一个问题是要将动态节点附加到的节点。当前配置节点的方式转到 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 文件中必须只有一个根节点(通常,它是站点的主页)。
<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;
}
}
}