• ASP.NET MVC必知必会知识点总结(二)


    一、实现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),在此不再说明。

  • 相关阅读:
    Java IO<2> 输入/输出流 FileInputStream/FileOutputStream
    springcloud1
    Java IO<4>Java io与装饰器模式
    springcloud2
    操作系统——第四章课后习题答案01
    操作系统学习笔记_04
    不夸张地说,在程序员里面,我算得上玩EXCEL比较溜的!
    IIS 发布 Vue2 + Net Core Api
    算法
    《无垠的太空(9).利维坦陨落》插曲:梦中人(2)
  • 原文地址:https://www.cnblogs.com/zuowj/p/4772709.html
Copyright © 2020-2023  润新知