欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

程序员文章站 2024-02-29 08:42:22
...

CHAPTER 2 Your First MVC Application

使用Visual Studio 2017 创建 ASP.NET Core

示例代码: https://github.com/apress/pro-asp.net-core-mvc-2

演示了:
* ViewBag, 强类型视图
* Model Binding
* Tag Helper
* Validation


读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

生成项目的目录结构

读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

点击运行

读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

添加Controller
Controller是用来处理web请求的,在C#中是一个类,继承自Microsoft.AspNetCore.Mvc.Controller。 每个controller内部的public method都是一个 action method,是用来处理请求的真正了逻辑所在。

ASP.NET Core的Controller都放置在Controller文件夹中,名字都是以Controller结尾,默认的controller是叫做 Home。

将HomeController中的代码全部替换为:

using Microsoft.AspNetCore.Mvc;
namespace PartyInvites.Controllers {
    public class HomeController : Controller {
        public string Index() {
            return "Hello World";
        }
    }
}

再次启动程序,就能够看到浏览器中输出的 Hello World

路由系统
当有URL请求来到的时候,ASP.NET 内部的 routing system(路由系统) 将根据请求地址来映射到对应的C# controller和action,这样就能正确的寻找到处理逻辑。

默认地, ASP.NET的HomeController中的Index方法是访问主页时的默认位置。 项目创建的时候,Starup.cs中已经写入了默认路由规则:

 app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

渲染View

修改HomeController:

namespace PartyInvites.Controllers {
    public class HomeController : Controller {
        public ViewResult Index() {
            return View("MyView");
        }
    }
}

当action返回了一个 ViewResult对象是,这就是告诉MVC让它渲染一个视图View。

添加视图

对着View/Home文件夹右键,添加新项:


读书笔记:Pro ASP.NET Core MVC 2 [Chap2 ]

替换内容:

@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
@ViewBag.Greeting World (from the view)
</div>
</body>
</html>

HomeController的Index中:

        public IActionResult Index()
        {
            int hour = DateTime.Now.Hour;
            ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon";
            return View("MyView");
        }

Controller将内容放入了一个叫 ViewBag的 dynamic对象中,然后View中将其取出,显示在了浏览器中。

强类型视图

public class HomeController : Controller {
public ViewResult Index() {
int hour = DateTime.Now.Hour;
ViewBag.Greeting = hour < 12 ? "Good Morning" : "Good Afternoon";
return View("MyView");
}

//用这个action来演示强类型视图
public ViewResult RsvpForm() {
    return View();
}
}

RsvpForm.cshtml

@model PartyInvites.Models.GuestResponse
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>RsvpForm</title>
</head>
<body>

<form asp-action="RsvpForm" method="post">
<p>
<label asp-for="Name">Your name:</label>
<input asp-for="Name" />
</p>
<p>
<label asp-for="Email">Your email:</label>
<input asp-for="Email" />
</p>
<p>
<label asp-for="Phone">Your phone:</label>
<input asp-for="Phone" /></p>
<p>
<label>Will you attend?</label>
<select asp-for="WillAttend">
<option value="">Choose an option</option>
<option value="true">Yes, I'll be there</option>
<option value="false">No, I can't come</option>
</select>
</p>
<button type="submit">Submit RSVP</button>
</form>
</body>
</html>

Tag Helper
MyView.cshtml中增加下面一句:

<a asp-action="RsvpForm">RSVP Now</a>

这个属性是 tag helper属性,让razor引擎来添加href,指向同controller下的 RsvpForm action。

分别处理Get和Post请求

[HttpGet]
public ViewResult RsvpForm() {
return View();
}

[HttpPost]
public ViewResult RsvpForm(GuestResponse guestResponse) {
// TODO: store response from guest
return View();
}

Validation

using System.ComponentModel.DataAnnotations;

namespace PartyInvites.Models {
public class GuestResponse {
    [Required(ErrorMessage = "Please enter your name")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Please enter your email address")]
    [RegularExpression(".+\\@.+\\..+", ErrorMessage = "Please enter a valid email address")]
    public string Email { get; set; }

    [Required(ErrorMessage = "Please enter your phone number")]
    public string Phone { get; set; }

    [Required(ErrorMessage = "Please specify whether you'll attend")]
    public bool? WillAttend { get; set; }

MVC会自动识别这些attribute,并且在model binding的时候进行验证。

Model Binding的时候检验结果:

[HttpPost]
public ViewResult RsvpForm(GuestResponse guestResponse) {
    if (ModelState.IsValid) {
        Repository.AddResponse(guestResponse);
        return View("Thanks", guestResponse);
    } else {
        // there is a validation error
        return View();    //这一句直接返回,能够利用Model Binding将验证失败前的值都保存在表单里
    }
}

表单页面显示处理错误:

<div asp-validation-summary="All"></div>      //这里面的值是 ValidationSummary的枚举

验证失败的字段会生成这样的HTML:

<input type="text" class="input-validation-error" data-val="true"
    data-val-required="Please enter your phone number" id="Phone"
    name="Phone" value="">

而没有验证错误的时候,生成的是这样的HTML:

<input type="text" data-val="true" data-val-required="Please enter your phone number"
id="Phone" name="Phone" value="">

可见,验证失败的时候,会生成一个 class=input-validation-error ,可以自己写css样式来修改验证错误提示。

MVC的惯例是静态内容放在wwwroot文件夹下。web 页面中引用不需要加上 wwwroot路径:

<link rel="stylesheet" href="/css/styles.css" />