控制器和视图的创建及使用
了解完整个项目结构后,开始学习使用我们ASP.NET Core的核心课程部分内容,先学习如何使用控制器和视图。
一、控制器
控制器可以理解为是视图和模型的中间者,是一个桥梁。可以决定对应方法展示什么样的视图,以及接收视图传过来的数据,并返回响应到前端展示。
我们来看下项目中默认创建的HomeController.cs控制器的代码都是什么意思,以及有什么作用:
using coreTest71.Models; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; namespace coreTest71.Controllers { public class HomeController : Controller { //引入和使用日志记录器(Logger)的实例,用于在HomeController类中记录日志信息。 private readonly ILogger<HomeController> _logger; //在创建HomeController类的实例时,通过依赖注入的方式注入一个ILogger实例,以便在HomeController类中记录日志信息。 //依赖注入是一种设计模式,它使得类能够通过构造函数或属性来接受其所需的依赖项,而不是在类内部直接创建这些依赖项。这种方式可以提高代码的可测试性、可维护性和松耦合性。 public HomeController(ILogger<HomeController> logger) { _logger = logger; } //默认方法Index,会对应Views文件夹下的Home文件夹中的Index视图 public IActionResult Index() { return View(); } //Privacy方法 public IActionResult Privacy() { return View(); } //作用是设置响应缓存的行为,以控制对该方法的响应是否被缓存。 [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { //为Error视图提供一个ErrorViewModel对象,并设置其中的RequestId属性值 return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } }
1、private readonly ILogger _logger;
它是在HomeController类中声明一个名为_logger的私有只读字段。
作用是引入和使用日志记录器(Logger)的实例,用于在HomeController类中记录日志信息。
ILogger是泛型接口ILogger的参数化类型,表示了日志记录器将与HomeController类相关联。泛型参数HomeController指定了日志记录器将记录日志的类的类型。
通过使用日志记录器,我们可以在应用程序中记录各种信息,例如调试信息、错误信息或状态信息。这对于应用程序的调试和监控非常有用,帮助我们了解应用程序的运行状况和调用流程。
在HomeController类中,我们可以通过使用_logger字段,调用ILogger接口中定义的方法,如LogInformation、LogError等,将需要记录的日志信息传递给日志记录器。这样,我们就可以方便地在HomeController类中记录和管理日志信息。
2、ResponseCache的作用
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 是一个特性(Attribute),应用于Error()方法。
作用是设置响应缓存的行为,以控制对该方法的响应是否被缓存。
具体作用如下:
Duration = 0:指定响应的缓存有效期为0秒,即禁用缓存。每次请求该方法时,都会重新计算和生成响应。
Location = ResponseCacheLocation.None:指定响应不应被缓存到任何位置,包括客户端浏览器和中间代理服务器。这可以确保每次请求该方法时都会生成新的响应。
NoStore = true:指示客户端不应将该响应存储在缓存中。这与Location = ResponseCacheLocation.None 结合使用,以确保禁止保存和重用响应结果。
通过设置这些属性,我们可以确保Error()方法的响应不会被缓存,以避免在错误发生时返回旧的或不正确的响应。每次请求该方法时,都会生成最新的错误响应。这对于开发和调试期间的错误处理很有帮助,可以更好地跟踪和调试错误。
3、new ErrorViewModel
new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }) 用于创建一个ErrorViewModel实例,并设置其属性值。
作用是为Error视图提供一个ErrorViewModel对象,并设置其中的RequestId属性值。
该代码中使用了条件运算符(ternary operator)和空合并运算符(null-coalescing operator)。
Activity.Current?.Id:获取当前活动(Activity)的Id属性值。Activity.Current返回当前正在执行的活动,而Id是活动的唯一标识符。使用?.用于安全调用,如果Activity.Current为null,则返回null,否则返回其Id属性值。
HttpContext.TraceIdentifier:获取当前HTTP请求的唯一标识符。HttpContext是ASP.NET Core中用于访问HTTP上下文的对象,TraceIdentifier是HTTP请求的唯一标识符属性。这可以用作备用值,如果Activity.Current为null时使用。
通过使用条件运算符和空合并运算符,表达式会选择Activity.Current的Id属性值,如果为null则选择HttpContext.TraceIdentifier的值。这样就可以在创建ErrorViewModel实例时设置RequestId属性为当前请求的唯一标识符。
ErrorViewModel通常用于在错误处理视图中显示错误详细信息,包括错误消息、堆栈跟踪和请求标识符等。通过设置RequestId属性,可以在视图中展示当前请求的唯一标识符,以帮助识别和调试错误。
二、控制器向视图传输数据
什么叫做控制器向视图传输数据呢?
因为视图只是负责页面的展示,而核心的功能实现都是在控制器实现。我们从视图向服务器发送操作请求后,需要控制器做一些处理,控制器做完处理后,需要返回结果在前端展示,这时候就需要“控制器向视图发送数据”了。
控制器向视图发送数据的三个方法
1、ViewData
ViewData也叫做ViewData属性,它在MVC 5中存放在ControllerBase类中,ViewData属性的定义定义如下:
public ViewDataDictionary ViewData { get; set; }
ViewData本身是ViewDataDictionary字典类型,其定义如下:
public class ViewDataDictionary : IDictionary<string, object>{}
使用示例:
在控制器LoginController.cs控制器中的Index方法,添加如下代码:
public ActionResult Index() { //使用ViewData ViewData["name"] = "张三"; return View(); //返回视图显示 }
对应Index.cshtml视图,添加如下代码:
@{ ViewBag.Title = "Index"; Layout = null; //对当前页面设置不要布局页 } <h2>Index</h2> <h1>这是我创建的第一个视图</h1> @* 使用ViewData *@ <p>我的名字:@ViewData["name"]</p>
运行效果:
2、ViewBag
这个用得最多。
ViewBag对象是ASP.NET MVC 3提供的功能,它被声明为一个dynamic类型。
对应ASP.NET MVC 5源代码格式如下:
[Dynamic]public dynamic ViewBag { get; }
须知:dynamic类型的变量都会编译为object类型的变量。因此,dynamic类型只存在于编译时刻,而不存在于运行时刻。
使用示例:
在控制器LoginController.cs下的test方法,添加如下代码:
public ActionResult test(string name) { //提示 ViewBag.notice = "你好啊~"; return View(); }
在视图test.cshtml中添加如下代码:
@{ Layout = null; } <h1>张三,@ViewBag.notice</h1>
运行效果:
3、TempData
ViewData属性与ViewBag属性无法跨Action方法传递数据,当需要在多个Action方法之间传递数据时,可采用TempData属性。
它在ASP.NET MVC 5源代码中声明和TempDataDictionary类的定义如下:
public TempDataDictionary TempData { get; set; }
TempData为什么可以实现跨方法访问,是因为属性是将数据保存在Session中。
使用示例:
在LoginController.cs的Index方法中使用TempData。
public ActionResult Index() { //使用ViewData ViewData["name"] = "张三"; //使用TempData TempData["nick"] = "李四"; return View(); //返回视图显示 } public ActionResult test(string name) { //提示 ViewBag.notice = "你好啊~"; return View(); }
对应的test.cshtml视图代码:
@{ Layout = null; } @* 使用TempData变量 *@ <h1>张三,@ViewBag.notice , @TempData["nick"]</h1>
运行代码,需要先运行/Login/Index。得到下面的结果:
再运行/Login/test,得到如下结果:
但是须知:当你再次刷新页面时,会发现这个值就不见了。只能生效一次。
补充知识点:dynamic类型的变量都会编译为object类型的变量。因此,dynamic类型只存在于编译时刻,而不存在于运行时刻。
完成了本课的学习,尝试的做一道作业题吧。
请分别使用ViewData、ViewBag、TempData传递“你好,王晓晓”到视图页面中展示。
需要购买本课才能留言哦~