デフォルトでは、ASP.NET MVC 3の新しいプロジェクトテンプレートは、デフォルトのレイアウト(かみそりのマスターページ)に以下を追加します。
<title>@ViewBag.Title</title>
たとえば、ビューには、ページのタイトルを割り当てるために次のものが含まれている必要があります。
@{
ViewBag.Title = "Log On";
}
おそらくそれは私の好みですが、ViewBagを使用してタイトルを保持するのが少し間違っていることに気づきました(マジックストリングのフレーバーが多すぎると考えています)。だから私の質問です:これは、ASP.NET MVC 3とかみそり(動的プロパティバッグを使用)を使用している人に推奨されるベストプラクティスですか、それともより強く型付けされたもの(おそらくカスタムベースクラスが関係するもの)を選択していますか?
Asp.net MVC 3に同梱されているデフォルトのタイトル処理機能に問題はないと思います。
私は個人的にこれを(以下に記述して)タイトルを処理するために行います以下のコードを承認していませんまたはデフォルトの機能よりも優れていると言って、それは単なる好みです。
主人
<title>
@RenderSection("Title");
</title>
見る
@section Title
{
write title
}
デフォルトの機能を改善するために提案できることの1つ
@{
string pageTitle = @ViewBag.Title ?? "Title Not Set";
}
<title>@pageTitle</title>
そのため、viewbagに追加するのを忘れると、ページにはtitle = Title Not Set
が表示されます
基本クラスを作成してから、すべてのコントローラーにその基本クラスから継承させることもできます。しかし、私はtitle
に多大な労力を費やしていると思います。
タイトルのViewBagは完全に問題ありません(私はそれがViewBagを持つ目的であるとさえ言います)-動的は絶対的な悪ではありません。 「タイトル」はよく知られており、変更される可能性は低く、ビューテンプレートで事前定義されています。私は次のタイトルを個人的に使用しています。
<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>
ViewBag.Title
の誤入力が心配な場合は、カスタムWebViewPage
を作成することで強い型にすることができますが、厳密に型指定された内部ではViewBag
または多分HttpContext.Items
を使用する必要がありますプロパティは、IIRCのレンダリング中に作成されたWebViewPage
の複数のインスタンスがあるためです。
ViewBag
にこだわって、独自のWebViewPage
を作成することをお勧めします。これはやり過ぎのようです。カスタムWebViewPage
がすでにある場合は、単一のプロパティを作成することもできますただ価値のない複雑さ-そしてそれはしばしば物事を過剰設計している人から来ます。
私もViewBagをまったく使用しません。
_Layout.shtmlの上部...
@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel
_Layout.shtml ...
<title>@Model.Title</title>
あなたのモデルでは...
/// <summary>
/// Index View Model
/// </summary>
public class IndexViewViewModel : EveryPageViewModel {
}
EveryPageViewModel
/// <summary>
/// Every Page View Model
/// </summary>
public abstract class EveryPageViewModel {
/// <summary>
/// Title
/// </summary>
public string Title { get; set; }
/// <summary>
/// Sub Title
/// </summary>
public string SubTitle { get; set; }
}
あなたのコントローラーアクションで
/// <summary>
/// Index
/// </summary>
/// <returns></returns>
public ActionResult Index() {
var model = new IndexViewViewModel();
model.Title = "Home";
return View(model);
}
個々のViewBagを編集するのではなく、PageTitle ActionFilter属性を作成したい
使用法:ビューを同じに保つ
<title>@ViewBag.Title</title>
コントローラ全体のページタイトルの場合:
[PageTitle("Manage Users")]
public class UsersController : Controller {
//actions here
}
個々のビューの場合:
public class UsersController : Controller {
[PageTitle("Edit Users")]
public ActionResult Edit(int id) {
//method here
}
}
属性コード:
public class PageTitleAttribute : ActionFilterAttribute
{
private readonly string _pageTitle;
public PageTitleAttribute(string pageTitle)
{
_pageTitle = pageTitle;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var result = filterContext.Result as ViewResult;
if (result != null)
{
result.ViewBag.Title = _pageTitle;
}
}
}
管理が簡単で、魅力のように機能します。
個人的には、このケースはViewBag
の受け入れ可能な使用法だと思います。 「よく知られている」プロパティに限定されており、将来的に問題が発生することはありません。結局のところ、それは実用的であることと、可能な限り迅速な方法を見つけることがすべてです。タイトルを設定する必要がある基本クラスがあると、私の意見では、タイプセーフに見合うにはコードが多すぎます。
幸運を!
ViewBag.Title = "My Title";の使用に問題はありません。
動的プロパティを使用するだけです。
問題は、情報を「宣言」する場所です。
つまり、手元の目的で最もアクセスしやすい場所です。
ページごとの場合は、それが適切な場所です。
ただし、ページのタイトルをモデルから派生できる場合は、それを行う必要があります。
この場合、おそらく使用するViewModelの基本クラスを使用し、Modelのプロパティからページタイトルを派生させるロジックを含むPageTitleプロパティをそこに作成します。
そう:
<title>Model.PageTitle</title>
要約すると、コース用の馬であり、動的プロパティの使用を恐れないでください。それらが何であり、何をしているのかを理解している限り。
設定したいTitleだけであれば、ViewBagを使用してもかまいません。まあ、それだけではない-せいぜい2-3のプロパティ。
しかし、すべてのコントローラーアクションでますます多くの(共通の)プロパティを設定しているのを見始めたら、強く型付けされた「ViewModelBaseクラス」を使用します。しかし、それは私だけです。
私たちは強いタイトル設定を好みます。BaseControllerクラスからのいくつかのサンプル。 (ページはカプセル化されたビューモーダルを定義します)
protected override ViewResult View(string viewName, string masterName, object model)
{
if (model is Page)
{
ViewBag.Title = ((Page)model).Title;
//HACK: SEO
//TODO: SEO
}
return base.View(viewName, masterName, model);
}