ASP. NET Core MVC configuration global route prefix

Source: Internet
Author: User

Application background

Do not know when you do the Web API application, have encountered this scenario, that is, all the interfaces are beginning with/API, that is, our API interface request address is like this:

http://www.example.com/api/order/333

Or is that the demand

http://www.example.com/api/v2/order/333

In the past, if we were to implement this requirement, we could add a routing Attribute to the Controller with an attribute such as [Route ("/api/order")], and then the MVC framework would scan your routing table to match a request like/api/order.
But the second with the version number of the requirements, the original Controller's route definition is [Route ("/api/v1/order")], now to upgrade to V2, and hundreds of interfaces, which requires a modification, may be confused.

Now, there is a simpler and more elegant way to do this, you can unify to add a global prefix route tag, let's take a look at it.

Iapplicationmodelconvention interface

First, we need to use this interface to Iapplicationmodelconvention, which is located under the Microsoft.AspNetCore.Mvc.ApplicationModels namespace, so let's look at the definition of the interface.

public interface iapplicationmodelconvention{void Apply (Applicationmodel application);

We know that the MVC framework has some conventions in it, so this interface is primarily about something that defines some MVC conventions that we can add or modify by specifying Applicationmodel objects. You can see that the interface provides an apply method that has a Applicationmodel object that we can use to modify what we need, and the MVC framework itself injects this interface into Services when it is started. So we just need to implement this interface and then configure it a little bit.

Then let's see what the Applicationmodel object has:

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 properties such as Apiexplorer,controllers,filters,properties.

    • Apiexplorermodel: The main thing is to configure the default MVC API Explorer, including the API description information, group information, visibility, etc.

    • Controllermodel: The main comtroller is the default convention related, this inside things are more, do not introduce each, we will have to configure the inside of a thing.

    • Ifiltermetadata: An empty interface, which acts primarily as a marker.

There is also a place to tell everyone is that you can see the Controllers property above it is a ilist<controllermodel>, which means that the list of all Controller information in your program is recorded, You can set it up for a certain part or a controller by traversing it, including the actions in the controller can be set in this way, and we can use this feature to be very flexible with the MVC framework, isn't it cool.

Let's use this feature to achieve our theme today. Thank you for your order of praise ~:)

Add Global route Unified prefix

Not so much nonsense, directly on the code, to say the words are all in the code:

Define a class routeconvention to implement the  IApplicationModelConvention  interface public class routeconvention  :  iapplicationmodelconvention{    private readonly attributeroutemodel  _centralprefix;    public routeconvention (iroutetemplateprovider  Routetemplateprovider)     {        _centralprefix  = new attributeroutemodel (Routetemplateprovider);    }    Apply method for  //interface     public void apply (applicationmodel application)      {        //Traversal of all  Controller         foreach  (var controller in application. Controllers)         {             //  has marked the  routeatt Controller            var  in ribute  Matchedselectors = controller. Selectors.where (X => x.attributeroutemodel != null). ToList ();            if  (matchedSelectors.Any ())             {                 foreach  (var selectormodel in  matchedselectors)                  {                     //  on   Current route     Add an   route prefix                       Selectormodel.attributeroutemodel =&nBsp Attributeroutemodel.combineattributeroutemodel (_centralprefix,                          Selectormodel.attributeroutemodel);                 }            }            //   controller with no marks  RouteAttribute              var unmatchedselectors =  controller. Selectors.where (X => x.attributeroutemodel == null). ToList ();            if  ( Unmatchedselectors.any ())             {                 foreach  (var selectormodel in unmatchedselectors)                  {                     //  Add a   Routing prefixes                      selectorModel.AttributeRouteModel = _centralPrefix;                 }             }        }    }}

Then we can start using this class of our own definition.

public static class mvcoptionsextensions{public static void Usecentralrouteprefix (this mvcoptions opts, iroutetemplate Provider routeattribute) {//Add our Custom implementation iapplicationmodelconvention Routeconvention opts.    Conventions.insert (0, New Routeconvention (Routeattribute)); }}

Finally, in the Startup.cs file, add the extension method above.

Public class startup{    public startup (ihostingenvironment env)      {        //...    }     public void configureservices (iservicecollection services)     {         //...                 services. ADDMVC (opt =>        {             //  route parameters are still valid here, such as adding a version number              opt. Usecentralrouteprefix (New routeattribute ("Api/v{version}"));         });     }    public void configure (IApplicationBuilder  app, ihostingenvironment env,&nbSp;iloggerfactory loggerfactory)     {         ...                 app. Usemvc ();     }}

, opt. usecentralrouteprefix  is the extension method defined above, where the routing parameters are still available, so for example you can assign a version number to your interface. After that, all of your Controller's roteattribute will be added with this prefix, which perfectly solves the need for the first version number. They might look like this:

[Route ("Order")]public class ordercontroller : controller{    //  Routing Address  : /api/v{version}/order/details/{id}    [route ("Details/{id}")]     public string getbyid (int id, int version)     {         //above is can receive version number, return  version  and  id         return $ "Other resource: {id}, version: {version}";     }}public class ItemController : Controller{     //  Routing Address:  /api/v{version}/item/{id}    [route ("Item/{id}")]     public string getbyid (int id, int version)     {         //above is can receive version number, return  version  and  id         return $ "Item: {id}, version: {version}";     }} 


ASP. NET Core MVC configuration global route prefix

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: info-contact@alibabacloud.com 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.