大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: ASP.NET 修改讲义

Action方法

Controller中返回ActionResult的方法,这些方法被称之为Action(方法)。

一个Controller中可以有多个不同名的Action。

如果Action同名,需要遵守方法重载的语法规定:

  • 通常标记[HttpPost]/[HttpGet]等,用以处理不同method的HTTP请求;
  • 但仅仅是[HttpPost]/[HttpGet]不能形成“重载”的效果(即不能用[HttpPost]/[HttpGet]等特性来区分方法)

说明/提示:ASP.NET的所有代码都需要遵守C#语法!


ActionResult

Action方法的返回值为ActionResult。注意:ActionResult是一个抽象类,下面还有很多具体的实现类,比如

通过return View() 返回的ViewResult,是最最常见的内容,返回一个完整的HTML页面。(其他实现类按课程进度讲解)

页面的生成依赖于:

viewName

即:方法View()的参数名,用于指定所需的.cshtml文件。

  • 如果不指定,使用的View文件就是: \Views\<ControllerName>\<ActionMethodName>.cshtml,和它所在的controller同名的folder(或Shared目录等)下的和该Acton同名的.cshtml文件
  • 否则,如果viewname:
    1. 以“/”或“~/”开头,那就需要以.cshtml结尾,呈现一个完整的.cshtml文件路径(类似于“绝对路径”)
      return View("~/Views/Home/Contact.cshtml");
      return View("/Views/Home/Contact.cshtml");
      PS:~是ASP.NET独有的、历史遗留标记——“服务器根路径”(绝大部分时候等同于/)
    2. 当前Controller目录(或Shared目录等)下,路径片段指定的View(类似于“相对路径”,但不带.cshtml后缀)
      return View("Home/Welcome");    //当前文件夹下有目录Home,Home下有Welcome.cshtml
      return View("Failed");  //当前文件夹下有Failed.cshtml
      return View("../Error");   //当前文件夹Shared文件夹下有Error.cshtml

演示:故意试图进入一个没有“适格”.cshtml文件的Action,查看报错信息(对比:找不到Controller和Action404错误

了解ASP.NET MVC由上往下(即:有“优先级”的)查找view的路径

Razor

.cshtml又被称之为razor(模板)。

#小知识#:为什么是cshtml?cs+html:

  • cs对应csharp(C#)
  • 如果是VB.NET开发,后缀名就是vbhtml

整个cshtml文件除了(不可变的)html标签,还有一些@符号引导的(可变的)声明、语句、代码块等。

ASP.NET MVC利用razor view,“结合”不同的数据(Model),生成完整的HTML页面,返回给前端。


Model

向razor view传递的数据,被称之为Model。

弱类型

一种方法是使用ViewData。

在Action中赋值:

public ActionResult Index()
{
    //想象:各种各样的内容都是可以从“数据库”取出来
    //ViewData["greet"] = "源栈欢迎你";
    ViewData["greet"] = true;
    return View();  
在razor view中取值:
<h1>
    @ViewData["greet"]
</h1>

注意:ViewData是一个“键值对”,其中key是string类型,value是Object类型。

@想一想@:这样有什么问题?(同为什么需要泛型集合

  • 装箱拆箱:性能损耗
  • 类型不安全
  • 没有智能提示,容易拼写错误
  • 常见错误:NullReferenceException

#预防针#:比如我们有这样的代码:

public ActionResult Index()
{
    if (LogOnSuccess())
    {
        ViewData["Success"] = true;
    }
    else //没有再给ViewData["Success"]赋值

在razor view这样就会报错:

@((bool)ViewData["Success"])

[]看起来不“舒服”,所以ASP.NET还推出了ViewBag,作为ViewData的“替代品”,但两者的问题是一样的。

要从根本上解决问题,需要引入

强类型

准备一个实现声明的类,

public class Student
{
    //private bool gender;
    public int Id { get; set; }
    public string Name { get; set; }

将其对象作为参数传入View()

public ActionResult Index()
{
    Student atai = new Student
    {
        Id = 10,
        Name = "阿泰"
    };
    return View(atai);

在razor中:

  1. 声明使用的Model类型(注意此时的@model是小写
    @model _17bang.Models.Student
  2. 调用@Model获得通过View()参数传入的model对象,然后就可以欲所欲为(调用其公共类成员,通常是属性)啦,^_^
    <h1>
        <a href="/User/@Model.Id">@Model.Name</a>
    </h1>
    注意此时的@Model,M是大写。


Request对象

@想一想@:之前学习过的View()、ViewData、ViewBag这些,是从哪来的?

他们都是在Controller(基类)中定义的,Request也一样……

PS:通常所有Controller都放置在Controllers文件夹下,但决定一个类是不是Controller,取决于它有没有继承Controller基类,而不是有没有放在这个文件夹下。

Request对象封装了HTTP请求的诸多信息,最常用的是:

QueryString

F12演示:QueryString的类型为NameValueCollection,有string/int索引器……

断点演示:QueryString获取的是URL中的参数

学生单页

URL路径:/Student/Single?id=5,告诉后台:

  • /Student/Single:学生单页
  • id=5:id=5的那个学生

后台准备好Controller和Action

public class StudentController : Controller
{
    public ActionResult Single()

然后在Action方法中拿到id:

int id = Convert.ToInt32(Request.QueryString["id"]);

通过repository拿到对应的Student对象:

Student atai = new StudentRepoitory().Get(id);
return View(atai);   //传递给view……

#体会#:所谓动态页面的动态

Request.Form

直接使用Request.Form获取FormData,是最“原始”的方式:

string name = Request.Form["UserName"][0];
string password = Request.Form["Password"][0];

注意:

  • UserName和Password都是input标签的name属性值。
  • Request.Form["UserName"]获取的是实现了StringValues的ICollection,所以要取得用户输入的值,还需要在后面接[0]。为什么呢?因为Form Data允许重复的name值可以允许重复:


@想一想@:Request.QueryString["id"]和Request.Form["key"]好用么?为什么?

其他

Request.Url:能获取几乎所有url相关的内容:Host / Port / Path / Query

Request.UrlReferrer:更多的时候我们是要取“上一个”URL的信息,即:用户从哪一个页面跳转到当前页面的

数据相关的:File / Cookie / Session(是在HttpContext中的)

HTTP协议相关的:HttpMethod / Headers(ContentType/UserAgent等简便方式)

@想一想@:Request对象是怎么生成的?它是怎么被“赋值”的?




作业

  1. 新建Controller、Action和View,完成以下页面的静态呈现:
    1. 文章单页:/Article/Single?id=1 
    2. 文章修改:/Article/Edit?id=7 
    3. 所有文章列表:/Article/Index?pageIndex=3 
    4. 文章分类列表:/Article/IndexOfCategory?pageIndex=3&category=1 
    5. 博主文章列表:/Article/IndexOfAuthor?author=5&pageIndex=2 
    6. 任务历史月记录:/Task/HistoryOfMonth?year=2019&month=8&id=5
    7. 用户注册页面:/Register 
  2. 并利用ADO.NET/EF实现以下两个页面的功能:
    1. /Article/Single?id=5,输出id=5的Article的标题、正文和关键字
    2. 注册页面,用户输入用户名和密码,提交之后页面刷新,根据数据库结果:
      1. 提示用户名重复,或者
      2. 用户名和密码存入数据库,显示注册成功 
学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 ASP.NET 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码