3

ビュー内に if/else のようなロジックを追加しないように求められました。現在、ページのログイン/登録機能を開発しており、ユーザーが役割にある場合は一連のリンクを表示し、役割にある場合は別のリンクを表示する必要があります。別の役割で。

これは私がこれまでに行ったことです:

<ul id="menu">
    <li>@Html.ActionLink("Products", "Books", "Home")</li>
    @if (User.Identity.IsAuthenticated)
    { 
         <li>@Html.ActionLink("Log Out" ,"LogOut","Account")</li>
    }
    else
    {
         <li>@Html.ActionLink("Log In" ,"LogIn","Account")</li>
    }
    @if(User.IsInRole("administrator"))
    {
       <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li>
    }
</ul>

このコードは _Layout.cshtml ファイル内に格納されています。ロジックをビューに追加することは避けたいと思います。

それを行う方法はありますか?

4

3 に答える 3

6

ビューでやりたくない場合は、コントローラーで行う必要があると思います。個々のビューから条件ステートメントを削除するには、次のようにします。

// controller
ActionResult MyAction()
{
    if (!User.Identity.IsAuthenticated)
    {
        ViewBag.MenuControl = "Menu/NotLoggedIn"
    } 
    else if (User.IsInRole("Administrator"))
    {
        ViewBag.MenuControl = "Menu/Administrator"
    } 
    else
    {
        ViewBag.MenuControl = "Menu/LoggedIn"
    }

    ...
}

// view
@Html.Partial(ViewBag.MenuControl);

または、このロジックを多くのビューで共有するには、このロジックを格納するための特定の MenuController を作成することをお勧めします。

ActionResult RenderMenu()
{
    string template;
    if (!User.Identity.IsAuthenticated)
    {
        template = "Menu/NotLoggedIn"
    } 
    else if (User.IsInRole("Administrator"))
    {
        template = "Menu/Administrator"
    } 
    else
    {
        template = "Menu/LoggedIn"
    }

    return View(template);
}

// view
@Html.Action("RenderMenu", "MenuController")

しかし…「ビューロジック」と「コントローラロジック」には大きな違いがあります。結局のところ、これが、MVC アーキテクチャでビューをコントローラーから分離したい主な理由の 1 つです。「ビュー内のすべての条件ステートメントを避ける」のような単純なルールは、MVC の設計方法の要点を本当に見逃しています。

実際には、コントローラーがどのように機能するかよりも、ビューをフォーマットする方法に関係があるため、ビューでこれを行うことを本当に好みます。私はあなたの現在のコードに固執します。

于 2013-03-20T07:37:33.180 に答える
5

if/else私はあなたの見解に声明を出すことに何の問題もないと思います。問題は、実際の条件文自体にあります。

これを例にとってみましょう:

@if(User.IsInRole("administrator"))
{
   <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li>
}

ここでは、ビジネスロジックとビューロジックを組み合わせています。ロールの名前を参照しています。これはビューとは何の関係もありません。これを回避するには、これを試してください:

モデルコード

public class MyModel
{
    public bool IsAdministrator { get; }
}

コントローラコード

myModel.IsAdministrator = User.IsInRole("administrator");

コードを表示

@if(this.Model.IsAdministrator)
{
   <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li>
}
于 2013-03-20T07:47:41.613 に答える
1

MVC の穴のポイントは、責任の領域を分離することです。モデルは完全に独立している必要があります。つまり、モデル自体についてのみ知っている必要があります。モデルにプレゼンテーション関連のロジックを含めることは、ビジネス ロジックと混合しない限り、ごく普通のことです。あなたの例では、明らかな改善は、すべての承認情報をモデル オブジェクトに移動し、if/else ロジックを表示したままにすることです。

コントローラ:

model.IsAuthenticated = User.Identity.IsAuthenticated;
model.IsAdministrator = User.IsInRole("administrator");
于 2013-03-20T08:26:24.870 に答える