zoukankan      html  css  js  c++  java
  • asp.net mvc 1.0(5) Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test(非原创)

    介绍

      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);
            }
        }
    }

     

  • 相关阅读:
    vmware centos 共赏目录不显示
    小程序上拉刷新
    chrome json接口数据 插件
    滚动条滚动事件
    smarty循环item命名规范
    css实现梯形样式(含有border)
    设置行高并不能垂直居中
    图片翻转交互效果
    smarty文章字符截取
    css动画 transition
  • 原文地址:https://www.cnblogs.com/GeneralXU/p/1517860.html
Copyright © 2011-2022 走看看