学编程,来源栈;先学习,再交钱
当前系列: ASP.NET 修改讲义

BeginForm()

MVC使用了using界定form表单范围:

@using (Html.BeginForm())@* 这里的Html前面没有@ *@
{ 
}

默认是:Post到当前页面。

BeginForm()方法可以重载,通过参数指定Action/Controller/Method等,比如:

@*form表单会用 Get方法 提交到 HomeController 下的 Index(),还带着routeValue(id=3)*@
@using (Html.BeginForm("Index", "Home", new { id = 3 }, FormMethod.Get))

演示:

  1. F12:生成的HTML form表单:
    <form action="/Home/Index/3" method="get">
    </form>
  2. 断点:HomeController.Index(id)被击中,且id=3


TextBox

form标签中的表单元素,可以用原生的HMTL标签,也可以用@Html.TextBox():

@Html.TextBox("username")

演示:生成的HTML

<input id="username" name="username" type="text" value="">

用户的输入,后台(Action中)可以通过Request对象获得:

string username = Request.Form["username"];

似乎这样的写法也没什么用?确实如此,^_^,所以我们更多的时候,需要配合

强类型Model

使用TextBoxFor

@Html.TextBoxFor(m => m.Name)

F12演示其定义:

public static MvcHtmlString TextBoxFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProperty>> expression);

m,代表当前view上声明的model;m => m.Name,取model的Name属性。

演示:生成的HTML代码,input的name就是指定的model属性名:

<input id="Name" name="Name" type="text" value="">

这还是没用呀?!见证奇迹的时候:

这就是MVC的


Model绑定

当ASP.NET MVC接收一个HTTP请求的时候,它就会自动的

  1. 解析从前台得到的数据,除了Form Data,还包括 QueryString 和 route data(掉头学习!)
  2. 将上述数据的key/name和Action方法参数属性进行匹配,并用这些数据
  3. 自动给这些属性赋值(含类型转换)

注意

  • 绑定是ASP.NET将前台(客户端/浏览器,是RazorPage)传回的值赋值给Action方法参数的行为,所以razor view使用PageModel中的属性,并需要“绑定”,其行为也是绑定。
  • model绑定和@Html.TextBoxFor()的使用没有关系!(演示:普通HTML表单传回的数据一样可以绑定)

#理解#:这一切(实例化Controller,调用Action,给它参数对象……)都通过反射实现:

Action本质上还是一个Controller的实例方法,它是被谁调用的呢?MVC框架,但MVC框架怎么知道有什么Controller什么Action呢?MVC的源代码可不可能这样

new RegisterController().Index(new Student())

可能的!所以只能通过反射,扫描整个项目,获得Controller的子类,以及他们的方法,并根据方法参数类型实例化对象……

PS:各种需要“高性能”的框架(ORM/MVC等)大量的应用反射,说明反射对性能的影响至少是“可以接受”的。

除了普通Model:

简单类型参数

也会被自动赋值。

public ActionResult Index(int id, string name, bool gender )

数据源通常是:

  • QueryString:比如/Register/?id=2&name=fg&gender=true,和/或
  • route data,比如/Register/Index/23?gender=true

断点演示:Action的参数值都如url所示

另:MVC是既可以给基本类型参数赋值,也可以给自定义类型(model)赋值(演示)。

可空类型/默认值

如果参数是可空类型,MVC有没法从前台获得相应的数据,比如URL为:/Register/Index/23,MVC就只能取得id=23,gender没值(=null)

这时候“没法绑定”,MVC会报错!

可以根据实际情况选择:

  • 可选参数(赋默认值):
    public ActionResult Index(int id, string name, bool gender = false )
  • 可空类型:
    public ActionResult Index(int id, string name, bool? gender )

复杂Model属性

实际开发中有可能Model的属性类型,不是基本类型而是自定义类型,比如:

public class Student
{
    public int Id { get; set; }
    public Major Major { get; set; }    //Major是自定义的

这种情况,在@Html.TextBoxFor()的时候,就需要:

@Html.TextBoxFor(m=>m.Major.Name)

一直点(.)到基本类型为止。

这样,生成的HTML:

<input id="Major_Name" name="Major.Name" type="text" value="">

MVC在Model绑定时,会根据key中的点(.),进一步的往下解析。比如先找到Major属性,根据它的类型实例化一个对象,再给对象的Name赋值——既然Name后面再没有点(.)了。

如果前端根本就没有向后台传递任何Major相关的值,Major为null值。

掉头重学:Editor


重载参数

TextBox的参数比较简单,常用的有:

htmlAttributes

所有的HtmlHelper都可以传这个参数。通常用匿名类(也可以用IDictionary,都是“键值对”)赋值:

object htmlAttributes
IDictionary<string, object> htmlAttributes

MVC会将其转换成HTML标签的属性。

    @Html.TextBoxFor(m => m.Name, new
    {
        style = "background-color:blue;",  //正常使用
        @class = "form-control",
        zyf_username_duplicated = /*null*/ string.Empty
    })

说明:

  • 因为@class是关键字,所以要加一个@符号,MVC会在生成HTML标签属性时自动将其去掉(类似的还有checked等)
  • 因为C#语法中属性名不能有中划线,所以要用下划线代替,MVC会在生成HTML标签属性时自动将其转换成中划线
  • 匿名对象的属性值不能为null值,所以用string.Empty代替

如果不想这么“折腾”的话,可以使用IDictionary格式:

@Html.TextBoxFor(m => m.Name, new Dictionary<string, object> {
    { "style", "background-color:blue" },
    { "class", "form-control" },
    { "zyf-username-duplicated", null } }
)
演示生成的HTML标签:略

stringFormat

当向View传递了Model,且Model中属性有值的时候,HTML表单元素的value会被赋值并呈现。(演示:略)
return View(new Student
{
    BirthDay = DateTime.Now
这时在TextBoxFor()中还可以传一个参数format,可以决定textbox的呈现格式。比如:
@Html.TextBoxFor(m => m.BirthDay, "{0:D}")

就会让文本框中日期格式变为:

更多格式可参见Microsoft Doc

另外,注意可空和非可空的区别:(演示)

  • 非可空有默认值,比如:0,会呈现出来
  • 可空默认为null,就不会呈现
学习笔记
源栈学历
今天学习不努力,明天努力找工作

作业

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

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

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

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

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

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

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

公众号:源栈一起帮

二维码