A preliminary study on asp.net core web API

Time:2021-10-5

This chapter will share with you the web API in asp.net core.

1、 Restful architecture style

Rest (representative state transfer) is the state transformation of the presentation layer, which is the design style of an interface. Is a new architectural style (an idea) of Web services.

Resources: all things are regarded as resources.

useThere are four request modes: post, delete, put and getSpecify the URL resource separatelyAdd, delete, modify query, restful is to manage and access resources through URIs, which has the characteristics of strong scalability and clear structure.

Uri: uniform resource identifier, the unique address corresponding to the resource.

Unified interface: addition, deletion, modification and query of crud, corresponding to HTTP method.

Main principles of rest architecture:

1. There is a resource identifier for all resources on the network.

2. Operations on resources do not change identifiers.

3. The same resource has multiple forms (XML, JSON).

4. All operations are stateless.

The architecture that conforms to the above rest principles is called restful

Stateless

Based on HTTP protocol, (login system – query salary – calculate tax, with status)

Stateless direct one address, you can get wages, you can get taxes

For more information about restful, please refer to the blog: https://blog.csdn.net/x541211190/article/details/81141459

2、 Web API

Webapi: Restful architecture style, HTTP protocol stateless standardized operation   More lightweight, especially JSON, suitable for mobile terminals.

Differences between web API and MVC:

Special personnel do special work, and their pipeline mode is different.

There is no such thing as generating pages in the web API. It does not need to find views, nor does it exist to get sessions. The web API specifically provides data, which is lighter than MVC.

The web API strictly adheres to the restful architectural style.

Next, let’s look at the code:

1. Web API project creation (using vs2019)

After successful creation, it is as follows:

Next, we add an API controller named users:

After adding, let’s look at the structure of API controller:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
    {
        // GET: api/
        [HttpGet]
        public IEnumerable Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api//5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api//5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api//5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

It can be seen that the API controller inherits the controllerbase base class and marks the [apicontroller] API controller feature and the [route (“API / [controller])] routing feature,

And different types of action methods are also marked with different features, respectively:Httpget, httppost, httpput, and httpdelete. These four features correspond to four HTTP method methods: query, add, modify, and delete.

2. Web API routing

The web API routing rules are as follows:

1. When the request comes in, it will find the appropriate controller through route matching.

2. How do you find action?

1) find a method according to httpmethod and start with the method name (i.e. start with post, delete, put and get). The beginning of get is the corresponding get request. (this point)In the. Net framework(applicable)

2) If you don’t start with post, delete, put and get, you can also use httpget, httppost, httpput and httpdelete.

3) Find the best match according to the parameters

    4)In. Net core routingActions marked with httpget, httppost, httpput and httpdelete will be matched preferentially. Other actions will be matched only if they are not matched, and the actions can start without post, delete, put and get.

People familiar with MVC may not be used to this rule at first. In MVC, we locate specific operations through controllers and actions. But why is this not the case in Web APIs?

This is because our web API strictly follows the restful style. In the restful style, there are only resources (all things are resources) and add, delete, modify and query operations. The resources here can regard it as our controller,

Do we need to pass specific methods or actions after we have resources? No, this is because our restful style has mapped our add, delete, modify and query operations to specific httpmethod methods (i.e. post, delete, put and get).

Let’s look at the routing rules of the web API through specific examples:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        [httpget ("{ID: int} / type / {typeID: int = 666}")] // access path: http://localhost:5000/api/values/1/type/666
        //[httpget ("get")] // access path: http://localhost:5000/api/values/get?id=1&typeId=666
        //[route ("/ API / [controller] / {ID: int} / type / {typeID: int}")] // access path: http://localhost:5000/api/values/1/type/666  (not recommended)
        public string Get(int id, int typeId)
        {
            return $"value-Type {id} {typeId}";
        }

        //[HttpGet("{name}")]
        [Route("api/[controller]/{name}")]
        //If the route template does not start with "/" or "~ /", the action attribute route will be superimposed (merged) with the controller attribute route
        //Access path: http://localhost:5000/api/values/api/values/abc
        public string OverlyingGet(string name)
        {
            return $"OverlyingGet {name}";
        }

        //If other actions are not marked with httpget in the same httpget request, the action will be matched
        public IEnumerable Test()
        {
            return new string[] { "Test1", "Test2" };
        }

        // GET: api/
        [httpget] // when both are httpget requests, priority is given to matching those with the httpget attribute
        public IEnumerable Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api//5
        [HttpGet("{id:int?}")]
        public string Get(int id)
        {
            return $"value-{id}";
        }

        // POST api/
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api//5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api//5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

PS: if the route template does not start with “/” or “~ /”, the action attribute route will be superimposed (merged) with the controller attribute route.

Use the. Net core cli to launch the following project:

It can be seen that the project is started successfully. Next, we use the browser to simulate the httpget request:

First, let’s look at the effect of using MVC traditional routing:

You can see that the access failed becauseBy default, the routing rules of webapi are restfulNext, let’s look at the correct access method:

So far, we have shown you a wave of restful routing rules. Someone may ask whether it can be changed to traditional MVC routing rules? Next, let’s demonstrate:

First, comment out the [route (“API / [controller])] and [apicontroller] attributes on the controller (PS: once the [apicontroller] attribute is marked, the [route (…)] attribute must be marked)

Then modify the startup.cs file to add a global routing template:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        //endpoints.MapControllers(); // The framework is generated by default
        endpoints.MapControllerRoute(
            name: "defaultWithAreas",
            pattern: "api/{area:exists}/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "api/{controller=Home}/{action=Index}/{id?}");
    });
}

Finally, access the following through the browser again:

Global routing and characteristic routing can coexist, and priority is given to matching characteristic routing

It can be seen that the access can be successful by using the traditional routing rules.

For more information about. Net core routing, see the following:

Microsoft official website about routing in asp.net core (includingRouting constraints):https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-3.1

Feature route merge: https://blog.csdn.net/sinolover/article/details/104329265/

Web API Routing: https://blog.csdn.net/qq_ 34759481/article/details/85018684

That’s all about routing.

3. Use ajax to request web API (PS: instead of restful style, traditional routing style is adopted here.)

To demonstrate that we have built an additional MVC project, let’s first look at the front-end code of MVC:

@{
    ViewData["Title"] = "Home Index";
    Layout = null;
}


    
        
            User ID:
        
        
            
        
        
            
        
        
            
        
        
            
        
    

    
    
        var user = { UserID: "10002", UserName: "TianYa", UserEmail: "[email protected]" };
        var dirName = "http://localhost:5001";
        $("#btnGet1").on("click", function () {
            $.ajax({
                url: dirName + "/api/users/GetUserByID",
                type: "get",
                data: $("#frmUser").serialize(),
                success: function (data) {
                    console.log(data);
                },
                datatype: "json"
            });
        });

        $("#btnPost1").on("click", function () {
            $.ajax({
                url: dirName + "/api/users/PostUser",
                type: "post",
                data: user,
                success: function (data) {
                    console.log(data);
                },
                datatype: "json"
            });
        });

        $("#btnPut1").on("click", function () {
            $.ajax({
                url: dirName + "/api/users/PutUser",
                type: "put",
                data: $("#frmUser").serialize(),
                success: function (data) {
                    console.log(data);
                },
                datatype: "json"
            });
        });

        $("#btnDelete1").on("click", function () {
            $.ajax({
                url: dirName + "/api/users/DeleteUser",
                type: "delete",
                data: { "userID": $("#txtId").val() },
                success: function (data) {
                    console.log(data);
                },
                datatype: "json"
            });
        });

Next, let’s look at the relevant codes of the web API:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;

using TianYa.Interface;
using TianYa.Model;

namespace MyWebAPI.Controllers
{
    //[Route("api/[controller]")]
    //[ApiController]
    public class UsersController : ControllerBase
    {
        private readonly IUserService _userService;
        public UsersController(IUserService userService)
        {
            _userService = userService;
        }

        [HttpGet]
        public Users GetUserByID(int userID)
        {
            return _userService.GetModel(userID);
        }

        [HttpPost]
        public Users PostUser(Users user)
        {
            return _userService.GetModel(user.UserID);
        }

        [HttpPut]
        public Users PutUser(Users user)
        {
            return _userService.GetModel(user.UserID);
        }

        [HttpDelete]
        public Users DeleteUser(int userID)
        {
            return _userService.GetModel(userID);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace TianYa.Model
{
    /// 
    ///User
    /// 
    public class Users
    {
        public int UserID { get; set; }
        public string UserName { get; set; }
        public string UserEmail { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

using TianYa.Model;
using TianYa.Interface;

namespace TianYa.Service
{
    /// 
    ///User service layer
    /// 
    public class UserService : IUserService
    {
        private List _listUsers = new List();
        public UserService()
        {
            _listUsers.Add(new Users
            {
                UserID = 10000,
                Username = "Zhang San",
                UserEmail = "[email protected]"
            });
            _listUsers.Add(new Users
            {
                UserID = 10001,
                Username = "Li Si",
                UserEmail = "[email protected]"
            });
            _listUsers.Add(new Users
            {
                UserID = 10002,
                Username = "Wang Wu",
                UserEmail = "[email protected]"
            });
            _listUsers.Add(new Users
            {
                UserID = 10003,
                Username = "Zhao Liu",
                UserEmail = "[email protected]"
            });
        }

        public Users GetModel(int userId)
        {
            return _listUsers.FirstOrDefault(m => m.UserID == userId) ?? _listUsers[0];
        }
    }
}

Then use the. Net core cli to start the MVC project and the web API project respectively. After successful startup, let’s visit the following:

From the running results, it can be found that:

1. The users type is returned in the action method of the web API, but the web API will automatically convert it to the specified type (such as JSON or XML) when responding to the front end.

2. The format of JSON data in response to the front end adopts hump naming method by default.

Then how can IKeep the JSON data responding to the front end in the original formatAnd?

You need to reference first  Microsoft.AspNetCore.Mvc.NewtonsoftJsonPackage:

Then modify the startup.cs file as follows:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;

using TianYa.Interface;
using TianYa.Service;

namespace MyWebAPI
{
    public class Startup
    {
        private readonly string _myCorsPolicy = "MyCorsPolicy";
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson(options =>
            {
                //Ignore circular references
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //No hump
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                //Format time
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                //If the field is null, the field will not be returned to the front end
                // options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            });
            Services. Addcors (options = > // set cross domain policy
                options.AddPolicy(_myCorsPolicy, builder =>
                 {
                     builder
                        .AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
                 })
            );
            services.AddTransient(); // Dependency injection
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseAuthorization();
            app.UseCors(_myCorsPolicy);
            app.UseEndpoints(endpoints =>
            {
                //endpoints.MapControllers(); // The framework is generated by default
                endpoints.MapControllerRoute(
                            name: "defaultWithAreas",
                            pattern: "api/{area:exists}/{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "api/{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

After the setup is completed and the restart is successful, let’s visit the following:

It can be seen from the running results that the JSON data returned to the front end retains the original format.

For more information about Ajax request web API, please refer to the blog post:

  https://blog.csdn.net/weixin_43537631/article/details/110563779

For more information about web API, please refer to Microsoft’s official website:

  https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&tabs=visual-studio

  https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?view=aspnetcore-5.0

So far, this article is all introduced. If you think it will inspire you, please remember to like it!!!

 

Demo source code:

Link: https://pan.baidu.com/s/1cJPAVpKao3raiS_ hTH66bw 
Extraction code: s5ft

This article is carefully written by the blogger. Please keep the original link for reprint:https://www.cnblogs.com/xyh9039/p/14163991.html

Copyright notice: if there is any similarity, it is purely a coincidence. If there is any infringement, please contact me in time to modify it. Thank you!!!