Configure the global routing prefix in ASP. NET Core MVC and coremvc

Source: Internet
Author: User

Configure the global routing prefix in ASP. NET Core MVC and coremvc

Reference page:







Hello everyone, today we will introduce a new feature of ASP. NET Core MVC and add a unified prefix to global routes. Strictly speaking, it is not a new feature, but a unique feature of Core MVC.

Application background

I don't know if you have encountered such a scenario when using Web Api applications, that is, all interfaces start with/api, that is, our api request address is like this:

Or such a requirement

In the past, if we wanted to implement this kind of requirement, we could add[Route("/api/order")]With this feature, the MVC Framework will scan your route table to match/api/orderSuch a request.
However, the second requirement with a version number is as follows:[Route("/api/v1/order")]Now we need to upgrade to v2 with more than interfaces, which requires one modification, and may be forced.

Now there is a simpler and more elegant way to do this. You can add a global prefix routing tag in a unified manner. Let's take a look at it.

IApplicationModelConvention Interface

First, we need to useIApplicationModelConventionThis interface is located inMicrosoft.AspNetCore.Mvc.ApplicationModelsIn the namespace, let's take a look at the interface definition.

public interface IApplicationModelConvention{    void Apply(ApplicationModel application);}    

We know that the MVC framework has some common things, so this interface is mainly used to customize some of the MVC conventions. We can specifyApplicationModelObject To add or modify some conventions. You can see that the interface providesApplyThis method hasApplicationModelObject, we can use this object to modify what we need. The MVC framework itself injects this interface into Services at startup, so we only need to implement this interface, then you can configure it with a little bit.

Let's take a look.ApplicationModelWhat does this object have:

public class ApplicationModel : IPropertyModel, IFilterModel, IApiExplorerModel{    public ApiExplorerModel ApiExplorer { get; set; }    public IList<ControllerModel> Controllers { get; }    public IList<IFilterMetadata> Filters { get; }    public IDictionary<object, object> Properties { get; }}

You can see thatApiExplorer,Controllers,Filters,Properties.

  • Apicyclermodel: Mainly used to configure the default MVC Api Explorer, including the Api description, group information, and visibility.
  • ControllerModel: it is mainly related to the default Comtroller conventions. There are more things in it, so we will not introduce them one by one. We will wait for a while to configure one thing in it.
  • IFilterMetadata: Empty interface, mainly used for marking.

Another thing we need to tell you is,You can see that the Controllers attribute above isIList<ControllerModel>That is to say, this list records information about all controllers in your program. You can set a certain part or Controller through traversal, the Actions information in the Controller can be set in this way. We can use this feature to flexibly modify the MVC framework.Is it cool.

Next, we will use this feature to implement our theme today. Thank you for your thumbs up ~ :)

Add unified global route prefix

There is not so much nonsense. You can directly add the code. All you have to say is in the Code:

// Define a class RouteConvention to implement the invoke interface public class RouteConvention: Rule {private readonly AttributeRouteModel _ centralPrefix; public RouteConvention (condition) {_ centralPrefix = new AttributeRouteModel (condition );} // Apply method of the interface public void Apply (ApplicationModel application) {// traverse all controllers foreach (var Controller in application. Controllers) {// Controller var matchedSelectors = controller. Selectors. Where (x => x. AttributeRouteModel! = Null ). toList (); if (matchedSelectors. any () {foreach (var selectorModel in matchedSelectors) {// Add a route prefix selectorModel to the current route. attributeRouteModel = AttributeRouteModel. combineAttributeRouteModel (_ centralPrefix, selectorModel. attributeRouteModel); }}// Controller var unmatchedSelectors = controller without RouteAttribute. selectors. where (x => x. attributeRouteModel = null ). toList (); if (unmatchedSelectors. any () {foreach (var selectorModel in unmatchedSelectors) {// Add a route prefix selectorModel. attributeRouteModel = _ centralPrefix ;}}}}}

Then, we can start to use the class we have defined.

Public static class MvcOptionsExtensions {public static void UseCentralRoutePrefix (this MvcOptions opts, IRouteTemplateProvider routeAttribute) {// Add RouteConvention opts for implementing IApplicationModelConvention. conventions. insert (0, new RouteConvention (routeAttribute ));}}

Finally, add the above Extension Method in the Startup. cs file.

Public class Startup {public Startup (IHostingEnvironment env ){//...} public void ConfigureServices (IServiceCollection services ){//... services. addMvc (opt => {// The route parameter is still valid here, for example, add a version number opt. useCentralRoutePrefix (new RouteAttribute ("api/v {version}");} public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory ){//... app. useMvc ();}}

Where,opt.UseCentralRoutePrefixThis is the extension method defined above. Here the routing parameters can still be used, so for example, you can specify a version number for your interface. In this way, the RoteAttribute of all your controllers will be added with this prefix, which perfectly solves the needs of the first version number. They look like this:

[Route ("order")] public class OrderController: Controller {// Route address: /api/v {version}/order/details/{id} [Route ("details/{id}")] public string GetById (int id, int version) {// the version number can be received, and the returned version and id return $ "other resource: {id}, version: {version}" ;}} public class ItemController: controller {// Route address:/api/v {version}/item/{id} [Route ("item/{id}")] public string GetById (int id, int version) {// the version number can be received above. The returned version and id return $ "item: {id}, version: {version }";}}

I hope you can understand and use the above in bold Chinese. This example is only a small scenario in actual needs. There will be various normal or abnormal requirements in specific projects, we need to think more about a function. In fact, the MVC framework still has many things to learn, including its design ideas and scalability. If you are interested in ASP. NET Core, please pay attention to me. I will share some of my learning achievements on a regular basis in my blog.

Thank you for your support. If you think this article is helpful to you, thank you for your [recommendation]. Good night ~.

Author's blog: Savorboard
You are welcome to repost it. Please provide the source and link clearly

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.