在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加很快,难以管理,而且如果有不同业务模块有重复的控制器名的话,还需要尽量避免。引入Area的作用就是把控制器按照不同的业务模块进行区分,方便管理,而且控制器名称可以重名。

1、Web API项目引入Area进行分类

Area在项目中可以称之为区域,每个Area代表应用程序的不同功能模块,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Controller、View和Model,但对于管理也增加了一定的难度。如果是Web API项目,我们可以把不必要的目录移除即可,简化对目录的管理。
引入Area可以是我们不同的业务模块可以重名,而且各个业务模块管理起来也更加方便,在原先的Web API项目里面,它们的目录是这样的。

虽然我们把它们的目录归类,但是它们还是存放在一个命名空间下的。

namespace MyWebApi.Controllers

这样使用虽然也没有什么问题,但是还是存在一些弊端,因此引入Area的方式对不同业务模块的控制器进行管理,以达到我们分类管理的目的。
引入Area前,我们的API路径如下所示

http://localhost:9001/api/User

引入Area后,我们把常规的权限管理、字典管理等基础模块放到Framework的Area里面,那么这个时候API路径和具体的Area相关,地址则变成了如下:

http://localhost:9001/api/Framework/User

我们再来看看具体的项目目录,Web API项目中使用Area后,Controller的目录如下所示。

除了在各个不同Area下有不同的控制器,而且也增加了一个**AreaRegistration.cs的文件,如对应Framework的Area,有一个FrameworkAreaRegistration.cs文件
这样对应下面的控制器,它的命名空间如下所示。

namespace WebAPI.Areas.Framework.Controllers

2、Web API项目对Area控制器的路径映射

上面小节介绍了使用Area来对Web API控制器的分类管理,并介绍了引入Area后对控制器位置、命名空间、Web API的URL等方面的不同。这样如果我们要解析对应地址的Web API,那么也需要做一定的处理,否则是无法找到对应的控制器,从而出现错误信息。
首先我们需要修改Web API里面WebApiConfig的配置信息,如下所示。

上面指定了默认的Web API映射,并指定结果只做JSON格式的输出(移除XML输出)。
为了对不同的Area实现API的地址处理,我们先设计一个基类,然后让不同的Area注册类继承它,方便统一处理。

其中基类Area注册类的CustomAreaRegistration类代码如下所示。

有了上面的基类映射 RegisterArea函数,我们只需要在子类设置对应的AreaName基类实现不同Area子类的正确映射API路径处理了。

/// <summary>
/// 框架基础Area的注册类
/// </summary>
public class FrameworkAreaRegistration : CustomAreaRegistration
{
public override string AreaName
{
get
{
return "Framework";
}
}
}

当然为了实现对Area的Web API控制器的URL正确解析,获取属于Action、Controller、以及对应命名空间的对象,那么还需要在global.asa.cs里面添加一行代码,如下所示。

 //对Web API的Area进行支持
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new AreaHttpControllerSelector(GlobalConfiguration.Configuration));

其中AreaHttpControllerSelector是我们自定义的HTTP控制器地址解析器,需要根据我们的地址提取出具体的控制器、Area名称、程序集类型等,方便构建对应的解析器。

private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
{
var controllerName = base.GetControllerName(request); var areaName = GetAreaName(request);
if (string.IsNullOrEmpty(areaName))
{
return null;
} var type = GetControllerTypeByArea(areaName, controllerName);
if (type == null)
{
return null;
} return new HttpControllerDescriptor(_configuration, controllerName, type);
}

有了这些基础的管理,我们就可以定义好我们所需要Area,然后构建具体业务范畴下的控制器接口即可。

3、Web API在客户端的接口调用

所有的Web API地址,都是与具体的Area有关系,例如在Framework业务下的字典模块,它们Web API配置的地址如下所示。

<!--字典Web API模块配置-->

<add key="DictType" value="http://localhost:27206/api/Framework/DictType"/>

<add key="DictData" value="http://localhost:27206/api/Framework/DictData"/>

<add key="CorpDictData" value="http://localhost:27206/api/Framework/CorpDictData"/>

<add key="City" value="http://localhost:27206/api/Framework/City"/>

<add key="District" value="http://localhost:27206/api/Framework/District"/>

<add key="Province" value="http://localhost:27206/api/Framework/Province"/>

<add key="UserParameter" value="http://localhost:27206/api/Framework/UserParameter"/>

我们在客户端,只需要对Web API进行封装即可,这个部分可以使用Database2Sharp代码生成工具进行统一的生成,所有继承关系统一处理好,我们所做的就是进行新增接口的处理即可。
例如对于字典模块DictData的处理,它对于Web API的封装类如下所示。

/// <summary>
/// DictData, 基于API服务的Facade接口实现类
/// </summary>
public class DictDataCaller : BaseApiService<DictDataInfo>, IDictDataService

这个基类,默认封装了对常规数据表业务Web API接口方式的增删改查以及各种复杂的接口处理。
如果对于一般的Web API(非数据表业务),那么只需要继承的基类做调整即可。

/// <summary>
/// 基于API服务的Facade接口实现类
/// </summary>
public class TestCaller : NormalApiService, ITestService

这个NormalApiService基类,默认只是封装了对token和签名的读取处理,没有特殊的业务接口,具体特定的接口我们来实现处理。

对于WebAPI客户端的调用,我们主要就是需要构建对应的URL,然后通过GET传递或者POST传递一些参数,并读取HTML结果,把它解析为对应的类型数据即可,如下代码所示。

/// <summary>
/// 根据字典类型名称获取对应的字典记录
/// </summary>
/// <param name="dictTypeName">字典类型名称</param>
/// <returns></returns>
public List<DictDataInfo> FindByDictType(string dictTypeName)
{
var action = System.Reflection.MethodBase.GetCurrentMethod().Name;
string url = GetTokenUrl(action) + string.Format("&dictTypeName={0}", dictTypeName); List<DictDataInfo> result = JsonHelper<List<DictDataInfo>>.ConvertJson(url);
return result;
}

通过GetTokenUrl(action) 函数获取对应的URL地址,由于传入一个参数,接口这里没有发生数据修改,是GET方式提交参数数据,因此把参数附加在URL即可。
也就是下面代码实现了完整Web API地址的构建。

string url = GetTokenUrl(action) + string.Format("&dictTypeName={0}", dictTypeName);

构建好这些URL地址后,我们通过获取对应Web API的结果并进行序列号到具体对象即可。如下代码所示。

List<DictDataInfo> result = JsonHelper<List<DictDataInfo>>.ConvertJson(url);

关于Web API接口的设计文章,可以参考我的随笔。

通过以上的封装处理,那么对于业务表的Web API接口调用,具体使用客户端的代码如下所示。

var dictType = CallerFactory<IDictTypeService>.Instance.GetTree();
Console.WriteLine(dictType.ToJson()); var dictData = CallerFactory<IDictDataService>.Instance.GetAllDict();
Console.WriteLine(dictData.ToJson());

如果对于非数据表业务的Web API接口调用,具体使用客户端的代码如下所示。

var testAction = CallerFactory<ITestService>.Instance.TestAction();
Console.WriteLine(testAction.ToJson()); var test = CallerFactory<ITestService>.Instance.Test("");
Console.WriteLine(test.ToJson());

这样,不管是在Web项目里面,还是在Winform项目里面,或者在跨平台的IOS项目里面(或者安卓项目),都可以以相同的方式消费Web API,这样我们所有的数据入口在一个地方,可以集中业务接口的统一开发,并且可以有效管理我们的数据提供的性能问题,如统一缓存处理,统一权限处理...
感谢大家对本文章的细心阅读,希望对您的开发有所启发或帮助。

Web API项目中使用Area对业务进行分类管理的更多相关文章

  1. 在ASP.NET Web API项目中使用Hangfire实现后台任务处理

    当前项目中有这样一个需求:由前端用户的一个操作,需要触发到不同设备的消息推送.由于推送这个具体功能,我们采用了第三方的服务.而这个服务调用有时候可能会有延时,为此,我们希望将消息推送与用户前端操作实现 ...

  2. 在.net core web api项目中安装swagger展示api接口(相当于生成api文档)

    1,  建立或打开项目后,在“程序包管理器控制台”中执行以下命令添加包引用: Install-Package Swashbuckle.AspNetCore 2,在项目中打开Startup.cs文件,找 ...

  3. ASP.NET MVC & Web API项目中集成MEF

    1.实现方式 //WebApi需要实现的接口 System.Web.Http.Dependencies.IDependencyResolver //MVC需要实现的接口 System.Web.Mvc. ...

  4. 从ASP.Net Core Web Api模板中移除MVC Razor依赖项

    前言 :本篇文章,我将会介绍如何在不包括MVC / Razor功能和包的情况下,添加最少的依赖项到ASP.NET Core Web API项目中. 一.MVC   VS WebApi (1)在ASP. ...

  5. 在Docker容器中运行.Net Core web Api项目

    安装Docker环境 参考本人这篇<CentOS 7 下Docker的安装>文章进行安装以及环境配置,这里不做赘述. 通过.NetCore开发WebApi项目 1. 创建.Net Core ...

  6. 开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试

    在我们开发开发H5程序或者小程序的时候,有时候需要基于内置浏览器或者微信开发者工具进行测试,这个时候可以采用默认的localhost进行访问后端接口,一般来说没什么问题,如果我们需要通过USB基座方式 ...

  7. 【WEB API项目实战干货系列】- 导航篇(十足干货分享)

    在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, Android APP, IOS APP, iPad APP, Hybired APP, H5 Web共用共同的 ...

  8. 【WEB API项目实战干货系列】- WEB API入门(一)

    这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController.   创建 Web API 项目 在这里我们使用VS2013, .NET 4.5.1创建 ...

  9. 使用模板创建第一个Web API项目

    软件环境 vs 2015 update3 本节将通过例子讲述创建Web API 项目的方法 第一步,打开vs ,依次通过[文件]菜单,[新建][项目]命令,大致步骤如下图 :   第2步,在弹出对话框 ...

随机推荐

  1. 操作系统篇-分段机制与GDT|LDT

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言     在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...

  2. 破解SQLServer for Linux预览版的3.5GB内存限制 (UBUNTU篇)

    在上一篇中我提到了如何破解RHEL上SQLServer的内存大小限制,但是Ubuntu上还有一道检查 这篇我将会讲解如何在3.5GB以下内存的Ubuntu中安装和运行SQLServer for Lin ...

  3. 深入浅出JavaScript之原型链&继承

    Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...

  4. Function.prototype.toString 的使用技巧

    Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...

  5. App解读

    一直不懂别人口中说的原生开发.混合式开发.今天突然看了一篇文章讲解的是什么叫做原生App?移动 Web App?混合APP?分享给大家. 原生App是专门针对某一类移动设备而生的,它们都是直接安装到设 ...

  6. .NET基础拾遗(6)ADO.NET与数据库开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

  7. Linux下UPnP sample分析

        一.UPnP简介   UPnP(Universal Plug and Play)技术是一种屏蔽各种数字设备的硬件和操作系统的通信协议.它是一种数字网络中间件技术,建立在TCP/IP.HTTP协 ...

  8. ABP框架 - 值对象

    文档目录 本节内容: 简介 值对象基类 最佳实践 简介 “一个表示领域的一个描述性方面的没有概念上的身份对象,称为值对象.“(Eric Evans). 与一个有身份(Id)实体相反,一个值对象没有身份 ...

  9. Atitit ABI FFI 的区别与联系 attilax总结

    Atitit ABI FFI 的区别与联系 attilax总结 FFI stands for Foreign Function Interface. A foreign function interf ...

  10. 【Win 10应用开发】把文件嵌入到XML文档

    把文件内容嵌入(或存入)到XML文档中,相信很多朋友会想到把字节数组转化为Base64字符串,再作为XML文档的节点.不过,有人会说了,转化后的base64字符串中含有像“+”这样的符号,写入到XML ...