Asp.net MVC5 框架揭秘 S412 实例解析 – 绝妙的扩展 模式的胜利
Asp.net MVC5 框架是个 开源的,处处可扩展的框架。
蒋先生 在他的这本书里 对如何理解框架,如何扩展框架, 给出了大量的说明和实例。
先上效果图
大部分做传统BS 的同学看到这个页面,脑海里的第一反应 就是一堆HTML 一堆控件 然后 后台绑定什么的吧。
但请看页面的代码。
-
@model MvcApp.Models.Employee
-
<html>
-
<head>
-
<title>编辑员工信息</title>
-
</head>
-
<body>
-
<table>
-
<tr>
-
<td>@Html.LabelFor(m => m.Name)</td>
-
<td>
-
@Html.EditorFor(m => m.Name)
-
</td>
-
</tr>
-
<tr>
-
<td>@Html.LabelFor(m => m.Gender)</td>
-
<td>
-
@Html.EditorFor(m => m.Gender)
-
</td>
-
</tr>
-
<tr>
-
<td>@Html.LabelFor(m => m.Education)</td>
-
<td>
-
@Html.EditorFor(m => m.Education)
-
</td>
-
</tr>
-
<tr>
-
<td>@Html.LabelFor(m => m.Departments)</td>
-
<td>
-
@Html.EditorFor(m => m.Departments)
-
</td>
-
</tr>
-
<tr>
-
<td>@Html.LabelFor(m => m.Skills)</td>
-
<td>
-
@Html.EditorFor(m => m.Skills)
-
</td>
-
</tr>
-
</table>
-
</body>
-
</html>
怎么做的呢? 这个MvcApp.Models.Employee 又是什么呢?为什么会很神奇的变成一堆 各种各样的 list 控件呢?
-
namespace MvcApp.Models
-
{
-
public class Employee
-
{
-
[DisplayName("姓名")]
-
public string Name { get; set; }
-
-
[RadioButtonList("Gender")]
-
[DisplayName("性别")]
-
public string Gender { get; set; }
-
-
[DropdownList("Education")]
-
[DisplayName("学历")]
-
public string Education { get; set; }
-
-
[ListBox("Department")]
-
[DisplayName("所在部门")]
-
public IEnumerable<string> Departments { get; set; }
-
-
[CheckBoxList("Skill")]
-
[DisplayName("擅长技能")]
-
public IEnumerable<string> Skills { get; set; }
-
}
-
}
看到这里对C# 和 .net 熟悉的同学一定心理有点谱了吧,特性!哦原来全是通过特性反射的呀。那又是如何反射的呢?
ListAttribute 继承了IMetadataAware 接口 然后MVC框架在创建View Model 时就会触发 事件 OnMetaDataCreated。
接着MVC 框架再通过 TemplateHint 确定了各个特性会对应的子模板,这里完全是通过名称的映射一一对应的。
然后再在模板中通过代码@Html.DropDownList("", listName, Model)
去调用对自定义的对HtmlHelper 的扩展方法 DropDownList,然后在这个扩展方法中再去取得需要的列表数据IEnumerable<ListItem>,再根据这个列表数据来构建需要的List<SelectListItem>
最后再调用已有的htmlHelper.DropDownList(name, selectListItems); 返回了需要的MvcHtmlString
整个扩展到此完毕。
同时还有许多疑点可以深究。
比如@Html.DropDownList("", listName, Model) 这段代码的第一个参数,到底起了什么作用呢?为什么是个空值呢?
通过实际测试我发现在赋空值和非空的情况下生成的HTML 有如下区别。
-
"" 参数
-
<tr>
-
<td><label for="Education">学历</label></td>
-
<td>
-
<select id="Education" name="Education"><option value="H">高中</option>
-
<option value="B">大学本科</option>
-
<option selected="selected" value="M">硕士</option>
-
<option value="D">博士</option>
-
</select>
-
</td>
-
</tr>
-
"Test" 参数
-
<tr>
-
<td><label for="Education">学历</label></td>
-
<td>
-
<select id="Education_test" name="Education.test"><option value="H">高中</option>
-
<option value="B">大学本科</option>
-
<option selected="selected" value="M">硕士</option>
-
<option value="D">博士</option>
-
</select>
-
</td>
-
</tr>
具体为何会有如上区别,请去研究代码看书吧。
玩Asp.net MVC 的同学 你真的发挥出 Asp.net MVC 这个框架的强大威力了么?