我有使用Razor引擎的MVC 3 C#項目。有什麼方法,我猜,將動態數據寫入_Layout.cshtml的最佳實踐是什麼?如何在MVC 3 Razor中將動態數據寫入頁面佈局?
例如,也許我想在我的網站的右上角顯示用戶的名字,這個名字就是從會議,DB,或任何基於中記錄哪些用戶的到來。
謝謝您。
更新:我還在尋找將某些數據呈現到佈局元素的良好做法。例如,如果我需要根據登錄用戶的憑據來呈現特定的CSS文件。
(對於上面的例子,我想使用URL傭工)
我有使用Razor引擎的MVC 3 C#項目。有什麼方法,我猜,將動態數據寫入_Layout.cshtml的最佳實踐是什麼?如何在MVC 3 Razor中將動態數據寫入頁面佈局?
例如,也許我想在我的網站的右上角顯示用戶的名字,這個名字就是從會議,DB,或任何基於中記錄哪些用戶的到來。
謝謝您。
更新:我還在尋找將某些數據呈現到佈局元素的良好做法。例如,如果我需要根據登錄用戶的憑據來呈現特定的CSS文件。
(對於上面的例子,我想使用URL傭工)
Visual Studio創建默認的Internet應用程序中使用_LogOnPartial.cshtml做的正是這一點。
用戶名值在HomeController的
代碼的登錄操作設置_LogOnPartial.cshtml
@if(Request.IsAuthenticated) {
<text>Welcome <strong>@User.Identity.Name</strong>!
[ @Html.ActionLink("Log Off", "LogOff", "Account") ]</text>
}
else {
@:[ @Html.ActionLink("Log On", "LogOn", "Account") ]
}
User.Identity是ASPNET會員提供商。
代碼爲_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>Test</h1>
</div>
<div id="logindisplay">
@Html.Partial("_LogOnPartial")
</div>
<nav>
<ul id="menu">
</ul>
</nav>
</header>
<section id="main">
@RenderBody()
</section>
<footer>
</footer>
</div>
</body>
</html>
代碼爲的AccountController登錄行動
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
代碼ApplicationViewPage類
public abstract class ApplicationViewPage<T> : WebViewPage<T>
{
protected override void InitializePage()
{
SetViewBagDefaultProperties();
base.InitializePage();
}
private void SetViewBagDefaultProperties()
{
ViewBag.LayoutModel = new LayoutModel(Request.ServerVariables["SERVER_NAME"]);
}
}
上面的代碼讓我有一個ViewBag .LayoutModel在每個頁面中保存我的LayoutModel類的一個實例。
這裏是我的LayoutModel類
public class LayoutModel
{
public string LayoutFile { get; set; }
public string IpsTop { get; set; }
public string IpsBottom { get; set; }
public string ProfileTop { get; set; }
public string ProfileBottom { get; set; }
public LayoutModel(string hostname)
{
switch (hostname.ToLower())
{
default:
LayoutFile = "~/Views/Shared/_BnlLayout.cshtml";
IpsBottom = "~/Template/_BnlIpsBottom.cshtml";
IpsTop = "~/Template/_BnlTop.cshtml";
ProfileTop = "~/Template/_BnlProfileTop.cshtml";
break;
case "something.com":
LayoutFile = "~/Views/Shared/_Layout.cshtml";
IpsBottom = "~/Template/_somethingBottom.cshtml";
IpsTop = "~/Template/_somethingTop.cshtml";
ProfileTop = "~/Template/_somethingProfileTop.cshtml";
break;
}
}
}
代碼下面是代碼來查看
@{
ViewBag.Title = "PageTitle";
Layout = @ViewBag.LayoutModel.LayoutFile;
}
@using (Html.BeginForm())
{
<span class="error">@ViewBag.ErrorMessage</span>
<input type="hidden" name="Referrer" id="Referrer" value="@ViewBag.Referrer" />
html stuff here
}
,請參閱以下問題的更多細節。確保你修改你的web.config,如下所述:How to set ViewBag properties for all Views without using a base class for Controllers?
除了atbebtg的回答,爲了渲染東西,你要利用Razor的部分支持。部分被命名爲模板化的HTML片段,可以在視圖中定義並在佈局適合的佈局中呈現。在佈局中,您可以撥打@RenderSection("wellKnownSectionName")
,並在使用佈局的視圖中聲明@section wellKnownSectionName { <link rel="stylesheet" href="@UserStylesheetUrl" /><script type="text/javascript" src="@UserScriptUrl"> }
。通常你想描述名字的意思,比如「documentHead」。
更新: 如果您在每個視圖上呈現相同的模板化HTML,它將轉而進入佈局。 (由於您的佈局包含HEAD和BODY標籤,因此您可以將相應的代碼添加到HEAD標籤中)。您只需確保通過ViewBag/View.Model從控制器傳遞佈局所需的信息/ ViewData的。所以,你的佈局將包括此:
<head>
<link rel="stylesheet" href="/css/@ViewBag.UserName/.css"/>
</head>
和您的控制器將包括填充ViewBag.UserName邏輯:
ViewBag.UserName = Session["UserName"];
(理想情況下,你可以使用一個強類型的視圖模式,我建議你避免使用Session來做任何事情,因爲它的好處與其他選擇相比是很小的,並且對架構造成很大的代價......相反,我只是建議在包含用戶名或其他內容的瀏覽器上存儲一些加密的cookie,您可以使用它每個頁面加載以從緩存/ db /服務檢索用戶對象。)
@atbebtg - 所以基本上只使用部分意見,並與@ Html.Partial(使其)佈局的內部? – Dimskiy 2011-05-03 17:20:21
是啊,只要使用局部視圖,並做@ Html.Partial() – atbebtg 2011-05-03 17:22:44
如果它是一塊數據的即將進行
元素?像CSS文件的路徑或什麼? – Dimskiy 2011-05-03 17:26:47