MVC中Area的另一种用法
【摘要】本文只是为一行代码而分享
context.MapRoute("API", "api/{controller}/{action}", new { }, newstring[] { "CNBlogs.UcHome.Web.Controllers.Api" });
我们在ASP.NET MVC中使用Area时通常这么干:
在Web项目中创建Areas文件夹,在其中创建对应的Area文件夹,在其下创建Controllers文件夹。然后在Area文件夹中创建AreaRegistration的子类用于注册Area路由,在Controllers文件夹中创建所需的Controller。

这么干有个前提,就是你的Web项目类型要是WebApplication。
而我们所处的场景是:Web项目类型是WebSite。之前在使用MVC时,将所有的Controller放在了一个单独的类库项目中。

我们今天有一个需求,需要用area来解决。为什么要用area?举个例子来说明。
比如我们在页面中添加网摘时,访问的网址是 home.cnblogs.com/wz/add ,而供其他应用调用网摘API的网址是 home.cnblogs.com/api/wz/add 。这里的wz对应的控制器名称都是WzController,Action都是add,实际也的确存在两个WzController,放在不同的文件夹中。如上图,一个在项目根文件夹,一个在Api文件夹。所以在网址中通过api前缀路径来区分,在程序中也要让ASP.NET路由找到对应的Controller。
这时Area就发挥作用了,但由于Conroller不在Web项目中,所以要找其他方法解决这个问题。方法来自Migrating a large web application to ASP.NET MVC(关键在最后一行代码):
When AreaRegistration.RegisterAllAreas() is called, ASP.NET will search for all AreaRegistration subclasses in all assemblies in the bin dir so that we do not have to modify the global.asax when we add new areas.
In the AreaRegistration subclass, we would do something like:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Services",
"Sub1/Sub11/Sub111/{controller}.mvc/{action}/{id}",
new { action = "Index", id = "" },
new string[] { "My.Custom.Namespace.Controllers" }
);
}
AreaRegistration.RegisterAllAreas()是global.asax中调用的,它会找到所有的AreaRegistration的子类,不管是在Web项目中,还是在其他类库项目中。所以我们在CNBlogs.UcHome.Web.Controllers项目的Api文件夹中放一个AreaRegistration的子类,也是能被找到的,然后在注册Area时,在参数中传递Controller所在的命名空间,问题就解决了。

【更新】
虽然通过ApiArea解决了api的路由问题,但是这时我们访问非api的路径(比如/wz/my),出现下面的错误:
Multiple types were found that match the controller named 'wz'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'wz' has found the following matching controllers:
CNBlogs.UcHome.Web.Controllers.Api.WzController
CNBlogs.UcHome.Web.Controllers.WzController
也就是说,如果有两个同名的Controller,必须在路由时指定命名空间,routes.MapRoute的第5个参数就是用于指定命名空间,我开始时不知道有这个参数,于是试图用Area来解决问题,实际是一个错误的解决方法,正确的解决方法是在Global.asax中针对不同的命名添加两个不同的路由,示例代码如下:

routes.MapRoute("API",
"api/{controller}/{action}",
new { },
null,
new string[] { "CNBlogs.UcHome.Web.Controllers.Api" }
);
routes.MapRoute("DefaultMvc",
"{controller}/{action}/{id}",
new { id = UrlParameter.Optional },
null,
new string[] { "CNBlogs.UcHome.Web.Controllers" }
);

MVC中Area的另一种用法的更多相关文章
- ASP.NET MVC中Area的另一种用法
ASP.NET MVC中Area的另一种用法 [摘要]本文只是为一行代码而分享 context.MapRoute("API", "api/{controller}/{ac ...
- mysql中模糊查询的四种用法介绍
下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...
- Spring MVC 中获取session的几种方法
Spring MVC 中使用session是一种常见的操作,但是大家上网搜索一下可以看到获取session的方式方法五花八门,最近,自己终结了一下,将获取session的方法记录下来,以便大家共同学习 ...
- Spring MVC中forward请求转发2种方式(带参数)
Spring MVC中forward请求转发2种方式(带参数) http://www.51gjie.com/javaweb/956.html
- 下面介绍mysql中模糊查询的四种用法:
下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...
- MVC中Area的使用
1.Area是什么? MVC 2 中引进了区域的概念,它允许将模型,视图和控制器分成单独的功能节点,换句话说,可以在大型复杂的网站中建立几个区域(模块),每一个区域都有Model,View,Contr ...
- JSP中的include的两种用法
1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...
- java中 this 关键字的三种用法
Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...
- python 中 dict 的另一种用法
python 中 dic另一种用法 描述 Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值. 语法 dict={} dict.get(k1,Non ...
随机推荐
- js作用域对象与运用技巧
1. JS作用域 1.1 全局作用域和局部作用域 函数外面声明的就是 全局作用域 函数内是局部作用域 全局变量可以直接在函数内修改和使用 变量,使用var是声明,没有var是使用变量. 如果在函数内使 ...
- 在XC2440上实现使用U盘自动更新系统的uboot
转:http://blog.chinaunix.net/uid-22030783-id-3347599.html 此版本uboot在XC2440_uboot_V1.3版本上修改得来,是为我们的一个大客 ...
- UltraISO(软碟通)制作安装Ubuntu系统的U盘安装盘
1.开UltraISO(软碟通),加载要写入U盘的iso文件,注意,要求软碟通的版本是9.3以上的.如下图: 2.点击“启动光盘.写入硬盘映像: 3.开启个写入硬盘映像的窗口,硬盘驱动器那一项看清楚是 ...
- java多线程之Concurrent包
1.在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题. 2.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的 ...
- Android客户端面试题集锦
声明:本文问题来自但不限于Xoper.ducky大牛的面试总结,网址:http://www.nowcoder.com/discuss/3043,欢迎各位进行补充 JAVA SE 1. 九种基本数据类型 ...
- 解决kylin报错:java.lang.IllegalStateException
一个kylin build job执行到第三步Extract Fact Table Distinct Columns时报错: 2017-05-24 20:04:07,930 ERROR [pool-9 ...
- jquery动态添加表单数据
动态添加用户 实现代码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html ...
- Dockerfile减少构建镜像大小的方法
这几天基于Dockerfile构建应用需要的特殊的镜像,比如Nginx需要add很多module的,就需要在镜像内编译和做build. 通过Dockerfile构建镜像时,很容易把镜像构建得很大. 从 ...
- 3D游戏图形技术解析(7)——视差映射贴图(Parallax Mapping)【转】
http://www.cnblogs.com/taotaobujue/articles/2781371.html 视差映射贴图(Parallax Mapping) ● 传统纹理贴图的弊端 纹理贴图大家 ...
- asp.net 大文上传配置
配置iis的文件上传大小控制: 今天先说一个问题,在window server2008 下配置上传文件的大小,除了工程自身的config外还需要配置一下服务器上的applicationhost.con ...