返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

时间:2022-03-13 04:37:03

原文:返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

[索引页]

[源码下载]

返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

作者:webabcd





介绍

asp.net mvc 之 Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

  • Action Filter - 在 Controller 层对信息做过滤。如何实现自定义的 Action Filter
  • UpdateModel -  根据参数自动为对象的属性赋值
  • ModelBinder - 定义如何绑定 Model,DefaultModelBinder 实现了 IModelBinder ,其可以根据名称自动将参数赋值到对象对应的属性上
  • Ajax -  在 asp.net mvc 中使用 ajax
  • Unit Test -  在 asp.net mvc 中使用单元测试

示例

1、asp.net mvc 自带的 Action Filter 的演示

FilterDemoController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; using MVC.Models; namespace MVC.Controllers
{
    // HandleError - 出现异常时跳转到 Error.aspx(先在指定的 view 文件夹找,找不到再在 Shared 文件夹下找)
    // 需要 web.config 配置 - <customErrors mode="On" />
    [HandleError]
    public class FilterDemoController : Controller
    {
        // 每一个 Filter 都有一个 Order 属性,其用来指定 Filter 的执行顺序         // [NonAction] - 当前方法为普通方法,不解析为 Action         // [AcceptVerbs(HttpVerbs)] - 调用该 Action 的 http 方法
        // HttpVerbs 枚举成员如下: HttpVerbs.Get, HttpVerbs.Post, HttpVerbs.Put, HttpVerbs.Delete, HttpVerbs.Head         ProductSystem ps = new ProductSystem();         // ActionName() - Action 的名称。默认值同方法名称
        [ActionName("Product")]         // ValidateInput() - 相当于 @ Page 的 ValidateRequest, 用于验证请求中是否存在危险代码。可防止 XSS 攻击。默认值为 true
        [ValidateInput(false)]
        public ActionResult Details(int id)
        {
            var product = ps.GetProduct(id);             return View("Details", product);
        }         // ValidateAntiForgeryToken() - 避免 CSRF 攻击(需要视图页面中使用 Html.AntiForgeryToken())。原理:生成一个随机字符串,将其同时写入 cookie 和 hidden,当 form 提交到 action 时,验证二者是否相等并且验证提交源是否是本站页面(详查 asp.net mvc 的源代码)
        // 拼 sql 的时候防止 sql 注入:使用 @Parameter 的方式
        [ValidateAntiForgeryToken()]
        public ActionResult ValidateAntiForgeryTokenTest()
        {
            return Content("ValidateAntiForgeryToken");
        }         // OutputCache() - 缓存。Duration - 缓存秒数。VaryByParam - none, *, 多个参数用逗号隔开
        [OutputCache(Duration = 10, VaryByParam = "none")]
        // [OutputCache(CacheProfile = "MyCache")] - 通过配置文件对缓存做设置。可以参看 http://www.cnblogs.com/webabcd/archive/2007/02/15/651419.html
        public ActionResult OutputCacheDemo()
        {
            return Content(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
        }         public ActionResult HandleErrorDemo()
        {
            throw new Exception("HandleErrorDemo");
        }         // Authorize() - 验证。走的是 membership
        [Authorize(Users = "user")]
        // [Authorize(Roles = "role")]
        // Request.IsAuthenticated - 返回一个 bool 值,用于指示请求是否通过了验证
        public ActionResult AuthorizeDemo()
        {
            return Content("Authorize");
        }         // 自定义的 Action Filter 的 Demo
        [MyFilter()]
        public ActionResult MyFilterDemo()
        {
            return Content("MyFilterDemo" + "<br />");
        }
    }
}

自定的 Action Filter 的实现

MyFilter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.Web.Mvc; namespace MVC
{
    /**//// <summary>
    /// 自定义的 Action Filter,需要继承 ActionFilterAttribute
    /// </summary>
    public class MyFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext.Current.Response.Write("OnActionExecuting" + "<br />");
        }         public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            HttpContext.Current.Response.Write("OnActionExecuted" + "<br />");
        }         public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            HttpContext.Current.Response.Write("OnResultExecuting" + "<br />");
        }         public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            HttpContext.Current.Response.Write("OnResultExecuted" + "<br />");
        }
    }
}

Details.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC.Models.Products>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% Html.BeginForm("ValidateAntiForgeryTokenTest", "FilterDemo"); %>
    <%= Html.AntiForgeryToken() %>
    <h2>
        Details</h2>
    <p>
        <strong>ProductID:</strong>
        <%= Html.Encode(Model.ProductID) %>
    </p>
    <p>
        <strong>ProductName:</strong>
        <%= Html.Encode(Model.ProductName) %>
    </p>
    <p>
        <input type="submit" name="btnSubmit" value="submit" />
    </p>
    <% Html.EndForm(); %>
</asp:Content>

2、应用 UpdateModel 的 Demo

UpdateModelController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; namespace MVC.Controllers
{
    public class UpdateModelController : Controller
    {
        public ActionResult Details(string name, int age)
        {
            User user = new User();             // UpdateModel() 和 TryUpdateModel() - 系统根据参数自动为对象的属性赋值             base.UpdateModel(user); // 失败抛异常
            // base.TryUpdateModel(user); // 失败不抛异常             ViewData.Model = user;             return View();
        }
    }
}

Details.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC.Controllers.User>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        Details</h2>
    <p>
        <strong>UserId:</strong>
        <%= Model.ID %>
    </p>
    <p>
        <strong>Name:</strong>
        <%= Model.Name%>
    </p>
    <p>
        <strong>Age:</strong>
        <%= Model.Age%>
    </p>
</asp:Content>

3、演示什么是 ModelBinder

ModelBinderController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; namespace MVC.Controllers
{
    public class ModelBinderController : Controller
    {
        /**//// <summary>
        /// 路由过来的或者参数过来的,会自动地赋值到对象的对应的属性上
        /// 做这个工作的就是实现了 IModelBinder 接口的 DefaultModelBinder
        /// </summary>
        public ActionResult Details(User user)
        {
            base.ViewData.Model = user;             // ModelState - 保存 Model 的状态,包括相应的错误信息等
            if (!base.ModelState.IsValid)
            {
                foreach (var state in ModelState)
                {
                    if (!base.ModelState.IsValidField(state.Key))
                        ViewData["errorMsg"] = state.Key + "/" + state.Value.Value.AttemptedValue + "<br />";
                }
            }             return View();
        }
    }
}

Details.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        Details</h2>
    <% var model = ((MVC.Controllers.User)ViewData.Model); %>
    <p>
        <strong>UserId:</strong>
        <%= model.ID %>
    </p>
    <p>
        <strong>Name:</strong>
        <%= model.Name %>
    </p>
    <p>
        <strong>Age:</strong>
        <%= model.Age %>
    </p>
    <p>
        <strong>error:</strong>
        <%= ViewData["errorMsg"] %>
    </p>
</asp:Content>

4、使用 ajax 的 Demo

    <p>
        Ajax
        
        <script src="http://www.cnblogs.com/Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>
        <script src="http://www.cnblogs.com/Scripts/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
                       
        <br />
        
        <!-- AjaxHelper 简要说明 -->
        <%= Ajax.ActionLink(
                "ProductId 为 1 的详情页",
                "Details",
                "Product",
                new { id = 1 },
                new AjaxOptions { UpdateTargetId = "ajax" }
            )
        %> 
    </p>
    <div id="ajax" />

5、在 VS 中做单元测试

ProductControllerTest.cs

using MVC.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Web.Mvc; using MVC.Models;
using System.Collections.Generic; namespace MVC.Tests
{
    /**//// <summary>
    ///这是 ProductControllerTest 的测试类,旨在
    ///包含所有 ProductControllerTest 单元测试
    ///</summary>
    [TestClass()]
    public class ProductControllerTest
    {
        private TestContext testContextInstance;         /**//// <summary>
        ///获取或设置测试上下文,上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }         附加测试属性#region 附加测试属性
        // 
        //编写测试时,还可使用以下属性:
        //
        //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //使用 TestInitialize 在运行每个测试前先运行代码
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //使用 TestCleanup 在运行完每个测试后运行代码
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion         /**//// <summary>
        ///Index 的测试
        ///</summary>
        // TODO: 确保 UrlToTest 属性指定一个指向 ASP.NET 页的 URL(例如,
        // http:///Default.aspx)。这对于在 Web 服务器上执行单元测试是必需的,
        //无论要测试页、Web 服务还是 WCF 服务都是如此。
        [TestMethod()]
        [HostType("ASP.NET")]
        [AspNetDevelopmentServerHost("C:\\MVC\\MVC", "/")]
        [UrlToTest("http://localhost:2005/")]
        public void IndexTest()
        {
            ProductController target = new ProductController(); // TODO: 初始化为适当的值
            int pageIndex = 0; // TODO: 初始化为适当的值             ViewResult actual;
            actual = target.Index(pageIndex) as ViewResult;             Assert.AreNotEqual(actual.ViewData.Model as List<Products>, null);
        }
    }
}

OK

[源码下载]

返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test的更多相关文章

  1. ASP&period;NET MVC的Action Filter

    一年前写了一篇短文ASP.NET MVC Action Filters,整理了Action Filter方面的资源,本篇文章详细的描述Action Filter.Action Filter作为一个可以 ...

  2. 理解ASP&period;NET MVC Framework Action Filters

    原文:http://www.cnblogs.com/darkdawn/archive/2009/03/13/1410477.html 本指南主要解释action filters,action filt ...

  3. 返璞归真 asp&period;net mvc &lpar;3&rpar; - Controller&sol;Action

    原文:返璞归真 asp.net mvc (3) - Controller/Action [索引页] [源码下载] 返璞归真 asp.net mvc (3) - Controller/Action 作者 ...

  4. ASP&period;NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁

    在开发程序的过程中,稍微不注意就会隐含有sql注入的危险.今天我就来说下,ASP.NET mvc 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁.不用每下地方对参数的值都进行检 ...

  5. 返璞归真 asp&period;net mvc &lpar;13&rpar; - asp&period;net mvc 5&period;0 新特性

    [索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...

  6. 返璞归真 asp&period;net mvc &lpar;7&rpar; - asp&period;net mvc 3&period;0 新特性之 Controller

    原文:返璞归真 asp.net mvc (7) - asp.net mvc 3.0 新特性之 Controller [索引页][源码下载] 返璞归真 asp.net mvc (7) - asp.net ...

  7. 返璞归真 asp&period;net mvc &lpar;4&rpar; - View&sol;ViewEngine

    原文:返璞归真 asp.net mvc (4) - View/ViewEngine [索引页] [源码下载] 返璞归真 asp.net mvc (4) - View/ViewEngine 作者:web ...

  8. 返璞归真 asp&period;net mvc &lpar;1&rpar; - 添加、查询、更新和删除的 Demo

    原文:返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo [索引页] [源码下载] 返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo 作者 ...

  9. 返璞归真 asp&period;net mvc &lpar;10&rpar; - asp&period;net mvc 4&period;0 新特性之 Web API

    原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API [索引页][源码下载] 返璞归真 asp.net mvc (10) - asp.net ...

随机推荐

  1. System&period;Dynamic&period;ExpandoObject 类型的简单使用

    该类型可以实现的是动态添加属性和移除属性,有点类似 js 中对象的操作,非常灵活 static void Main(string[] args) { dynamic obj = new System. ...

  2. Description Resource Path Location Type Java compiler level does not match the version of the instal

    解决办法 在项目上右键Properties->Project Facets,在打开的Project Facets页面中的Java下拉列表中,选择相应版本. 有可能是java1.6 改成java6 ...

  3. CSS3 GRID LAYOUT

    CSS3 GRID LAYOUT http://www.w3cplus.com/blog/tags/356.html 中国首个开源 HTML5 跨屏前端框架 http://amazeui.org/

  4. ibeacon的使用和应用场景简单示例

    目的,用ibeacon实现签到功能,不需要太严谨,只是试水. 拿到ibeacon的第一感觉是,这东西能用嘛,2-3年的电池,后面商家说是用个3M双面胶找个地方一贴就行,感觉不太靠谱,嘿嘿,在网上找了一 ...

  5. js 操作COOKE备忘

    function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf( ...

  6. web运维第一篇&colon;nginx配置文件详解笔记

    #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...

  7. M - 非常可乐

    很明显看出来的广搜题目,不过因为有3个杯子相互倾倒,所以会产生6种倒发,比较冗杂,不过应该可以构造一个数组来解决这个问题,试试看吧 ////////////////////////////////// ...

  8. OSCache缓存框架介绍

          OSCache是一种开放性的JSP定制标记应用,由OpenSymphony设计,提供了在现有JSP页面之内实现快速内存缓冲的功能. OSCache是个一个广泛采用的高性能的J2EE缓存框架 ...

  9. POJ 2528 QAQ段树&plus;分离

    Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Submitcid=58236#statu ...

  10. 中文代码示例之Angular入门教程尝试

    原址: https://zhuanlan.zhihu.com/p/30853705 原文: 中文代码示例教程之Angular尝试 为了检验中文命名在Angular中的支持程度, 把Angular官方入 ...