一、实现Controller的依赖注入:

1.自定义继承DefaultControllerFactory 类的控制器工厂类并重写GetControllerInstance方法;(如:InjectControllerFactory)

2.在Global.asax文件中的Application_Start方法中注册该控制器工厂类,示例如下:

ControllerBuilder.Current.SetControllerFactory(new InjectControllerFactory());

二、在Action方法中添加ActionName特性实现为其指定别名,或者添加NonAction以表明该方法并不会被路由匹配到,可通过继承ActionMethodSelectorAttribute抽象类并重写IsValidForRequest方法实现类似HttpGet、HttpPost、HttpPut、HttpDelete 和 NonAction 等自定义Action方法选择器

三、导步Controller:继承自AsyncController抽象类,并自定义异步Action方法(异步方法有两种:一种是XxxAsync/XxxCompleted,二种是Task返回值),具体实现详见:ASP.NET MVC下的异步Action的定义和执行原理

四、基本过滤器如下,可以通过实现相应接口来自定义过滤器

五、在View上动态添加或处理内容

1.内联代码(代码片段):如 @{ .. }或<% .. %>
2.Html helper方法:生成单个或多个HTML元素,如 Html.Label,Html.Editor等
3.Section:在指定的位置插入创建好的一部分内容(类似ASP.NET PlaceHolder),如 @section sectionName{ ...}
4.Partial view:存在于一个单独的视图文件中,作为子内容可在多个视图中共享,如 Html.Partial、Html.RenderPartial
5.Child action,相当于一个包含了业务逻辑的UI组件。当使用child action时,它调用 controller 中的 action 来返回一个view,并将结果插入到输出流中,如 Html.Action、Html.RenderAction

六、HTML Helper扩展方法:可直接生成相应的HTML元素,主要分为如下几类

1.链接类:在System.Web.Mvc.Html.LinkExtensions静态类包含生成各种链接的扩展方法;
2.表单类:在System.Web.Mvc.Html.FormExtensions静态类包含生成From元素的扩展方法;
3.输入类:在System.Web.Mvc.Html.InputExtensions静态类包含生成各种输入元素的扩展方法;
4.多文本输入类:在System.Web.Mvc.Html.TextAreaExtensions静态类包含生成TextArea元素的扩展方法;
5.选择类:在System.Web.Mvc.Html.SelectExtensions静态类包含生成各种选择元素的扩展方法;
6.动态编辑器模板类:在System.Web.Mvc.Html.EditorExtensions静态类包含依据要指定的类型来动态生成表单成员元素方法;

若要自定义HTML Helper动态编辑器模板类,可按照MVC约定,在 /Views/Shared/EditorTemplates 文件夹下创建相应的局部视图文件,示例代码如下:

//定义的HTML HELPER模板方法:
@model MvcApplication1.Models.Role

@Html.DropDownListFor(m => m, new SelectList(Enum.GetNames(Model.GetType()), Model.ToString()))

//View中使用:
@model MvcApplication1.Models.User

@Html.EditorFor(m => m.Role)

注意:模板类文件名需与成员类型名称相同,或在数据实体类中指定成员使用哪个类型自定义模板(如:[UIHint("Role")])

七、MVC视图中使用AJAX:

1.使用原生的Ajax或第三方类库(如:jQuery.ajax)

2. 使用 MVC Unobtrusive Ajax

A.在Web.config文件中配置启动 Unobtrusive Ajax(默认为启用)

    <appSettings>
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings> 

B.在调用的页面顶部引入相应的JS脚本文件,如下:

    <script src="~/Scripts/jquery-1.8.2.min.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>

C.最后采用Ajax.BeginForm来包裹表单成员,并为Ajax.BeginForm设置相应的参数

整个示例代码如下:

ACTION代码:

        public ActionResult Ajax()
        {
            return View();
        }

        public ActionResult GetPersons(string selectedRole)
        {
            IEnumerable<Person> persons = new[]{new Person(){FirstName="z", LastName="x",Role=Role.User},
            new Person(){FirstName="z1", LastName="x",Role=Role.Admin},
            new Person(){FirstName="z2", LastName="x",Role=Role.User},
            new Person(){FirstName="z3", LastName="x",Role=Role.Admin},
            new Person(){FirstName="z4", LastName="x",Role=Role.User}};

            if (selectedRole != "All")
            {
                persons = persons.Where(p => Enum.GetName(typeof(Role), p.Role) == selectedRole);
            }

            return PartialView(persons);

        }

VIEW代码:

//主视图Ajax

<h2>Ajax</h2>

<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

<table>
    <tbody id="result">

    </tbody>
</table>

@using (Ajax.BeginForm("GetPersons", new AjaxOptions() { UpdateTargetId = "result" }))
{
    <div>
        @Html.DropDownList("selectedRole", new SelectList(
            new[] { "All" }.Concat(Enum.GetNames(typeof(MvcApplication1.Models.Role)))))
        <button type="submit">Submit</button>
    </div>
}

//分部视图:GetPersons
@model IEnumerable<MvcApplication1.Models.Person>

@foreach (var p in Model)
{
    <tr>
        <td>@p.FirstName</td>
        <td>@p.LastName</td>
        <td>@p.Role</td>
    </tr>
}

八、Model Binding(模型绑定): 是 HTTP 请求和 Action 方法之间的桥梁,它根据 Action 方法中的 Model 类型创建 .NET 对象,并将 HTTP 请求的数据经过转换赋给该对象。

A.Model Binder(模型绑定器),顾名思义,可以形象的理解为将数据绑定到一个 Model 的工具。

MVC 框架内置默认的 Model Binder 是 DefaultModelBinder 类。当 Action Invoker 没找到自定义的 Binder 时,则默认使用 DefaultModelBinder。默认情况下,DefaultModelBinder 从如下 4 种途径查找要绑定到 Model 上的值:

Request.Form,HTML form 元素提供的值。
RouteData.Values,通过应用程序路由提供的值。
Request.QueryString,所请求 URL 的 query string 值。
Request.Files,客户端上传的文件。

B.绑定到复合类型(嵌套关联类型、可索引的类型等)需注意视图中表单成员的元素名称name必需符合可关联、可索引,示例如下:

//MODEL
public class Person {
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address HomeAddress { get; set; }
}
public class Address {
    public string City { get; set; }
    public string Country { get; set; }
}

//VIEW
@Html.EditorFor(m=> m.HomeAddress.Country)
//或

<input id="HomeAddress_Country" name="HomeAddress.Country" type="text" value="" />
//可索引类型的在VIEW写法
@Html.Editor("[" + i + "].Country")
//或
@Html.EditorFor(m => m[i].Country)
//或
<input   name="[0].Country" type="text" value="" />

当然如果不想这么麻烦也可以自己实现ModelBinder 类,然后在ACTION方法中显式指定ModelBinder,如下:

        public ActionResult Index([ModelBinder(typeof(CustomerModelBinder))]Person p)
        {
            return View();
        }

 九、Model验证的几种方法:

1.在Action方法中使用 ModelState 对Model对象的属性值自行判断合法性,如:

        public ActionResult UpdatePerson(Person p)
        {
            if (string.IsNullOrEmpty(p.FirstName))
            {
                ModelState.AddModelError("FirstName", "FirstName is not allow null!");
            }

            if (string.IsNullOrEmpty(p.LastName))
            {
                ModelState.AddModelError("LastName", "LastName is not allow null!");
            }

            if (ModelState.IsValid)
            {
                //执行更新
            }

            return View();
        }

2.在Model各属性上直接定义验证规则,然后DefaultModelBinder类会自动进行验证,如:

    public class Person
    {
        [Range(1,int.MaxValue)]
        public int PersonId { get; set; }

        [Required(ErrorMessage="请输入姓")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "请输入名")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "请完整输入地址")]
        public Address HomeAddress { get; set; }

        public Role Role { get; set; }
    }

3.通过继承ValidationAttribute抽象类并重写IsValid方法来自定义验证特性类(如下示例),然后使用方法与方法2相同

    public class MailAttribute:ValidationAttribute
    {
        public override bool IsValid(object value)
        {
            if(value==null) return false;
            var regex = new System.Text.RegularExpressions.Regex(@"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            return regex.IsMatch(value.ToString());
        }
    }

//MODEL的某个属性设置:

        [Mail(ErrorMessage="不是有效的电子邮箱地址")]
        public string EMail { get; set; }

4.MODEL自验证:让MODEL类实现IValidatableObject接口,在Validate方法进行验证判断,然后DefaultModelBinder类会自动进行验证,如:

    public class Computer:IValidatableObject
    {
        public string CPU { get; set; }

        public string MB { get; set; }

        public string MEM { get; set; }

        public string HDD { get; set; }

        public string Power { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var errors=new List<ValidationResult>();
            if (string.IsNullOrEmpty(CPU))
            {
                errors.Add(new ValidationResult("CPU is not allow null!"));
            }
            if (string.IsNullOrEmpty(MB))
            {
                errors.Add(new ValidationResult("MB is not allow null!"));
            }

            if (string.IsNullOrEmpty(MEM))
            {
                errors.Add(new ValidationResult("MEM is not allow null!"));
            }

            if (string.IsNullOrEmpty(Power))
            {
                errors.Add(new ValidationResult("Power is not allow null!"));
            }

            return errors;
        }
    }

以上验证默认是在提交到服务器端后再进行的验证,也可以开启客户端验证或远程验证(实现原理都是基于AJAX),在此不再说明。

ASP.NET MVC必知必会知识点总结(二)的更多相关文章

  1. 《MySQL必知必会》[01] 基本查询

    <MySQL必知必会>(点击查看详情) 1.写在前面的话 这本书是一本MySQL的经典入门书籍,小小的一本,也受到众多网友推荐.之前自己学习的时候是啃的清华大学出版社的计算机系列教材< ...

  2. 关于TCP/IP,必知必会的十个经典问题[转]

    关于TCP/IP,必知必会的十个问题 原创 2018-01-25 Ruheng 技术特工队   本文整理了一些TCP/IP协议簇中需要必知必会的十大问题,既是面试高频问题,又是程序员必备基础素养. 一 ...

  3. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  4. 读书笔记--SQL必知必会--建立练习环境

    书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL in 10 Minutes - Fourth Edition> MyS ...

  5. 读书笔记--SQL必知必会12--联结表

    12.1 联结 联结(join),利用SQL的SELECT在数据查询的执行中联结表. 12.1.1 关系表 关系数据库中,关系表的设计是把信息分解成多个表,一类数据一个表,各表通过某些共同的值互相关联 ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  8. 《SQL必知必会》学习笔记(一)

    这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...

  9. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  10. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术点,所以我称为必知必会.尽管这一系列是使用.NET/C# ...

随机推荐

  1. 返水bug-备用

    NOOK(N) CSBFB(25) off(Y) QQ(2652880032) G(1) off1(Y) QQ1(3479301404) G1(1) off2(Y) QQ2(309235846) G2 ...

  2. Oozie分布式任务的工作流——Sqoop篇

    Sqoop的使用应该是Oozie里面最常用的了,因为很多BI数据分析都是基于业务数据库来做的,因此需要把mysql或者oracle的数据导入到hdfs中再利用mapreduce或者spark进行ETL ...

  3. SQL语句全

    创建数据库 创建之前判断该数据库是否存在 if exists (select * from sysdatabases where name='databaseName') drop database ...

  4. [erlang]supervisor(监控树)的重启策略

    1. init函数 init() -> {ok, {SupFlags, [ChildSpec,...]}} | ignore. [ChildSpec,...] 是在init之后默认要启动的子进程 ...

  5. Python 实现发送、抄送邮件功能

    发送邮件 问题 在web.py中,如何发送邮件? 解法 在web.py中使用web.sendmail()发送邮件. web.sendmail('cookbook@webpy.org', 'user@e ...

  6. python默认的是17位小数的精度,但是这里有一个问题,就是当我们的计算需要使用更高的精度(超过17位小数)的时候该怎么做呢?

    1. 使用格式化(不推荐) 1 2 3 >>> a = "%.30f" % (1/3) >>> a '0.3333333333333333148 ...

  7. Android开发之Canvas rotate方法释疑

    Canvas的rotate()函数本应该是很简单的一个函数,但是由于api手册言之不详,使用中难免有吃不准的地方.下面所记录的几点,都是我在使用中所迷惑过的问题,特此记录. 1,坐标原点在哪里? 如果 ...

  8. journalctl --help

    journalctl [OPTIONS...] [MATCHES...] Query the journal. Flags:     --system              Show the sy ...

  9. linux如何修改主机名

    一:#hostname hn1 二:修改/etc/sysconfig/network中的 HOSTNAME=hn1三:修改/etc/hosts文件  127.0.0.1 hn1

  10. javascript中的removeEventListener失效问题

    一般现在我们用js绑定事件是 addEventListener(event,function,bool) event:事件的名称 字符串 如:'click', function: 事件处理的方法: b ...