我有一个主页,其中有一个名为GetSiteMap()
的函数,此函数用于根据当前位置自定义呈现站点地图。我的问题是,在MVC中,你没有模型背后的代码,因此不会暴露这种功能。
这样做的正确方法是什么?我是否应该使用其中定义的功能的某种母版页控制器?
Public Function GetSitemap() As String
Dim s As New SiteNavigation
Dim siteMapNodeCollection As SiteMapNodeCollection
If Not SiteMap.CurrentNode.Equals(SiteMap.RootNode) Then
If Not SiteMap.CurrentNode.HasChildNodes Then
' otherwise it'll go to the pseudo-current directory, which is wrong
Dim parentNode As SiteMapNode = SiteMap.CurrentNode.ParentNode.ParentNode
s.AddBackLink(parentNode.Url, parentNode.Title)
Else
Dim parentNode As SiteMapNode = SiteMap.CurrentNode.ParentNode
s.AddBackLink(parentNode.Url, parentNode.Title)
End If
End If
If Not SiteMap.CurrentNode.HasChildNodes Then
siteMapNodeCollection = SiteMap.CurrentNode.ParentNode.ChildNodes
Else
siteMapNodeCollection = SiteMap.CurrentNode.ChildNodes
End If
For Each siteMapNode As SiteMapNode In siteMapNodeCollection
GenerateLinks(siteMapNode, s)
Next
Return s.GetSiteNavigation()
End Function
Private Sub GenerateLinks(ByRef siteMapNode As SiteMapNode, ByRef siteNavigation As SiteNavigation)
If siteMapNode.Url.Length = 0 And siteMapNode.Description = "separator" Then
siteNavigation.AddSeparator()
ElseIf siteMapNode.Url.Length = 0 And siteMapNode.Description = "heading" Then
siteNavigation.AddHeading(siteMapNode.Title)
Else
siteNavigation.AddLink(siteMapNode.Url, siteMapNode.Description, siteMapNode.Title, siteMapNode.HasChildNodes)
End If
End Sub
对不起,这就是我的意思。我前几天很快写了这篇文章,所以它并不完美,但现在它完成了这项工作。我正在使用站点地图并且给某些元素没有URL,而是使用诸如“separator”之类的描述来指示<li>
元素以不同的方式呈现(不同的类应用于此HTML元素)。
答案 0 :(得分:1)
这取决于它的作用;如果它只是检查请求,那么您可以在HtmlHelper
上编写(例如)扩展方法并从视图中写入;
<%=Html.GetSiteMap()%>
另一种选择是将其推入母版页。如果您需要进行数据库查询等,可以考虑使用“操作过滤器”来完成一半工作(准备数据),然后(如上所述)在视图中调用HtmlHelper
以显示它。有用吗?
答案 1 :(得分:1)
由于站点地图可以根据用户的位置进行自定义,因此我假设您正在考虑生成用户界面元素,而不是搜索引擎映射。为搜索引擎消费生成站点地图最好离线完成,并且只需定期更新。
要生成用户界面,我会考虑使用ViewUserControl并将其渲染为您需要的任何页面中的部分。 ViewUserControl将使创建和维护与之关联的标记变得更加容易。它也可用于任何需要它的视图(并且可以包含在您的MasterPage中)。正如@Marc Gravell建议的那样,可以使用ActionFilter生成数据。但是,如果控件无处不在,可以创建一个基本控制器,控制器可以从中导出并覆盖基本控制器中的OnActionExecuted,这可能是最简单的。您可以检测何时生成ViewResult,然后创建并为ViewData分配站点地图控件的数据。
基础控制器:
public override OnActionExecuted( ActionExecutedContext filterContext )
{
if (filterContext != null && filterContext.Result is ViewResult)
{
ViewData["siteMap"] = this.GetSiteMap();
}
}
母版/查看
<% Html.RenderPartial( "SiteMap", ViewData["siteMap"], ViewData ) %>
ViewUserControl
foreach (var elem in Model)
{
.... render your HTML
}
答案 2 :(得分:0)
MVC确实有强类型视图。从您的标记中,您可以访问您的模型以确定基本上替换代码隐藏逻辑的位置:
<%= Html.Encode(ViewData.Model.GetSiteMap()) %>
将呈现相应的站点地图。您的模型可以是“主要演示文稿”类,它公开页面常用的不同方法。
我想这与Marc提出的解决方案类似。
答案 3 :(得分:0)
我的问题是在MVC中你没有 因此没有模型背后的代码 暴露这种功能
那不是真的。 aspx + code behind是默认实现,直到很久以前才发布。目前,默认模板不使用代码,但内置于运行时。
在MVC中,Controller应该创建站点地图的模型,而View(可能是用户控件)只负责渲染它。