7

動的であるとエラーが発生するリスクがあるため、ViewBagを回避する方法をどのように処理しますか。また、新しいViewModelを設定して、毎回ビューに戻す必要もありません。たとえば、ViewBagに通常詰め込まれている一般的なデータを公開するために、必ずしも以下を変更する必要はありません。

[HttpGet]
void Index() 
{ 
    return View(); 
}

[HttpGet]
void Index() 
{
    var messages = new MessageCollection();
    messages.AddError("Uh oh!");

    return View(messages);
}

パイプラインのどこに、カスタムで強く型付けされたViewBagのようなプロパティを追加しますが、コントローラーとビューでエレガントに公開します。特定のViewModelが常に必要ない場合は、これを実行したいと思います...

[HttpGet]
void Index()
{
    Messages.AddError("Uh oh!");

    return View();
}

そして、ビュー側では、@((IMessageCollection)ViewBag.Messages).Errors idの代わりに、強く型付けされてどこでも利用できる@Messages.Errorsのようなものがあります。また、Razorビューの上部にあるコードブロックにキャストしたくありません。

WebFormsでは、これをベースページに配置し、必要に応じてページに表示または非表示にできるユーザーコントロールを設定するようなことをしていました。コントローラーがビューから切り離されているため、同様の動作を再現する方法がわかりません。

これは可能ですか、それとも最良の設計アプローチは何ですか?

ありがとう、スコット

4

3 に答える 3

10

Razor ビューはかなり単純化されています。厳密に型指定された単一のモデルと対話します。ビューで強く型付けしたいものはすべて、モデル上にある必要があります。モデルに不要なものがある場合、またはそれが 1 回限りのものである場合ViewBagは、すべての非モデル データの汎用キャッチオールとして提供されます。これが動的である理由です。強く型付けされると、キャッチオールになる能力が制限されます。

短くて簡単: 強く型付けしたい場合は、ビュー モデルにメッセージを追加します。それ以外の場合は、そのまま使用してViewBagください。それらはあなたの選択です。

于 2013-03-22T20:58:42.327 に答える
0

ASP.NET MVC では、、、および(詳細については、このブログ投稿ViewBagを参照してください) を自由に使用できます。は辞書の動的ラッパーです。と同等です。ビューでプロパティを使用すると、取得しています。自分で探してください:ViewDataTempDataViewBagViewDataViewBag.Prop = "value"ViewData["Prop"] = "value"ModelViewData.Model

public abstract class WebViewPage<TModel> : WebViewPage
{
    private ViewDataDictionary<TModel> _viewData;
    public new AjaxHelper<TModel> Ajax { get; set; }
    public new HtmlHelper<TModel> Html { get; set; }
    public new TModel Model { get { return ViewData.Model; } }
}

ViewBagまたはのいずれかを使用ViewDataして、あなたの特別なプロパティを保持することで、目的を達成できます。最初のステップは、必要なプロパティを使用して のカスタム派生を作成するWebViewPage<TModel>ことです。

public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel>
{
    public IList<string> Messages 
    { 
        get { return ViewBag.Messages ?? (ViewBag.Messages = new List<string>()); }
    } 
}

@model YourModelClassビューに移動し、行(最初の行) を次のように置き換えます。

@inherits CustomWebViewPage<YourModelClass>

Messagesビューでプロパティを使用できるようになりました。

@String.Join(", ", Messages)

コントローラーで使用するには、おそらくそこからプロパティを派生さControllerせて追加することもできます。

public abstract class CustomControllerBase : Controller
{
    public IList<string> Messages 
    {
        get
        {
            return ViewBag.Messages ?? (ViewBag.Messages = new List<string>());
        }
    } 
}

そのコントローラーから派生する場合は、新しいプロパティを使用できます。リストに入力したものはすべて、ビューでも使用できます。

public class ExampleController : CustomControllerBase
{
    public ActionResult Index()
    {
        Messages.Add("This is a message");
        return View();
    }
}

プロパティのゲッターが短くなったので、ViewBag を使用しました。ViewData必要に応じて ( ) でも同じことができますViewData["Messages"]

これは の実装方法とはまったく同じではありませModelん。保存しているキーを誰かが使用すると誤ってプロパティが上書きされる可能性があるためです。

さらに深く掘り下げると、そこから派生しViewDataDictionaryてそこにプロパティを配置し、代わりにそれを使用するためにコントローラーとビュー メソッドの一部をオーバーライドできる場合があります。次に、プロパティは とまったく同じになりますModel。しかし、それはあなたに任せましょう - 私はそれが価値があるとは思わない.

于 2015-05-11T19:45:59.333 に答える