2017-04-11 9 views
1

うまくいけば私は自分自身を明確にしています。私は2つの共有レイアウトを持つ私のmvcプロジェクト内の領域を持っています _Application.cshtml(エリア用)_Layout.cshtml(エリア用以外)MVCのエリアと共有レイアウト

レポートとお気に入りはエリアコントローラ向けです。
デフォルトの名前空間コントローラ用の役割とユーザーです。

<li>@Html.ActionLink("Reports", "Reports", "Home")</li> 
<li>@Html.ActionLink("Favourites", "Favourites", "Home")</li> 
<li>@Html.ActionLink("System Roles", "Roles", "Support",new { Area = "" }, htmlAttributes: new { title = "System Roles" }) </li> 
<li>@Html.ActionLink("Users", "Users", "Support", new { Area = "" }, htmlAttributes: new { title = "Users" })</li> 

私は別の共有レイアウトを定義しています。レポートやお気に入りへのリンクはありません(まったく別のナビゲーションメニュー)。

デフォルトの名前空間コントローラからアクションを呼び出す機能を失うことなく、_Application共有レイアウトにロールとユーザーのレイアウトを割り当てることはできますか?

if (this.ViewContext.RouteData.DataTokens["Area"] != null) { 
    Layout = "~/Views/Shared/_Application.cshtml"; 
} 
else 
{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

私はこれを試しましたが、定義されていないため、DataTokenはエリアルートを受信しません。

編集:申し訳ありませんが、私はトラブルの問題を記述したのです(あまりにも、同僚との...)

エリア「調達」:コントローラは:「ホーム」は、3つのビューインデックス、レポートとお気に入りを持っています。ナビゲーションメニュー(_Applicaiton.cshtml)は調達エリア専用です

エリア:コントローラー "サポート"には2つのビューロールとユーザーがあります。ナビゲーションメニュー(_Layout.cshtml)には、プロジェクトの他のエリアにナビゲートするリンクが含まれています。

上記のアクションリンクは、インデックスビューにあります。 ReportsまたはFavoritesをクリックすると、ApplicationName/Procurement/Home/ReportsまたはApplicationName/Procurement/Home/Favoritesに移動します。

をクリックすると、ApplicationName/Support/RolesまたはApplicationNameに移動します。/SupportUsers

ロールとユーザーのレイアウトをどのように定義したかによって、ナビゲーションメニューはProcurement Areaに固有のものを表示するのではなく、一般的なものに戻ります。

ナビゲーション・メニューの「ロール」または「ユーザー」をクリックして調達レイアウトに留まり、同じサポート・コントローラーを参照することが可能かどうかを調べたいと考えています。私は作成している各エリアのロールとユーザーページを作成する必要はありません。

答えて

0

伝統的にはDataTokensではなくViewContext.RouteData.Values["key"]を使用します。違いがあるかどうかわからないまた、私はキーが "エリア"ではなく "エリア"だと思う。辞書のキーでは大文字と小文字が区別されるので、これが問題になる可能性があります。

EDIT

わかりました。私はもう少し理解できるかもしれないと思う。必要な機能を実現するには、調達領域にロール機能とユーザー機能を再実装する必要があります。しかし、それだけでコードをコピーする必要はありません。適切なビューでロードするために、ビューの規則に頼ることができます。たとえば、ロールビューをViews\Sharedに移動すると、Razorは異なるコントローラまたはエリアでそのビューを検索するときに見つけられます。Views\Sharedは常に最終結果パスです。アクション自体については、実際にはコードを繰り返すのではなく、コントローラの継承を利用して1つ以上の異なる領域に同じコントローラ/アクションを実装することができます。

+0

「エリア」の小文字は正しいですか。しかし、私はこのアプローチが私にとってはうまくいくとは思わない。私はActionLinkでAreaを定義しません。これは、デフォルトの名前空間コントローラ内のアクションであり、キーが決して設定されないようにするためです... – foop

+0

本質的に、私はRoleとUserのビューとアクションをプロジェクト。しかし、私はユーザーに再利用されたビューやアクションのための特定のエリアを残さないという経験を与えたいと思っています。 – foop

+0

'_Application.cshtml'は' _Layout.cshtml'から継承していますか? –

2

一部の領域に特定のレイアウトを使用する場合は、単純な解決策があります。

_ViewStartファイルを使用して、各領域で使用するレイアウトを指定します。

~/Views/_ViewStart.cshtmlファイル:

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

~/Areas/Xxx/Views/_ViewStart.cshtmlファイル:

@{ 
    Layout = "~/Views/Shared/_LayoutXxx.cshtml"; 
} 

あなたが読むことができるASP.NET MVC 3: Layouts with Razor

がViewStartを聞かせするために、ビューからLayout = "..."宣言を削除することを忘れないでください その仕事をしなさい。

+0

しかし、私が参照しているビューは、その特定のエリアには存在しません。 – foop

+0

あなたからのご連絡は難しいです。あなたは、あなたが持っているさまざまなケース(どのロール、どのユーザープロパティ、どのURL、どのURL)で起こりたいもののリストを私たちに与えることができますか? – SandRock

0

ビューを使用して条件付きでドライブしたい場合は、ビューエンジンから継承することができます。は、リクエストごとにビューの位置をオーバーライドします

This postは、異なる静止画解像度パターンを示しています。

ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)メソッドをオーバーライドして、特定のリクエストに対して使用可能なビューをカスタマイズできます。 controllerContextオブジェクトを使用すると、正しいビューを返すことができるように、ユーザーとそのロールを見つけることができます。

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
{ 
    if (/* user has role X */) 
    { 
     return new ViewEngineResult(new string[] { "Some View.cshtml" }); 
    } 

    return base.FindView(controllerContext, viewName, masterName, useCache); 
} 

This article古典的なビューエンジンから継承して宣言する方法を示します。 This articleは、カスタムViewEngineでリクエストオブジェクトを使用して、ユーザーの役割に応じてビューを選択する方法を示しています。

関連する問題