1

为什么有时@ViewBag.Title包含正确的页面标题而@Page.Title为空?我们正在调试我们的视图/布局代码,我们注意到了这种差异。

谢谢。

4

2 回答 2

9

当您使用 asp.Net MVC 时,您可以使用一些工具将数据获取到您的页面。

  1. 您发送到视图的模型。
  2. 视图包。
  3. 临时数据。
  4. 饼干。
  5. 会议。

这些中的每一个都有自己的用例我们将使用的示例是一个基本的列表和更新视图,用于一组公司

该模型

每当您将定义的数据集发送到视图时都应该使用模型,并且应该包含页面的主要数据,并且通常模型特定于页面或控制器

查看包

每当您需要将一般数据发送到模型上未定义的页面或跨视图树使用的数据时,都应该使用 ViewBag 。

温度数据

临时数据顾名思义就是临时数据的存储,当您不确定数据是否会到达目的地或者您想在操作之间传递数据而不添加参数时,应该使用它。

饼干

Cookie 就像全局变量一样,是整个应用程序中的主机数据。

会议

像 cookie 这样的会话是全局变量,但它们的生命周期不同会话可用于在请求之间存储表单数据之类的事情不要使用会话来执行此操作,而是使用诸如http://garlicjs.org/之类的东西

让我们看一下示例我们有以下 ViewModel

public class Company 
{
  public int? id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
}

布局页面如下所示

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    //This looks for the Title property on the ViewBag and inserts it in the title tags
    <title>@ViewBag.Title</title>
</head>
<body>
   @Html.Action("Header", "PageElements")
   @RenderBody()
</body>
</html>

PageElements 控制器上的 Header Action 看起来像这样

public PartialViewResult Header()
{
  ViewBag.CurrentLink = HttpContext.Current.Request.Cookies["CurrentLink"];

  return PartialView();
}

标题部分视图如下所示

<header>
   <ul> 
      <li class="@(ViewBag.CurrentLink == "Home" ? "Current" : "")"> 
          @Html.ActionLink("Home", "Index", "Home")
      </li>
      <li  class="@(ViewBag.CurrentLink == "Companies" ? "Current" : "")"> 
          @Html.ActionLink("Companies", "Index", "Companies")
      </li>
   </ul>
</header>

更新的控制器操作如下所示

public ViewResult Update(int id)
{  

  //Gets a company from the database
  var model = db.GetCompany(id);

  //Sets The Title property on the ViewBag to Update : CompanyName
  ViewBag.Title = String.Format("Update : {0}", model.Name);  

  //Sends the company to the view
  return View(model);
}

更新视图如下所示

@model Application.Models.Company
@{
   Layout = "_layout.cshtml";
}

@using (Html.BeginForm())
{ 
   @Html.HiddenFor(model => Model.id)

   @Html.LabelFor(model => Model.Name)
   @Html.TextBoxFor(model => Model.Name)

   @Html.LabelFor(model => Model.Description)
   @Html.TextAreaFor(model => Model.Description)
   <button>Submit</button>
}

更新的发布操作如下所示

[HttpPost]
public ActionResult Update(Company model)
{ 
  //Attempts to update the model 
  if (model.Update())
  {
     //Set the message to update succeeded
     TempData["Message"] = String.Format("{0} Successfully updated");
  }
  else   
  {
     //Set the message to update failed
     TempData["Message"] = String.Format("{0} filed to update");
  } 

  return RedirectToAction("Index");
}

公司的控制器操作如下所示

public ViewResult Index()
{
  //Index is the entrypoint for companies so we set the currentlink to companies while we are in companies
  HttpContext.Current.Request.Cookies["CurrentLink"] = "Companies";      

  //Gets the success or failure message from the temp data
  ViewBag.Message = TempData["Message"]; 

  //Sets The Title property on the ViewBag to List of companies
  ViewBag.Title = "List of companies";

  var model = db.GetAllCompanies();

  return View(model);
}

列表的视图如下所示

@model IEnumrable<Application.Models.Company>
@{
   Layout = "_layout.cshtml";
}
<span>@ViewBag.Message</span>
<ul>
@foreach (var company in Model) 
{
  <li>@company.Name : @company.Description @Html.AnchorLink("Edit", "Update", new { company.id}) </li>
}
</ul>

让我们讨论一下这个应用程序的流程是如何工作的

  1. 指数行动被公司触发。
  2. 我们将当前链接设置到Cookie中的公司
  3. 然后我们在ViewBag中设置 Title
  4. 我们检查 TempData 中的消息并将它们放入ViewBag
  5. 然后我们将公司的集合放入一个模型中,然后发送到页面。
  6. 现在 razor 启动并开始首先渲染页面
  7. 然后布局渲染并从ViewBag中获取 Title 值
  8. 然后标题部分视图呈现并从Cookie中获取 currentlink 值
  9. 我们点击一​​个公司的更新按钮
  10. 更新操作运行
  11. 从数据库中获取公司并将其发送到模型中的视图
  12. 我们在ViewBag中更改标题以更新
  13. 页面首先呈现并将公司数据放在表单上,​​来自模型
  14. 然后布局渲染并从ViewBag中获取 title 值
  15. 然后标题呈现并从cookie中获取当前链接(值仍然是公司,我们不必更改它)
  16. 然后我们提交表单并向TempData添加一条消息
  17. 现在我们回到了公司列表,我们可以从TempData中获取成功或失败消息

我们使用模型特定数据发送到视图。我们使用ViewBag常规数据发送到视图和布局。我们使用TempData在动作之间传递数据而不使用参数。我们使用Cookie来存储暂时不会更改的数据

于 2013-03-04T19:56:31.930 回答
4

正确的是 using ViewBag.Title,因为它是在您的ViewBag财产的上下文中,View而您的财产Page.Title来自 asp.net webforms。这就是为什么Page.Title为空的原因,它没有上下文。

于 2013-03-04T16:32:23.967 回答