1. Controller向View传值

ViewBag

第一种方式,使用ViewBag 它是dynamic类型的,因此可以随意传值。

  1. // Controller
  2. public class HomeController : Controller
  3. {
  4. // GET: Home
  5. public ActionResult Index()
  6. {
  7. ViewBag.Content = "我是ViewBag传值数据。";
  8. return View();
  9. }
  10. }
  11. // View
  12. @{
  13. ViewBag.Title = "Index";
  14. }
  15. <h2>Index</h2>
  16. @ViewBag.Content

输出显示
image.png

ViewData

第二种ViewData
一般存放一些不主要的数据。
使用方式和ViewBag不同,但它俩是一个东西。相关代码如下

  1. public dynamic ViewBag
  2. {
  3. get
  4. {
  5. if (_dynamicViewDataDictionary == null)
  6. {
  7. _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
  8. }
  9. return _dynamicViewDataDictionary;
  10. }
  11. }
  12. public ViewDataDictionary ViewData
  13. {
  14. get
  15. {
  16. if (_viewDataDictionary == null)
  17. {
  18. _viewDataDictionary = new ViewDataDictionary();
  19. }
  20. return _viewDataDictionary;
  21. }
  22. set
  23. {
  24. _viewDataDictionary = value;
  25. }
  26. }

使用方式

  1. // Controller
  2. public class HomeController : Controller
  3. {
  4. // GET: Home
  5. public ActionResult Index()
  6. {
  7. ViewBag.Content = "我是ViewBag传值数据。";
  8. ViewData["ViewData"] = "我是ViewData传值数据,ViewBag用法一样可以获取值。";
  9. return View();
  10. }
  11. }
  12. // View
  13. @{
  14. ViewBag.Title = "Index";
  15. }
  16. <h2>Index</h2>
  17. @ViewBag.Content
  18. <br />
  19. @ViewData["ViewData"]
  20. <br />
  21. @ViewBag.ViewData

image.png

TempData

存储之后,读取一次数据就被清空掉了。
本质就是Session。

  1. public void TempDataDemo()
  2. {
  3. TempData["TempData"] = "TempData";
  4. Response.Redirect("./TempDataDemo2");
  5. }
  6. // 添加TempDataDemo2视图
  7. public ActionResult TempDataDemo2()
  8. {
  9. return View();
  10. }
  11. URL http://localhost:63179/Home/TempDataDemo
  12. Redirect http://localhost:63179/Home/TempDataDemo2
  13. Response : HelloTempData
  14. 重新访问Url : http://localhost:63179/Home/TempDataDemo2
  15. 输出为空

View(Model)

使用View方法
image.png
Models文件夹新建Student类。
使用第二个重载方法。

  1. public ActionResult ShowData()
  2. {
  3. return View(new Student
  4. {
  5. Id = 1,
  6. Name = "张三",
  7. Age = 18
  8. });
  9. }

生成对应的视图。使用Model属性获取数据

  1. @model WebMvc.Models.Student
  2. @{
  3. ViewBag.Title = "ShowData";
  4. }
  5. <h2>ShowData</h2>
  6. @Model.Id
  7. @Model.Name
  8. @Model.Age

不加小写的model是弱类型视图,没有任何提示。@model里的类型一定和View方法参数里的类型一致

2. View向Controller传值

基础

  1. public class ViewController : Controller
  2. {
  3. public ActionResult Index(string name)
  4. {
  5. return Content("response:" + name);
  6. }
  7. }

使用?name=123 可以获取到值,和Request.QueryString一样
image.png
而使用post请求同样也可以获取到值。

  1. public class ViewController : Controller
  2. {
  3. public ActionResult Index(string name)
  4. {
  5. return Content("response:" + name);
  6. }
  7. public ActionResult ShowForm()
  8. {
  9. return View();
  10. }
  11. }

创建视图访问Index,一样可以获取到值。

  1. @{
  2. ViewBag.Title = "ShowForm";
  3. }
  4. <h2>Index</h2>
  5. <form action="/View/Index" method="post">
  6. <input type="text" name="name"/>
  7. <button>提交</button>
  8. </form>

image.pngimage.png
使用Http特性就可以指定使用什么方式去访问。
image.png
比如使用HttpGet就可以现在Index只能通过Get方式访问。

  1. [HttpGet]
  2. public ActionResult Index(string name)
  3. {
  4. return Content("response:" + name);
  5. }

使用post请求就会报404,因为没有对应的Action

模拟登录功能(ViewModel)

Models文件夹里,创建LoginViewModel实体,并添加验证特性。

  1. using System.ComponentModel.DataAnnotations;
  2. namespace WebMvc.Models
  3. {
  4. public class LoginViewModel
  5. {
  6. [Required, StringLength(20, MinimumLength = 2)]
  7. public string Email { get; set; }
  8. [Required, MinLength(2)]
  9. public string Password { get; set; }
  10. }
  11. }

控制器中添加方法

  1. public ActionResult Login()
  2. {
  3. return View();
  4. }
  5. [HttpPost]
  6. public ActionResult Login(LoginViewModel model)
  7. {
  8. if (!ModelState.IsValid)
  9. {
  10. return Json("输入有误!");
  11. }
  12. if (model.Email == "admin" && model.Password == "123")
  13. {
  14. return Json("Success");
  15. }
  16. else
  17. {
  18. return Json("Failed");
  19. }
  20. }

两个Login方法成对出现,无参返回视图,有参负责登录验证。
右键Login方法创建视图。选择模板Create,模型选择上面创建的。
image.png
会根据模型生成Html代码加上验证。
image.png
我们发现,这个EmailPassword是属性的名字,但我们想要中文的。则取Model类中修改,给字段加上特性[Display]
添加电子邮箱验证[EmailAddress]
密码框是明文的,需要修改为密码框[DataType]

  1. using System.ComponentModel.DataAnnotations;
  2. namespace WebMvc.Models
  3. {
  4. public class LoginViewModel
  5. {
  6. [Display(Name = "电子邮箱")]
  7. [EmailAddress]
  8. [Required, StringLength(20, MinimumLength = 2)]
  9. public string Email { get; set; }
  10. [Display(Name = "密码")]
  11. [DataType(DataType.Password)]
  12. [Required, MinLength(2)]
  13. public string Password { get; set; }
  14. }
  15. }

然后再把生成的前端代码登录按钮文字从Create修改为登录。
这个时候我们再看,就已经改变了。
image.png

Html

Html.BeginForm()

在上面生成的前端代码中,@using (Html.BeginForm())
代表开始生成一个表单。有12个重载,一般指使用默认的。

Html.AntiForgeryToken()

这个方法是生成一个防伪标记,用于防止仿照页面去访问。
对应的后端接口需要添加上[ValidateAntiForgeryToken]特性。
使用上面创建的ShowForm页面去访问测试。
image.png
image.png

Html.ValidationSummary()

将LoginAction修改为如下

  1. [HttpPost]
  2. [ValidateAntiForgeryToken]
  3. public ActionResult Login(LoginViewModel model)
  4. {
  5. if (!ModelState.IsValid)
  6. {
  7. ModelState.AddModelError("", "输入有误!");
  8. return View();
  9. }
  10. if (model.Email == "admin" && model.Password == "123")
  11. {
  12. return Json("Success");
  13. }
  14. else
  15. {
  16. ModelState.AddModelError("","账号或密码错误!");
  17. return View();
  18. }
  19. }

ModelState.AddModelError("","账号或密码错误!");
ValidationSummary方法将模型错误按无序列表形式显示。
image.png

Html.LabelFor()

Label标签
image.png

Html.EditorFor()

文本框
image.png

Html.ValidationMessageFor()

错误消息
image.png