ASP.NET MVC学习之视图篇(1)
一.前言
不知道还有多少读者从第一篇开始一直学习到如今,笔者也会一直坚持将ASP.NET MVC的学习完美的结束掉,然后开始写如何配合其他框架使用ASP.NET MVC的随笔。当然笔者后面的随笔如果没有特殊说明使用的都是ASP.NET MVC 4,因为笔者认为只要精通即可。
二.正文
1.自定义视图引擎
相信很多人都知道在控制器中一个动作方法返回一个View之后,ASP.NET MVC默认会到Views下对应的控制器名的文件夹下寻找和这个动作方法同名的视图(如果你指定了视图名则会按照你指定的视图名查找)。但是这中间是如何做到的呢?其实多亏ASP.NET MVC的灵活性强的特点,当你返回View之后,控制器会通过一组视图引擎去查找对应的页面,如果其中一个视图引擎返回了符合的视图则结束查找开始渲染视图。下面我们就开始分析上面这几个过程中涉及的接口有哪些。
首先是视图引擎,它要能够根据要求返回符合的视图(实现Iview接口),而视图引擎需要实现IViewEngine接口,IViewEngine接口代码如下所示:

1 public interface IViewEngine
2 {
3 ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
4 ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
5 void ReleaseView(ControllerContext controllerContext, IView view);
6 }

其中FindView是根据要求返回对应的视图,其中ControllerContext包含了控制器相关的数据,viewName则是视图的名称,useCache表示是否使用缓存,FindPartialView则是查找分布视图,最后一个ReleaseView则是释放页面对象。
这里我们可以看到FindPartialView与FindView都要求返回ViewEngineResult类型,而该类的构造函数有以下几种方式:
1 public ViewEngineResult(IEnumerable<string> searchedLocations); 2 public ViewEngineResult(IView view, IViewEngine viewEngine);
其中第一个是当未查找到时返回的,其中参数是表示该引擎查找了哪些路径,而第二个则是查找成功后返回的其中要求输入一个实现IView接口的对象,
第二个参数一般都是this,主要是用来最后调用视图引擎的ReleaseView方法的,到这里我们就要将视角转向IView接口,以下是该接口的代码:
1 public interface IView
2 {
3 void Render(ViewContext viewContext, TextWriter writer);
4 }
大家可以看到这接口的方法很少,只有一个Render,而这个方法就是负责最后生成页面html代码的,我们可以看到第一个参数是ViewContext,这个参数包含了控制器传递到视图中的参数,比如ViewBag,ViewData等,而第二个参数是用来写入html代码的。下面我们简单的举一个小例子。
首先我们创建一个实现IView接口的对象:

1 namespace MvcStudy.View
2 {
3 public class CustomView : IView
4 {
5 public void Render(ViewContext viewContext, System.IO.TextWriter writer)
6 {
7 writer.Write("from custom view");
8 }
9 }
10 }

这里我们直接输出了一个字符串。接着我们还要实现IViewEngine接口:

1 namespace MvcStudy.View
2 {
3 public class CustomViewEngine : IViewEngine
4 {
5
6 public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
7 {
8 return new ViewEngineResult(new string[] { "Custom View Engine" });
9 }
10
11 public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
12 {
13 if (viewName.Equals("CustomView"))
14 {
15 return new ViewEngineResult(new CustomView(), this);
16 }
17 return new ViewEngineResult(new string[] { "Custom View Engine" });
18 }
19
20 public void ReleaseView(ControllerContext controllerContext, IView view)
21 {
22
23 }
24 }
25 }

这里我们没有为分布视图进行查找,而仅仅只是实现了FindView的查找,并且只有视图名为CutomView时才会返回对应的结果。
完成了上面的操作,最后我们还要将我们的视图引擎加入到视图引擎组中,下面我们在Global.asax的Application_Start中写入如下代码:
1 ViewEngines.Engines.Add(new CustomViewEngine ());
然后修改Home控制器中Index动作方法:

1 namespace MvcStudy.Controllers
2 {
3 public class HomeController : Controller
4 {
5 public ActionResult Index()
6 {
7 return View("CustomView");
8 }
9 }
10 }

最后我们运行该程序。最后我们将会看到页面输出了我们之前写的字符串,到此为止我们就能够自己创建自己的视图引擎了。
2.修改默认的查询路径
可能很多人发现ASP.NET MVC自带的Razor视图引擎非常好,并不想自己去实现视图引擎,而只是想修改查询的路径,比如把 ~/Views/[ConrollerName]/[ActionName].cshtml改成~/Views/[ControllerName]_[ActionName].cshtml这种形式,当然强大的ASP.NET MVC依然可以办到,因为Razor视图引擎的具体实现类是RazorViewEngine,我们可以继承这个类,并修改ViewLocationFormats属性,下面我们将上面的那种查询方式实现,首先我们新建一个CustomRazorViewEngine类,具体代码如下:

1 namespace MvcStudy.View
2 {
3 public class CustomRazorViewEngine : RazorViewEngine
4 {
5 public CustomRazorViewEngine()
6 {
7 ViewLocationFormats = new string[]{
8 "~/Views/{1}_{0}.cshtml",
9 "~/Views/Shared/{0}.cshtml"
10 };
11 }
12 }
13 }

其中的{0}和{1}代表的是视图名称和控制器名称,如果读者还要修改区域,则{2}代表区域名称。
我们创建好了之后还要加入到视图引擎中(仍然在Global.asax中写入的Application_Start事件中写入):
1 ViewEngines.Engines.Clear(); 2 ViewEngines.Engines.Add(new CustomRazorViewEngine());
然后修改Home控制器的Index动作方法,将之前的传入到View中的参数删除,然后在Views下新建一个Home_Index.cshtml视图,重新运行改成程序。
3.视图中调用我们自己的方法
有时候视图中一些常用的功能我们都会响应的集中起来,生成一个工具类,但是在视图中调用的时候总是要写入整个命名空间十分麻烦,下面我们可以轻松的解决这个问题。
首先我们新建一个工具类:

1 namespace MvcStudy.Utility
2 {
3 public static class ShowHead
4 {
5 public static String Show()
6 {
7 return "<p>this is head</p>";
8 }
9 }
10 }

然后打开~/Views/Home/Index.cshtml视图,在顶部加上@using MvcStudy.Utility,然后我们就可以在下面写入@ShowHead.Show()了
当然我们也可以在Views下的Web.config中加入这个命名空间:

1 <namespaces> 2 <add namespace="System.Web.Mvc" /> 3 <add namespace="System.Web.Mvc.Ajax" /> 4 <add namespace="System.Web.Mvc.Html" /> 5 <add namespace="System.Web.Optimization"/> 6 <add namespace="System.Web.Routing" /> 7 <add namespace="MvcStudy.Utility"/> 8 </namespaces>

这样所有的视图都可以使用这个工具类了,但是读者的运行之后显示的不会是一个p标签,而是被转义之后的字符,这个是ASP.NET MVC为了方式XSS而设置了,所以这里还有一个问题要解决就是如何输出Html标签,而不会被转义,这里就需要使用MvcHtmlString类了,下面我们修改我们的工具类:

1 namespace MvcStudy.Utility
2 {
3 public static class ShowHead
4 {
5 public static MvcHtmlString Show()
6 {
7 return new MvcHtmlString("<p>this is head</p>");
8 }
9 }
10 }

我们看到返回的结果类型从String改成了MvcHtmlString,重新运行程序我们可以发现最后的输出没有被转义了。如果你需要直接输出Modal中的内容,而不想被转义则需要调用@Html.Raw(Model),这样就不会被转义了。
转自:http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_view_1.html
ASP.NET MVC学习之视图篇(1)的更多相关文章
- ASP.NET MVC学习之视图篇(2)
继ASP.NET MVC学习之视图(1)学习 4.HTML辅助器 虽然在ASP.NET MVC中我们已经摆脱了ASP.NET的控件,但是对于页面中需要循环标签的情况依然还是存在,可能很多人认为用for ...
- ASP.NET MVC学习之过滤器篇(2)
下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成 ...
- ASP.NET MVC学习之控制器篇扩展性
原文:ASP.NET MVC学习之控制器篇扩展性 一.前言 在之前的一篇随笔中已经讲述过控制器,而今天的随笔是作为之前的扩展. 二.正文 1.自定义动作方法 相信大家在开发过程一定会遇到动作方法的重名 ...
- ASP.NET MVC学习之控制器篇
一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MV ...
- ASP.NET MVC学习之过滤器篇(1)
一.前言 继前面四篇ASP.NET MVC的随笔,我们继续向下学习.上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面. 二.正文 以下的示例建立在ASP.NET MVC ...
- ASP.NET MVC学习之控制器篇(二)
原文链接:http://www.asp.net/learn/mvc/ 这篇教程探索了ASP.NET MVC控制器(controller).控制器动作(controller action)和动作结果(a ...
- ASP.NET MVC学习之路由篇(3)
根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...
- ASP.NET MVC学习之路由篇(2)
7.解决与物理路径的冲突 当发送一个请求至ASP.NET MVC时,其实会检查网站中存不存在这个请求的物理路径文件,如果存在的话,就会直接将这个物理文件返回.但是有时候我们需要它执行控制器的某个方法, ...
- ASP.NET MVC学习之路由篇(1)
1.基本路由 RouteConfig.cs: 1 public class RouteConfig 2 { 3 public static void RegisterRoutes(RouteColle ...
随机推荐
- jquery Ajax中的dataType简析
jquery中的ajax有好几种运用方式,但是基本上都是使用的$.ajax()方法,很多人经常会使用它来从后台获取json格式的数据,但是经常发现返回的json字符串并不能自动的转换成js里的json ...
- [leetcode]_Maximum Depth of Binary Tree
第三道树的题目,我还是不会,我擦,怎么递归算法还是不能很好理解.看来还得好好研究下递归算法. 题目:求一棵树的最大深度. 思路:递归地求取左子树最大深度 和 右子树最大深度,返回较大值即为 整棵树的 ...
- Silverlight学习之初始化参数
首先需要在Silverlight的宿主页面添加上initParams,如 <param name="initParams" value="key1=jerry,ke ...
- Java应用架构的演化之路
Java应用架构的演化之路 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互,所以我们首先需要知道各种系统之间是如何交互的,使用何种技术实现. 1. 不同系统不同语言之间的交互 现 在我们常见 ...
- 解决:JS如何取得当前正在执行的function的名字
代码如下 function getFName(fn){ return (/^[\s\(]*function(?:\s+([\w$_][\w\d$_]*))?\(/).exec(fn.toString( ...
- CentOS下安装LNMP(LINUX+NGINX+MYSQL+PHP)环境
一.安装Nginx最新版 首先查看是否有安装源包 yum list nginx (或yum info nginx) 如果没有则 vi /etc/yum.repos.d/nginx.repo #添加如 ...
- 室内净化ThinkPHP复习
"$_GET[id]"这个是和$_GET['id']一样的 foreach的是 name 和 item if(!empty($_GET['id'])){ $where.= &quo ...
- linux之I2C裸机驱动解析(转)
1 硬件特性 1.1 概述 I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和双向数据线(SDA).由于I2C总线仅需要两根线,因此在电路板上占用的空间更少, ...
- 宝马测试(C++实现)
测试目的:对编辑器放大,缩小性能测试. 测试资源:一匹宝马. 测试结果:良好. 实现方法:通过调用本地保存的宝马文件,逐字逐行的显示在编辑器中,并放大,缩小.对不同的符号进 ...
- [原创]PostgreSQL Plus Advanced Server监控工具PEM(三)
三.使用PEM Client 在PEM Client中连接PEM Server 点击上图所示的按钮或点击菜单-> 第一次连接PEM Server,会有一次导入证书的操作,点击Yes按钮. 接下来 ...