http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 3293|回复: 1

[Asp.Net] ASP.NET MVC中Area的另一种用法

[复制链接]
发表于 2013-1-11 09:44:37 | 显示全部楼层 |阅读模式
【摘要】本文只是为一行代码而分享
  1. 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:
  1. public override void RegisterArea(AreaRegistrationContext context)
  2. {
  3.     context.MapRoute(
  4.     "Services",
  5.     "Sub1/Sub11/Sub111/{controller}.mvc/{action}/{id}",
  6.     new { action = "Index", id = "" },
  7.     new string[] { "My.Custom.Namespace.Controllers" }
  8.     );
  9. }
复制代码
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中针对不同的命名添加两个不同的路由,示例代码如下:
  1. 【更新】

  2. 虽然通过ApiArea解决了api的路由问题,但是这时我们访问非api的路径(比如/wz/my),出现下面的错误:

  3. 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.

  4. The request for 'wz' has found the following matching controllers:
  5. CNBlogs.UcHome.Web.Controllers.Api.WzController
  6. CNBlogs.UcHome.Web.Controllers.WzController

  7. 也就是说,如果有两个同名的Controller,必须在路由时指定命名空间,routes.MapRoute的第5个参数就是用于指定命名空间,我开始时不知道有这个参数,于是试图用Area来解决问题,实际是一个错误的解决方法,正确的解决方法是在Global.asax中针对不同的命名添加两个不同的路由,示例代码如下:
复制代码


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2013-1-11 09:54:20 | 显示全部楼层
不错
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-5-3 10:35

© 2014-2021

快速回复 返回顶部 返回列表