2009-04-23 65 views
0

我有其中有一個功能叫GetSiteMap()母版頁,此功能用於定製呈現基於當前位置的地圖。我的問題是,在MVC中,你沒有模型背後的代碼,因此沒有公開這種功能。ASP.NET 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 

對不起,這就是我的意思。我前幾天寫得很快,所以它不完美,但現在它完成了這項工作。我使用的是站點地圖,並給出了某些元素沒有網址,而是使用「分隔符」等描述來指示<li>元素以不同的方式呈現(將不同的類應用於此HTML元素)。

回答

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 
} 
1

這取決於它的功能;如果它只是檢查請求,那麼你可以在HtmlHelper上編寫(例如)擴展方法並從視圖中寫入;

<%=Html.GetSiteMap()%> 

另一種選擇是將其推送到母版頁。如果您需要執行數據庫查詢等,則可以考慮使用「操作過濾器」來完成一半的工作(準備數據),然後(如上所述)在視圖中調用HtmlHelper以顯示它。有用嗎?

+0

啊是的,我還沒有實施任何幫手。可能性是它會觸發數據庫查詢的權限。我還不確定。它實際上只是輸出一些HTML。我很快就會對HTML助手產生興趣。 – Kezzer 2009-04-23 11:53:15

+0

我會重構它,以便它不會生成HTML。在MVC中,這最好留給視圖,而不是控制器操作。 HtmlHelpers應該對控制器提供的數據進行操作,而不是進行數據庫查詢。如果您將DB訪問權限構建到幫助程序中,您將會破壞關注點。 – tvanfosson 2009-04-23 12:07:50

0

MVC確實有強類型的意見。從您的標記,你可以訪問你的模型來確定位置,其basicly替換代碼隱藏的邏輯:

<%= Html.Encode(ViewData.Model.GetSiteMap()) %> 

這會使相應的地圖。你的模型可能是一個'主表達'類,它揭示了網頁常用的不同方法。

我想這是類似於馬克提出的解決方案。

0

我的問題是,在MVC你不 有模型背後的代碼因此不是 揭露那種功能

這是不正確的。 aspx +後面的代碼是默認實現,直到很少發佈之前。目前,默認模板沒有使用後面的代碼,但在運行時內置。

在MVC控制器應該創建您的站點地圖的模型和視圖(也許一個用戶控件)有唯一的責任來呈現它。

也許這可以幫助http://mvcsitemap.codeplex.com/