2009-04-23 25 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 

申し訳ありませんが、これは私が言ったことです。先日私はこれを非常に素早く書きましたので、完璧ではありませんが、今は仕事をしています。私はサイトマップを使用していて、特定の要素にURLはなく、代わりに<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 
} 
+0

どこにGetSiteMap()を持っているコードは行くべきですか?それはSiteMapを表すカスタムクラスを使用します。 – Kezzer

+0

コードはベースコントローラー自体に含まれる可能性があります。これは私の例で示したものです。サイトマップは、実際にはMVCアプリケーションのコントローラアクションの関数なので、私はコントローラとそれを保持すると思います。モデルにSiteMapを表すクラスを配置します。 – tvanfosson

1

これは機能によって異なります。要求を調べているだけの場合は、例えばHtmlHelperに拡張メソッドを書いてビューから書き込むことができます。

<%=Html.GetSiteMap()%> 

もう1つの選択肢は、これをマスターページにプッシュすることです。データベースクエリなどを行う必要がある場合は、作業の半分(データの準備)を行い、次に(上のように)表示されるビュー内のHtmlHelperの呼び出しを行う「アクションフィルタ」を検討することができます。どんな使い方ですか?

+0

はい、まだヘルパーは実装されていません。可能性は、アクセス許可のデータベースクエリを実行する可能性があります。私はちょうどまだわからない。とにかくそのまま文字通りHTMLを出力します。私はすぐにHTMLヘルパーにbashを持っていきます。 – Kezzer

+0

私はそれがHTMLを生成しないようにリファクタリングします。 MVCでは、これは実際にはコントローラの操作ではなく、ビューに残すのが最も良い方法です。 HtmlHelpersは、コントローラから提供されたデータを操作して、データベースのクエリを行わないでください。あなたはあなたのヘルパーにDBアクセスを構築する場合、懸念の分離を破るでしょう。 – tvanfosson

0

MVCに厳密に型指定されたビューがあります。適切なサイトマップをレンダリングします

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

:あなたのマークアップからは、basicly分離コードロジックを置き換える位置を決定するために、あなたのモデルにアクセスすることができます。モデルは、ページでよく使用されるさまざまなメソッドを公開する「マスタープレゼンテーション」クラスにすることができます。

これはMarcの提案されているソリューションに似ていると思います。

0

私の問題は、MVCであなたが はモデルの背後にあるコードを持っていないということですしたがって、 その種の機能を公開する

これは正しくありません。 aspx +コードの背後には、数少ないリリース前のデフォルトの実装がありました。現在、のデフォルトテンプレートはコードを使用しませんが、ランタイムに組み込まれています。

MVCでは、コントローラはサイトマップのモデルを作成する必要があり、ビュー(多分ユーザーコントロール)はそれをレンダリングする唯一の責任を持ちます。

これは役に立ちます。

関連する問題