• ASP.NET MVC3 系列教程 控制器 & 视图


    I:控制器和视图的基础概念

    1.控制器的概念

    控制器在ASP.NET MVC3当中是最终处理客户端请求的一个实现,他有个一硬性条件就是必须实现System.Web.Mvc.IController接口,而且类的命名必须要以Controller结尾,尽管按照硬性条件上来说,要自己实现一个接口比较纠结,但幸好的是在ASP.NET MVC3内部已经包含了一个默认的实现,我们只需要把类的命名设置为Controller结尾然后继承System.Web.Mvc.Controller类,立刻就可以轻松地实现了IController接口了.如果你不喜欢这种默认提供的实现方式,而是自己去实现IController的话.下面的代码可以做一个简单的参考:

    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace MvcApplication1.Controllers
    {
        public class NoDefaultController : IController
        {
            void IController.Execute(RequestContext requestContext)
            {
                var httpContext = requestContext.HttpContext;
    
                var response = httpContext.Response;
    
                response.ContentType = "text/html; charset=utf-8";
    
                response.Write("自己的简单实现! Hello World");
            }
        }
    }
    

    请注意:控制器类不硬性要求放在*.Controllers命名空间中
    image

        如果是使用继承默认的类去实现的话代码如下:

    using System.Web.Mvc;
    
    namespace MvcApplication1
    {
        public class HelloController : Controller
        {
            public ActionResult Index()
            {
                return Content("默认的实现! Hello World");
            }
        }
    }
    

    效果图我就不发了.大家可以手动试一试.

    2.视图的概念

    视图的理解比较简单.你可以把视图理解为*.aspx或*.cshtml的文件.但是不是所有的aspx, cshtml文件都可以作为视图,它们必须得属于某一个以控制器名称命名的文件夹当中,而且要按照约定去存放到路径 ~/Views/{controller}/View.cshtml.
    另外视图还包含解析他的ViewEngine(视图引擎),本文在这里不涉及这个高级话题.
    image

    我们可以看出在~/Views/{controller}/View.cshtml中的{controller}并不需要像类命名那样以Controller结尾去做文件夹名称.

    3.工作原理图
    image
    当然,内部的工作原理会比这个图复杂得多.在此也仅仅是让大家有个了解而已!如有错误请指出.谢谢!

    提示:MvcHandler实现了IHttpAsyncHandler, IHttpHandler, IRequiresSessionState这三个接口,我在Debug进去的时候发现都是走异步的路线.对于这个处理方式,了解的人希望可以为我解答一下!

    II:控制器

    1.操作方法

    操作方法的含义是指在继承了System.Web.Mvc.Controller类中所定义的返回值的类型可以兼容ActionResult的方法.

    using System.Web.Mvc;
    
    namespace MvcApplication1.Controllers
    {
        public class HomeController : Controller
        {
            ///<summary>
            /// Hi, 我是Index操作方法
            ///</summary>
            ///<returns></returns>
            public ActionResult Index()
            {
                ViewBag.Message = "Welcome to ASP.NET MVC!";
    
                return View();
            }
    
            ///<summary>
            /// 厄, 我是About操作方法
            ///</summary>
            ///<returns></returns>
            public ActionResult About()
            {
                return View();
            }
    
            ///<summary>
            /// 可以为方法添加不是操作方法的特性
            ///</summary>
            ///<returns></returns>
            [NonAction]
            public string NonAction()
            {
                return "亲,不好意思噢.我不是操作方法噢,请不要乱调用噢!";
            }
        }
    }
    

    同时也可以使用[ActionName(“重命名操作方法”)]特性去重命名操作方法.

    [ActionName("NewActionName")]
    public ActionResult RenameAction()
    {
        return Content("利用特性换个马甲");
    }
    



    image

    2.操作方法的返回值类型的种类

    目前ASP.NET MVC3默认提供了11种ActionResult的实现
    在System.Web.Mvc命名空间
    ActionResult
      ContentResult
      EmptyResult
      FileResult
      HttpStatusCodeResult
        HttpNotFoundResult
        HttpUnauthorizedResult
      JavaScriptResult
      JsonResult
      RedirectResult
      RedirectToRouteResult
      ViewResultBase
        PartialViewResult
        ViewResult

    代码示例:

    using System.Web.Mvc;
    
    namespace MvcApplication1.Controllers
    {
        public class ActionResultController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult ContentResult()
            {
                return Content("Hi, 我是ContentResult结果");
            }
    
            public ActionResult EmptyResult()
            {
                //空结果当然是空白了!
                //至于你信不信, 我反正信了
                return new EmptyResult();
            }
    
            public ActionResult FileResult()
            {
                var imgPath = Server.MapPath("~/demo.jpg");
    
                return File(imgPath, "application/x-jpg", "demo.jpg");
            }
    
            public ActionResult HttpNotFoundResult()
            {
                return HttpNotFound("Page Not Found");
            }
    
            public ActionResult HttpUnauthorizedResult()
            {
                //未验证时,跳转到Logon
                return new HttpUnauthorizedResult();
            }
    
            public ActionResult JavaScriptResult()
            {
                string js = "alert(\"Hi, I'm JavaScript.\");";
    
                return JavaScript(js);
            }
    
            public ActionResult JsonResult()
            {
                var jsonObj = new
                {
                    Id = 1,
                    Name = "小铭",
                    Sex = "男",
                    Like = "足球"
                };
    
                return Json(jsonObj, JsonRequestBehavior.AllowGet);
            }
    
            public ActionResult RedirectResult()
            {
                return Redirect("~/demo.jpg");
            }
    
            public ActionResult RedirectToRouteResult()
            {
                return RedirectToRoute(new { 
                    controller = "Hello", action = "" 
                });
            }
    
            public ActionResult ViewResult()
            {
                return View();
            }
    
            public ActionResult PartialViewResult()
            {
                return PartialView();
            }
    
            //禁止直接访问的ChildAction
            [ChildActionOnly]
            public ActionResult ChildAction()
            {
                return PartialView();
            }
    
            //正确使用ChildAction
            public ActionResult UsingChildAction()
            {
                return View();
            }
        }
    }
    

    请注意,个别的操作方法结果在执行时,他们返回的HTTP状态码及ContentType有差别的.~另外如果要知道ContentType到底有多少种设置可参考

    3.操作方法的参数

    在本小节,我仅仅演示如何使URL参数映射到操作方法的参数,对于更复杂的用法,我将会留到 模型 的章节去讲解.

    首先我们需要先添加一个新的路由映射,然后在设置3个占位符参数,它们分别是p1, p2, p3.然后将p1约束为仅字母与数字的组合,p2约束为仅数字,p3没有添加约束.

    routes.MapRoute(
        "UsingParams",
        "p/{p1}/{p2}/{p3}",
        new { 
            controller = "Home", 
            action = "UsingParams"
        },
        new { p1 = "[a-z0-9]+", p2 = @"\d+" }
    );
    

    在添加一个Home控制器的操作方法

    public ActionResult UsingParams(string p1, int? p2, string p3)
    {
        string output = string.Empty;
        output += "p1 = " + (p1 ?? "null");
        output += "<br />p2 = " 
            + (p2.HasValue  p2.Value.ToString() : "没有值");
        output += "<br />p3 = " + (p3 ?? "null");
        return Content(output);
    }
    

    运行效果
    image

    这里在弄一个仿YouKu的URL路由设置
    image

    路由设置

    routes.MapRoute(
        "YouKu_Show",
        "v_{action}/id_{id}.html",
        new { controller = "YouKu" },
        new { id = "[a-z0-9]{13}" },
        new string[] { "MvcApplication1.YouKu" }
    );
    
    routes.MapRoute(
        "YouKu_PlayList",
        "v_{action}/{id}.html",
        new { controller = "YouKu" },
        new { id = "[a-z0-9]{12}" },
        new string[] { "MvcApplication1.YouKu" }
    );
    

    详细代码文末会放出.

    III:视图

    1.视图的语法在很早的时候我已经写过一篇文章了.在此就略过不提.

    2.视图与控制器之间如何进行数据交互

    在前面的接触当中,我们已经对控制器和视图有一定的了解了.接着,我们将要了解他们之间的几种常用的数据交互方式.注意:ASP.NET MVC不存在IsPostBack.如果你需要把WebForm和MVC相结合.那么很抱歉,我个人非常反对这种方式.因为选择MVC的主要原因就是不希望再与runat=server打交道(当然你用ASP.NET开发而不去runat=server的话,是可以实现的).另一点MVC也方便测试.~在过去,如果你要对ASP.NET进行测试,我们可以设想一下,对每个需要测试的runat=server的服务器控件去设置一个预设值的话,由于属性繁多,复杂程度已经可想而知了.另外从根源上并不能保证都能发现所有问题.~或许我的这个测试ASP.NET的猜想根本不成立.而测试的时候往往还需要每Builder一次,然后对需要测试的页面逐个测试检查什么按钮之类的..OK,这些伤心事就不在提了.下面介绍下MVC下的数据交互有那几种方式.

    2.1 ASP.NET MVC不在有IsPostBack,如何实现处理GET,POST?
    首先我帖出一段简单的代码去为你展示ASP.NET MVC3下处理GET, POST的方式

    //默认是处理Get请求,当然你也可以显式添加
    [HttpGet]
    public ActionResult UsingViewBag()
    {
        return View();
    }
    
    //显式将操作方法设置处理Post请求
    [HttpPost]
    public ActionResult UsingViewBag(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
        {
            ViewBag.Msg = inputBlank;
        }
        else
        {
            ViewBag.Msg = "你输入了: " + input;
        }
    
        return View();
    }
    

    在这里你会发现在ASP.NET MVC下是用[Http*]或[AcceptVerbs(HttpVerbs.*)]特性去实现类似WebForm下的IsPostBack.

    2.2 ASP.NET MVC3的数据交互方式种类

    A:ASP.NET原生的Request,Response.

    System.Web.Mvc.Controller的成员:HttpContext, Request, Response, Session, User都跟WebForm下的类似.

    Request.QueryString,Request.Form,Request.Cookies,RouteData.Values等.

    B:ASP.NET MVC3自带的ViewData,ViewBag,TempData

    using System.Web.Mvc;
    
    namespace MvcApplication1.Controllers
    {
        public class ParamsController : Controller
        {
            string inputBlank = "你输入了空白";
    
            public ActionResult Index()
            {
                return View();
            }
    
            //默认是处理Get请求,当然你也可以显式添加
            [HttpGet]
            public ActionResult UsingViewBag()
            {
                return View();
            }
    
            //显式将操作方法设置处理Post请求
            [HttpPost]
            public ActionResult UsingViewBag(string input)
            {
                if (string.IsNullOrWhiteSpace(input))
                {
                    ViewBag.Msg = inputBlank;
                }
                else
                {
                    ViewBag.Msg = "你输入了: " + input;
                }
    
                return View();
            }
    
            public ActionResult UsingViewData()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult UsingViewData(string input)
            {
                if (string.IsNullOrWhiteSpace(input))
                {
                    ViewData["msg"] = inputBlank;
                }
                else
                {
                    ViewData["msg"] = "你输入了: " + input;
                }
    
                return View();
            }
    
            public ActionResult UsingTempData()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult UsingTempData(string input)
            {
                if (string.IsNullOrWhiteSpace(input))
                {
                    TempData["msg"] = inputBlank;
                }
                else
                {
                    TempData["msg"] = "你输入了: " + input;
                }
    
                return View();
            }
        }
    }
    
    

    更详细的讨论,或许得另写一遍文章了.下一篇写Model,另外关于@Html的扩展方法,我打算另外写一篇去介绍.

    IV:源代码下载

    image
    下载源代码
    End….Thanks!

    作者的文章帮助很大
    声明: 本文版权归作者dotNetDR_和博客园共有,转载必须保留此段声明。
    Service and Support: 点击这里给我发消息
    ASP.NET MVC 4.0-II群  cnblogs_码农
  • 相关阅读:
    Nop中的Cache浅析
    使用DapperExtensions实现简单仓储
    使用nodejs爬取拉勾苏州和上海的.NET职位信息
    使用Microsoft Fakes进行单元测试(2)
    使用Microsoft Fakes进行单元测试(1)
    小程序之滚动到页面底部
    小程序之动态修改页面标题
    小程序之面试题
    小程序之公共组件的开发
    小程序之web-view打开外部链接
  • 原文地址:https://www.cnblogs.com/highend/p/aspnet_mvc3_controller_and_view.html
Copyright © 2020-2023  润新知