In the Web API project, use Area to manage services by category. apiarea
In many previously developed Web API projects, the Controller of the entire Web API is usually placed in the Controllers directory of the base directory for convenience and rapid development. However, as the business becomes more and more complex, in this way, the files in the Controllers directory are added quickly and difficult to manage. If there are duplicate controller names in different business modules, avoid them as much as possible. The introduction of Area is to differentiate the controller based on different business modules for convenient management, and the Controller name can be duplicated.
1. Areas are introduced into Web API projects for classification
An Area can be called a region in a project. Each Area represents different functional modules of an application. An Area enables each functional module to have its own folders, including its own Controller, View, and Model, however, it also increases the difficulty of management. For a Web API project, we can remove unnecessary directories to simplify Directory management.
The introduction of Area can be the name of different business modules, and the management of each business module is more convenient. In the original Web API project, their directories are like this.
Although we classify their directories, they are stored in a namespace.
namespace MyWebApi.Controllers
Although there are no problems in this way, there are still some drawbacks. Therefore, we have introduced the Area method to manage controllers of different business modules to achieve our classification management goal.
Before the introduction of Area, our API path is as follows:
http://localhost:9001/api/User
After the introduction of Area, we put basic modules such as regular permission management and dictionary management into the Area of the Framework. At this time, the API path is related to the specific Area, and the address is changed to the following:
http://localhost:9001/api/Framework/User
Let's take a look at the specific project directory. After Area is used in the Web API project, the Controller directory is as follows.
In addition to different controllers in different areas**The AreaRegistration. cs file, such as the Area of the Framework, has a FrameworkAreaRegistration. cs file.
In this way, it corresponds to the following controller, and its namespace is as follows.
namespace WebAPI.Areas.Framework.Controllers
2. Path ing between the Web API project and the Area controller
The preceding section describes how to use Area to manage the categories of Web API controllers. It also describes the differences in the Controller location, namespace, and Web api url after Area is introduced. In this way, if we want to parse the Web API of the corresponding address, we also need to do some processing. Otherwise, the corresponding controller cannot be found, resulting in an error message.
First, we need to modify the configuration information of WebApiConfig in the Web API, as shown below.
The default Web API ing is specified above, and only outputs in JSON format are specified (XML output is removed ).
In order to implement API address processing for different areas, we first design a base class, and then let different Area registration classes inherit from it for convenient unified processing.
The following code shows the CustomAreaRegistration class of the basic Area registration class.
With the above base class reging RegisterArea function, we only need to set the corresponding AreaName base class in the subclass to implement correct API ing of API paths for different Area subclass.
/// <Summary> /// registration class of the Framework basic Area /// </summary> public class FrameworkAreaRegistration: customAreaRegistration {public override string AreaName {get {return "Framework ";}}}
Of course, in order to correctly parse the URL of the Area Web API Controller and obtain objects belonging to the Action, Controller, and corresponding namespace, you also need to go to global. asa. add a line of code in cs, as shown below.
// Support GlobalConfiguration. Configuration. Services. Replace (typeof (IHttpControllerSelector), new AreaHttpControllerSelector (GlobalConfiguration. Configuration) for the Area of the Web API ));
Here, AreaHttpControllerSelector is our custom HTTP controller address parser. We need to extract the specific controller, Area Name, assembly type and so on based on our address to facilitate the construction of the corresponding parser.
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);}
With these basic management, we can define the Area we need and then build the Controller Interface in the specific business scope.
3. Call Web APIs on the client
All the Web API addresses are related to the specific Area. For example, the dictionary module under the Framework Service. The addresses configured by the Web API are as follows.
<! -- Dictionary Web API module configuration -->
<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"/>
On the client side, we only need to encapsulate Web APIs. This part can be uniformly generated using the Database2Sharp code generation tool, and all inheritance relationships are processed in a unified manner, what we do is to process newly added interfaces.
For example, for processing the dictionary module DictData, its encapsulation class for Web APIs is as follows.
/// <Summary> /// DictData, implementation class of the API service-based Facade interface /// </summary> public class DictDataCaller: BaseApiService <DictDataInfo>, IDictDataService
By default, this base class encapsulates the addition, deletion, modification, and query of Web API methods for conventional data table services, and various complex interface processing.
For general Web APIs (non-data table service), you only need to adjust the inherited base class.
/// <Summary> /// API-based Facade interface implementation class /// </summary> public class TestCaller: NormalApiService, ITestService
This NormalApiService base class encapsulates the token and signature reading by default. There is no special service interface. We can implement specific interfaces for processing.
For WebAPI client calls, we mainly need to build the corresponding URL, then pass some parameters through GET or POST, read the HTML results, and parse it into the corresponding type of data, the following code is used.
/// <Summary> /// obtain the corresponding dictionary Record Based on the dictionary type name /// </summary> /// <param name = "dictTypeName"> name of the dictionary type </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 ;}
Use the GetTokenUrl (action) function to obtain the corresponding URL address. Because a parameter is input, no data changes have been made to the interface. The GET method submits parameter data, so you can append the parameter to the URL.
That is, the following code constructs a complete Web API address.
string url = GetTokenUrl(action) + string.Format("&dictTypeName={0}", dictTypeName);
After these URL addresses are constructed, we can obtain the results of the corresponding Web API and serial number to the specific object. The following code is used.
List<DictDataInfo> result = JsonHelper<List<DictDataInfo>>.ConvertJson(url);
For more information about the design of Web API interfaces, see my documents.
- Experience in Designing Web APIs
- Design and Analysis of Web API application architecture (1)
- Design and Analysis of Web API application architecture (2)
For details about how to use the Web API, refer:
- Application of Web API application architecture in Winform Hybrid Framework (1)
- Application of Web API application architecture in Winform Hybrid Framework (2) -- processing of custom exception results
- Application of Web API application architecture in the Winform Hybrid Framework (3) -- process decomposition of WebAPI calling on the Winfrom Interface
- Application of Web API application architecture in Winform Hybrid Framework (4) -- quickly develop a whole set of applications using code generation tools
- Application of Web API application architecture in the Winform Hybrid Framework (5) -- processing method for coexistence of system-level dictionary and company-level dictionary
After the preceding encapsulation, the client code for calling the Web API of the business table is as follows.
var dictType = CallerFactory<IDictTypeService>.Instance.GetTree();Console.WriteLine(dictType.ToJson());var dictData = CallerFactory<IDictDataService>.Instance.GetAllDict();Console.WriteLine(dictData.ToJson());
If you call a Web API for a non-data table service, the client code is as follows.
var testAction = CallerFactory<ITestService>.Instance.TestAction();Console.WriteLine(testAction.ToJson());var test = CallerFactory<ITestService>.Instance.Test("123");Console.WriteLine(test.ToJson());
In this way, you can consume Web APIs in the same way, whether in a Web project, in a Winform project, or in a cross-platform IOS project (or android project, in this way, all our data portals can be centrally developed for business interfaces, and the performance problems provided by our data can be effectively managed, such as unified cache processing, unified permission processing...
Thank you for your careful reading of this article and hope to inspire or help you in your development.