3

すべてのビューがレンダリングされるマスター レイアウト ファイルがあります。次のルールを使用して、このレイアウトの特定の領域でユーザーにメッセージを表示したいと考えています。

  1. メンテナンス期間中、ユーザーがサインインした後、すべてのページに警告を表示します。
  2. メンテナンス期間が近づくと、ユーザーがサインインした後にすべてのページに警告を表示します (ただし、#1 とは異なる内容で)
  3. 通常の期間中、サインイン時にのみメッセージを表示し、それ以降のページではメッセージを表示しません
  4. 他のビュー/コントローラーからこの領域に追加のメッセージを追加したい可能性がありますが、メンテナンス警告が重複しているかどうかを意識する必要はありません

私はこれを行う正しい方法に本当に苦労しています。今、私は次のようなものを持っています:

public class LayoutController : Controller
{
    [ChildActionOnly]
    public IHtmlString GetMarginMessages() {
        loadMaintenanceMessages();
        var messages = this.ViewBag.MarginMessages.ToSingleString();
        return new HtmlString(messages);
    }

    private List<string> loadMaintenanceMessages() {
        if (withinMaintenancePeriod)
        {
            this.ViewBag.MarginMessages.Add("foo");
        } 
        else if (nearMaintenancePeriod) {
            this.ViewBag.MarginMessages.Add("bar");
        }
    }
}

次に、私のレイアウトでは次のことができます。

<div id="marginMessage">@Html.Action("GetMarginMessages")</div>

他のページまたはコントローラーでは、次のものを使用できます。

this.ViewBag.MarginMessages.Add("Something")    // or have it go through a helper of sorts

これはこれについて考える正しい方法ですか?ViewBag を使用することに興奮していませんが、ビュー間/コントローラー共有を管理するためのより良い方法がわかりません。また、ビューのレンダリングごとにメンテナンス期間のチェックを行うのも、あまり適切ではありません。

私が見逃している他のオプションは何ですか?

4

3 に答える 3

4

このために、別のアクションをレンダリングするセクションをマスター レイアウト ビューに作成します。何かのようなもの

(page stuff...)
<div id="marginMessages>
    Html.Action("GetMarginMessages", "Infrastructure")
</div>
(more page stuff...)

InfrastructureControllerマージンメッセージ、通知メッセージなどの分野横断的な問題を処理するコントローラーとして持っています。そのコントローラーには、GetMarginMessagesメッセージを表示する必要があるかどうかを判断するメソッドがあり、表示する必要がある場合は、必要に応じてレンダリングされたメッセージを含む部分ビューを返します。メッセージがない場合は返される可能性があるため、が空EmptyResultのときにページが正常に表示されることを確認する必要があります。div

より複雑なロジックの場合は、コントローラ メソッドの後 ( ) またはビューのレンダリング前 ( ) にActionFilterAttributeリクエストをキャッチする、から派生したアクション フィルタを作成できます。(理論的には、どちらを使用しても大した問題ではありません。)OnActionExecuted()OnResultExecuting()

そこから、次の目的で使用できますfilterContext

  • ユーザーがヒットしたコントローラーのメソッドとアクションを確認する
  • コントローラーがモデルに入力した値を確認しますViewBagTempData
  • モデル内の値の追加/削除/変更、、ViewBagおよびTempData

したがって、そこから値を設定して、メッセージをレンダリングする部分ビューが何をする必要があるかを伝えることができるはずです。部分ビューはこれらの値を取得し、必要に応じて使用できます (使用する前に、すべてのものを null チェックすることを忘れないでください)。

設定が完了すると、このアクション フィルターを次の対象に適用できます。

  • すべてのメソッド、メソッドのに追加するGlobalFilterCollectionことApplication_Start()Global.asax.cs
  • public class MyController : Controllerコントローラーのファイルの行の上に追加することにより、コントローラー全体
  • そのメソッドの上に追加することにより、特定のメソッド

そしてもちろん、これらの場所のどこでも、値をコンストラクターに渡すことができ、フィルターにロジックを設定して、どれがどれをオーバーライドするかを判断できます。

于 2013-08-08T16:18:28.837 に答える
0

別の簡単なオプション (どれだけ複雑にする必要があるかによって異なります) は、MVC のセクションを使用することです。

http://www.c-sharpcorner.com/UploadFile/3d39b4/Asp-Net-mvc-4-layout-and-section-in-razor/

レイアウト ビューでは、セクションを参照できます。

@RenderSection("featured", required: false)

次に、任意のビューで、この要素の中に何を入れるかを選択できます。

@section featured
{
    <!--Whatever you would like in here-->
    <h1>@ViewBag.Title.</h1>                 
}

次に、それを必要としないビューについては、セクション定義を含めないでください。

また、複数のビューが同じセクション コンテンツを使用する場合、次のコンテンツのみの子レイアウトを使用できます。

  • メイン レイアウトの参照
  • セクションの定義 (複数のビューに対して 1 回定義するだけで済みます)
于 2015-04-20T20:35:17.733 に答える