我在使用HTML辅助方法在过程中的之前没注意到的细节:
1. Html.BeginForm:
用于提交表单,利用路由引擎找到提交路径。与<form>相比,当应用程序部署到一个非网站根目录或者修改了路由定义,就会出现找不到资源。
2. Html.ValidationSummary:
用来显示ModelState字典中所有验证错误的无序列表,生成<ul>展示错误信息。使用布尔类型参数来告知辅助方法错误级别显示方式。
true只显示ModelState中与模型本身有关的错误。 false是除了显示模型错误还显示属性相关的错误。
3. Html.Label:
其存在的价值除了显示附加信息,其中for特性,一般要包含相关输入元素的ID,此时如果用户单击label那么浏览器会把焦点传送给相关输入控件。在复选框和单选框较为常用。
4. Html.DropDownList和Html.ListBox(支持多项需把multiple特性设置为multiple)
后台用SelectList或MultiSelectList构建。对于SelectList构造函数的参数需要指定原始集合,作为后台值使用的属性名称(Id),作为显示文本使用的名称(Name),以及当前所选项。
5. Html.Editor(Html.EditorFor)模板辅助方法,默认和Html.TextBox的效果相同,区别在于,可以在后台通过在属性上面设置[DataType]特性来生成合适的编辑器,如[DataType(DataType.MultilineText)]则会生成多行文本。
在使用ViewData,ViewBag,进行模型绑定时注意问题:
- 对于ViewData["Name"]和View.Name效果相同,可以认为是相同值的两种不同访问形式
- 当设置ViewData["Name"]="XXX"时,前台用Html.TextBox("Name")或Html.TextBox("XXX",ViewData["Name"])都可以得到值,
- 对于ModelState当模型绑定失败时也会将值保存在其查找表中的某个属性中。以便呈现视图时显示给用于它原先的错误输入形式。
- 辅助方法查看ViewData里的内容,也可以看到其中的对象属性。如下:
public ActionResult Edit(int id) { ViewBag.Student = new Student(){Name="XXX"}; return View(); } //视图中访问 @Html.TextBox("Student.Name") //渲染结果 <input id="Student_Name" name="Student.Name" type="text" value="XXX"/>
注意到渲染得到的input元素id特性使用下划线替代点,因为id中使用点是非法的,id特性一般被客户端脚本使用。另外一点设置样式时class前面需要加@符号
带有连字符的C#属性名是无效的,需要用下划线替代,所有HTML辅助方法在渲染时会将属性名中下划线转换为连字符。如下例子(红色标出):
Html.BeginForm("","",FormMethod.Get,new {@class="", data_name="XXX"}) //渲染效果 <form action="" class="", method="get" data-name="XXX">
在使用强类型绑定时,对于Html.TextBox("Name")这种形式的辅助方法,当ViewData["Name"]和强类型同时存在的情况下,如何模型中Name字段为null或空字符串则会使用ViewData["Name"]中的值。
由此可以看出辅助方法在查找强类型模型对象之前会首先查看ViewData或ViewBag。
另外可以使用强类型辅助方法,除了以For为后缀和lambda表达式替换字符串外,渲染效果与之前相同,但不会造成与ViewData中的Key冲突。
渲染辅助方法
- Html.ActionLink和Html.RouteLink:用法简单两者遵循相同的模式,但是RouteLink只可以接收路由名称,而不能接收控制器和操作的名称。各自重载方法很多
Html.ActionLink("文本显示", "操作名称", "控制器名称", new {id = 12}, null)
Html.RouteLink("文本显示", new {action="操作名称", ......})
- Url辅助方法:Action,Content,RouteUrl
- Html.Partial和Html.RenderPartial:不需要通过控制器中的某个操作直接渲染视图,并且需要和母版视图拥有相同的模型
Html.Partial:将部分视图渲染成字符串
RenderPartial:直接写入响应流,其用法上需要在@{}代码块中书写。拥有较好的性能
- Html.Action和Html.RenderAction
类似于上面提到的,但是这两个执行单独的控制器操作,可以建立不同的模型和利用单独的控制器上下文,提高灵活性和重用性。
通常配合ChildActionOnlyAttribute特性使用,其可以有效避免运行时直接通过URL来调用某个控制器中的某个Action操作