在ASP.NET Core 2.2 中创建 Web API并结合Swagger
一、创建 ASP.NET Core WebApi项目
二、添加
三、
-----------------------------------------------------------
一、创建项目,WideWorldImporters.API,选项按照下列图操作
二、引用需要的Nuget包
- Microsoft.EntityFrameworkCore.SqlServer
Swashbuckle.AspNetCore
Swashbuckle.AspNetCore包允许为Web API启用帮助页。
试运行一下项目
OK, 没任何错误。?
添加一个文件夹Models,在里面添加4个.cs文件,
Entities.cs //实体,为了简单些把多个实体放在这一个文件里,实际项目里可以一个文件一个类
Extensions.cs //扩展类,
Requests.cs //请求类,
Responses.cs //响应类,
4个文件的完整代码如下:
Entities.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 using Microsoft.EntityFrameworkCore; 6 using Microsoft.EntityFrameworkCore.Metadata.Builders; 7 8 namespace WideWorldImporters.API.Models 9 { 10 public partial class StockItem 11 { 12 public StockItem() 13 { 14 } 15 16 public StockItem(int? stockItemID) 17 { 18 StockItemID = stockItemID; 19 } 20 21 public int? StockItemID { get; set; } 22 23 public string StockItemName { get; set; } 24 25 public int? SupplierID { get; set; } 26 27 public int? ColorID { get; set; } 28 29 public int? UnitPackageID { get; set; } 30 31 public int? OuterPackageID { get; set; } 32 33 public string Brand { get; set; } 34 35 public string Size { get; set; } 36 37 public int? LeadTimeDays { get; set; } 38 39 public int? QuantityPerOuter { get; set; } 40 41 public bool? IsChillerStock { get; set; } 42 43 public string Barcode { get; set; } 44 45 public decimal? TaxRate { get; set; } 46 47 public decimal? UnitPrice { get; set; } 48 49 public decimal? RecommendedRetailPrice { get; set; } 50 51 public decimal? TypicalWeightPerUnit { get; set; } 52 53 public string MarketingComments { get; set; } 54 55 public string InternalComments { get; set; } 56 57 public string CustomFields { get; set; } 58 59 public string Tags { get; set; } 60 61 public string SearchDetails { get; set; } 62 63 public int? LastEditedBy { get; set; } 64 65 public DateTime? ValidFrom { get; set; } 66 67 public DateTime? ValidTo { get; set; } 68 } 69 70 public class StockItemsConfiguration : IEntityTypeConfiguration<StockItem> 71 { 72 public void Configure(EntityTypeBuilder<StockItem> builder) 73 { 74 // Set configuration for entity 75 builder.ToTable("StockItems", "Warehouse"); 76 77 // Set key for entity 78 builder.HasKey(p => p.StockItemID); 79 80 // Set configuration for columns 81 82 builder.Property(p => p.StockItemName).HasColumnType("nvarchar(200)").IsRequired(); 83 builder.Property(p => p.SupplierID).HasColumnType("int").IsRequired(); 84 builder.Property(p => p.ColorID).HasColumnType("int"); 85 builder.Property(p => p.UnitPackageID).HasColumnType("int").IsRequired(); 86 builder.Property(p => p.OuterPackageID).HasColumnType("int").IsRequired(); 87 builder.Property(p => p.Brand).HasColumnType("nvarchar(100)"); 88 builder.Property(p => p.Size).HasColumnType("nvarchar(40)"); 89 builder.Property(p => p.LeadTimeDays).HasColumnType("int").IsRequired(); 90 builder.Property(p => p.QuantityPerOuter).HasColumnType("int").IsRequired(); 91 builder.Property(p => p.IsChillerStock).HasColumnType("bit").IsRequired(); 92 builder.Property(p => p.Barcode).HasColumnType("nvarchar(100)"); 93 builder.Property(p => p.TaxRate).HasColumnType("decimal(18, 3)").IsRequired(); 94 builder.Property(p => p.UnitPrice).HasColumnType("decimal(18, 2)").IsRequired(); 95 builder.Property(p => p.RecommendedRetailPrice).HasColumnType("decimal(18, 2)"); 96 builder.Property(p => p.TypicalWeightPerUnit).HasColumnType("decimal(18, 3)").IsRequired(); 97 builder.Property(p => p.MarketingComments).HasColumnType("nvarchar(max)"); 98 builder.Property(p => p.InternalComments).HasColumnType("nvarchar(max)"); 99 builder.Property(p => p.CustomFields).HasColumnType("nvarchar(max)"); 100 builder.Property(p => p.LastEditedBy).HasColumnType("int").IsRequired(); 101 102 // Computed columns 103 104 builder 105 .Property(p => p.StockItemID) 106 .HasColumnType("int") 107 .IsRequired() 108 .HasComputedColumnSql("NEXT VALUE FOR [Sequences].[StockItemID]"); 109 110 builder 111 .Property(p => p.Tags) 112 .HasColumnType("nvarchar(max)") 113 .HasComputedColumnSql("json_query([CustomFields],N'$.Tags')"); 114 115 builder 116 .Property(p => p.SearchDetails) 117 .HasColumnType("nvarchar(max)") 118 .IsRequired() 119 .HasComputedColumnSql("concat([StockItemName],N' ',[MarketingComments])"); 120 121 // Columns with generated value on add or update 122 123 builder 124 .Property(p => p.ValidFrom) 125 .HasColumnType("datetime2") 126 .IsRequired() 127 .ValueGeneratedOnAddOrUpdate(); 128 129 builder 130 .Property(p => p.ValidTo) 131 .HasColumnType("datetime2") 132 .IsRequired() 133 .ValueGeneratedOnAddOrUpdate(); 134 } 135 } 136 137 public class WideWorldImportersDbContext : DbContext 138 { 139 public WideWorldImportersDbContext(DbContextOptions<WideWorldImportersDbContext> options) 140 : base(options) 141 { 142 } 143 144 protected override void OnModelCreating(ModelBuilder modelBuilder) 145 { 146 // Apply configurations for entity 147 148 modelBuilder 149 .ApplyConfiguration(new StockItemsConfiguration()); 150 151 base.OnModelCreating(modelBuilder); 152 } 153 154 public DbSet<StockItem> StockItems { get; set; } 155 } 156 }
View Code
Extensions.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore;namespace WideWorldImporters.API.Models {public static class WideWorldImportersDbContextExtensions{public static IQueryable<StockItem> GetStockItems(this WideWorldImportersDbContext dbContext, int pageSize = 10, int pageNumber = 1, int? lastEditedBy = null, int? colorID = null, int? outerPackageID = null, int? supplierID = null, int? unitPackageID = null){// Get query from DbSetvar query = dbContext.StockItems.AsQueryable();// Filter by: 'LastEditedBy'if (lastEditedBy.HasValue)query = query.Where(item => item.LastEditedBy == lastEditedBy);// Filter by: 'ColorID'if (colorID.HasValue)query = query.Where(item => item.ColorID == colorID);// Filter by: 'OuterPackageID'if (outerPackageID.HasValue)query = query.Where(item => item.OuterPackageID == outerPackageID);// Filter by: 'SupplierID'if (supplierID.HasValue)query = query.Where(item => item.SupplierID == supplierID);// Filter by: 'UnitPackageID'if (unitPackageID.HasValue)query = query.Where(item => item.UnitPackageID == unitPackageID);return query;}public static async Task<StockItem> GetStockItemsAsync(this WideWorldImportersDbContext dbContext, StockItem entity)=> await dbContext.StockItems.FirstOrDefaultAsync(item => item.StockItemID == entity.StockItemID);public static async Task<StockItem> GetStockItemsByStockItemNameAsync(this WideWorldImportersDbContext dbContext, StockItem entity)=> await dbContext.StockItems.FirstOrDefaultAsync(item => item.StockItemName == entity.StockItemName);}public static class IQueryableExtensions{public static IQueryable<TModel> Paging<TModel>(this IQueryable<TModel> query, int pageSize = 0, int pageNumber = 0) where TModel : class=> pageSize > 0 && pageNumber > 0 ? query.Skip((pageNumber - 1) * pageSize).Take(pageSize) : query;} }
View Code
Requests.cs
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks;namespace WideWorldImporters.API.Models {public class PostStockItemsRequest{[Key]public int? StockItemID { get; set; }[Required][StringLength(200)]public string StockItemName { get; set; }[Required]public int? SupplierID { get; set; }public int? ColorID { get; set; }[Required]public int? UnitPackageID { get; set; }[Required]public int? OuterPackageID { get; set; }[StringLength(100)]public string Brand { get; set; }[StringLength(40)]public string Size { get; set; }[Required]public int? LeadTimeDays { get; set; }[Required]public int? QuantityPerOuter { get; set; }[Required]public bool? IsChillerStock { get; set; }[StringLength(100)]public string Barcode { get; set; }[Required]public decimal? TaxRate { get; set; }[Required]public decimal? UnitPrice { get; set; }public decimal? RecommendedRetailPrice { get; set; }[Required]public decimal? TypicalWeightPerUnit { get; set; }public string MarketingComments { get; set; }public string InternalComments { get; set; }public string CustomFields { get; set; }public string Tags { get; set; }[Required]public string SearchDetails { get; set; }[Required]public int? LastEditedBy { get; set; }public DateTime? ValidFrom { get; set; }public DateTime? ValidTo { get; set; }}public class PutStockItemsRequest{[Required][StringLength(200)]public string StockItemName { get; set; }[Required]public int? SupplierID { get; set; }public int? ColorID { get; set; }[Required]public decimal? UnitPrice { get; set; }}public static class Extensions{public static StockItem ToEntity(this PostStockItemsRequest request)=> new StockItem{StockItemID = request.StockItemID,StockItemName = request.StockItemName,SupplierID = request.SupplierID,ColorID = request.ColorID,UnitPackageID = request.UnitPackageID,OuterPackageID = request.OuterPackageID,Brand = request.Brand,Size = request.Size,LeadTimeDays = request.LeadTimeDays,QuantityPerOuter = request.QuantityPerOuter,IsChillerStock = request.IsChillerStock,Barcode = request.Barcode,TaxRate = request.TaxRate,UnitPrice = request.UnitPrice,RecommendedRetailPrice = request.RecommendedRetailPrice,TypicalWeightPerUnit = request.TypicalWeightPerUnit,MarketingComments = request.MarketingComments,InternalComments = request.InternalComments,CustomFields = request.CustomFields,Tags = request.Tags,SearchDetails = request.SearchDetails,LastEditedBy = request.LastEditedBy,ValidFrom = request.ValidFrom,ValidTo = request.ValidTo};} }
View Code
Responses.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Threading.Tasks; 6 using Microsoft.AspNetCore.Mvc; 7 8 namespace WideWorldImporters.API.Models 9 { 10 public interface IResponse 11 { 12 string Message { get; set; } 13 14 bool DidError { get; set; } 15 16 string ErrorMessage { get; set; } 17 } 18 19 public interface ISingleResponse<TModel> : IResponse 20 { 21 TModel Model { get; set; } 22 } 23 24 public interface IListResponse<TModel> : IResponse 25 { 26 IEnumerable<TModel> Model { get; set; } 27 } 28 29 public interface IPagedResponse<TModel> : IListResponse<TModel> 30 { 31 int ItemsCount { get; set; } 32 33 double PageCount { get; } 34 } 35 36 public class Response : IResponse 37 { 38 public string Message { get; set; } 39 40 public bool DidError { get; set; } 41 42 public string ErrorMessage { get; set; } 43 } 44 45 public class SingleResponse<TModel> : ISingleResponse<TModel> 46 { 47 public string Message { get; set; } 48 49 public bool DidError { get; set; } 50 51 public string ErrorMessage { get; set; } 52 53 public TModel Model { get; set; } 54 } 55 56 public class ListResponse<TModel> : IListResponse<TModel> 57 { 58 public string Message { get; set; } 59 60 public bool DidError { get; set; } 61 62 public string ErrorMessage { get; set; } 63 64 public IEnumerable<TModel> Model { get; set; } 65 } 66 67 public class PagedResponse<TModel> : IPagedResponse<TModel> 68 { 69 public string Message { get; set; } 70 71 public bool DidError { get; set; } 72 73 public string ErrorMessage { get; set; } 74 75 public IEnumerable<TModel> Model { get; set; } 76 77 public int PageSize { get; set; } 78 79 public int PageNumber { get; set; } 80 81 public int ItemsCount { get; set; } 82 83 public double PageCount 84 => ItemsCount < PageSize ? 1 : (int)(((double)ItemsCount / PageSize) + 1); 85 } 86 87 public static class ResponseExtensions 88 { 89 public static IActionResult ToHttpResponse(this IResponse response) 90 { 91 var status = response.DidError ? HttpStatusCode.InternalServerError : HttpStatusCode.OK; 92 93 return new ObjectResult(response) 94 { 95 StatusCode = (int)status 96 }; 97 } 98 99 public static IActionResult ToHttpResponse<TModel>(this ISingleResponse<TModel> response) 100 { 101 var status = HttpStatusCode.OK; 102 103 if (response.DidError) 104 status = HttpStatusCode.InternalServerError; 105 else if (response.Model == null) 106 status = HttpStatusCode.NotFound; 107 108 return new ObjectResult(response) 109 { 110 StatusCode = (int)status 111 }; 112 } 113 114 public static IActionResult ToHttpResponse<TModel>(this IListResponse<TModel> response) 115 { 116 var status = HttpStatusCode.OK; 117 118 if (response.DidError) 119 status = HttpStatusCode.InternalServerError; 120 else if (response.Model == null) 121 status = HttpStatusCode.NoContent; 122 123 return new ObjectResult(response) 124 { 125 StatusCode = (int)status 126 }; 127 } 128 } 129 }
View Code
接下来开始添加Api控制器 WarehouseController
右击项目文件夹Controllers
WarehouseController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using WideWorldImporters.API.Models;namespace WideWorldImporters.API.Controllers {[Route("api/v1/[controller]")][ApiController]public class WarehouseController : ControllerBase{protected readonly ILogger _logger;protected readonly WideWorldImportersDbContext _dbContext;public WarehouseController(ILogger<WarehouseController> logger, WideWorldImportersDbContext dbContext){_logger = logger;_dbContext = dbContext;}/// <summary>/// 获取库存项列表/// </summary>/// <param name="pageSize">页大小</param>/// <param name="pageNumber">页号</param>/// <param name="lastEditedBy">最后编辑者</param>/// <param name="colorId">颜色ID</param>/// <param name="outerPackageId">外包装ID</param>/// <param name="supplierId">供应商ID</param>/// <param name="unitPackageId"></param>/// <returns></returns>public async Task<IActionResult> GetStockItemsAsync(int pageSize = 10,int pageNumber = 1,int? lastEditedBy = null,int? colorId = null,int? outerPackageId = null,int? supplierId = null,int? unitPackageId = null){_logger?.LogDebug($"'{nameof(GetStockItemsAsync)}' 被调用了");var response = new PagedResponse<StockItem>();//创建分页对象try{var query = _dbContext.GetStockItems();response.PageSize = pageSize;response.PageNumber = pageNumber;response.ItemsCount = await query.CountAsync();//获取总记录数 response.Model = await query.Paging(pageSize, pageNumber).ToListAsync();response.Message = $"第 {pageNumber} 共 {response.PageCount}, 产品总数量: {response.ItemsCount}";_logger?.LogInformation("已成功检索库存项!");}catch (Exception e){response.DidError = true;response.ErrorMessage = "有一个内部错误,请联系技术支持!";_logger?.LogCritical($"There was an error on '{nameof(GetStockItemsAsync)}' invocation: {e}");}return response.ToHttpResponse();}/// <summary>/// 获取单记录/// </summary>/// <param name="id"></param>/// <returns></returns>[HttpGet("StockItem/{id}")][ProducesResponseType(200)][ProducesResponseType(404)][ProducesResponseType(500)]public async Task<IActionResult> GetStockItemAsync(int id){_logger?.LogDebug($"'{nameof(GetStockItemAsync)}' 被执行了!");var response = new SingleResponse<StockItem>();try{response.Model = await _dbContext.GetStockItemsAsync(new StockItem(id));}catch (Exception e){response.DidError = true;response.ErrorMessage = "有错误,请联系技术支持!";_logger?.LogCritical($"There was an error on '{nameof(GetStockItemAsync)}' invocation: {e}");}return response.ToHttpResponse();}// POST// api/v1/Warehouse/StockItem//// <summary>/// Creates a new stock item/// </summary>/// <param name="request">Request model</param>/// <returns>A response with new stock item</returns>/// <response code="200">Returns the stock items list</response>/// <response code="201">A response as creation of stock item</response>/// <response code="400">For bad request</response>/// <response code="500">If there was an internal server error</response>[HttpPost("StockItem")][ProducesResponseType(200)][ProducesResponseType(201)][ProducesResponseType(400)][ProducesResponseType(500)]public async Task<IActionResult> PostStockItemAsync([FromBody]PostStockItemsRequest request){_logger?.LogDebug("'{0}' has been invoked", nameof(PostStockItemAsync));var response = new SingleResponse<StockItem>();try{var existingEntity = await _dbContext.GetStockItemsByStockItemNameAsync(new StockItem { StockItemName = request.StockItemName });if (existingEntity != null)ModelState.AddModelError("StockItemName", "Stock item name already exists");if (!ModelState.IsValid)return BadRequest();// Create entity from request modelvar entity = request.ToEntity();// Add entity to repository _dbContext.Add(entity);// Save entity in databaseawait _dbContext.SaveChangesAsync();// Set the entity to response modelresponse.Model = entity;}catch (Exception ex){response.DidError = true;response.ErrorMessage = "There was an internal error, please contact to technical support.";_logger?.LogCritical("There was an error on '{0}' invocation: {1}", nameof(PostStockItemAsync), ex);}return response.ToHttpResponse();}// PUT// api/v1/Warehouse/StockItem/5/// <summary>/// Updates an existing stock item/// </summary>/// <param name="id">Stock item ID</param>/// <param name="request">Request model</param>/// <returns>A response as update stock item result</returns>/// <response code="200">If stock item was updated successfully</response>/// <response code="400">For bad request</response>/// <response code="404">If stock item is not exists</response>/// <response code="500">If there was an internal server error</response>[HttpPut("StockItem/{id}")][ProducesResponseType(200)][ProducesResponseType(400)][ProducesResponseType(404)][ProducesResponseType(500)]public async Task<IActionResult> PutStockItemAsync(int id, [FromBody]PutStockItemsRequest request){_logger?.LogDebug("'{0}' has been invoked", nameof(PutStockItemAsync));var response = new Response();try{// Get stock item by idvar entity = await _dbContext.GetStockItemsAsync(new StockItem(id));// Validate if entity existsif (entity == null)return NotFound();// Set changes to entityentity.StockItemName = request.StockItemName;entity.SupplierId = request.SupplierID;entity.ColorId = request.ColorID;entity.UnitPrice = request.UnitPrice;// Update entity in repository _dbContext.Update(entity);// Save entity in databaseawait _dbContext.SaveChangesAsync();}catch (Exception ex){response.DidError = true;response.ErrorMessage = "There was an internal error, please contact to technical support.";_logger?.LogCritical("There was an error on '{0}' invocation: {1}", nameof(PutStockItemAsync), ex);}return response.ToHttpResponse();}// DELETE// api/v1/Warehouse/StockItem/5/// <summary>/// Deletes an existing stock item/// </summary>/// <param name="id">Stock item ID</param>/// <returns>A response as delete stock item result</returns>/// <response code="200">If stock item was deleted successfully</response>/// <response code="404">If stock item is not exists</response>/// <response code="500">If there was an internal server error</response>[HttpDelete("StockItem/{id}")][ProducesResponseType(200)][ProducesResponseType(404)][ProducesResponseType(500)]public async Task<IActionResult> DeleteStockItemAsync(int id){_logger?.LogDebug("'{0}' has been invoked", nameof(DeleteStockItemAsync));var response = new Response();try{// Get stock item by idvar entity = await _dbContext.GetStockItemsAsync(new StockItem(id));// Validate if entity existsif (entity == null)return NotFound();// Remove entity from repository _dbContext.Remove(entity);// Delete entity in databaseawait _dbContext.SaveChangesAsync();}catch (Exception ex){response.DidError = true;response.ErrorMessage = "There was an internal error, please contact to technical support.";_logger?.LogCritical("There was an error on '{0}' invocation: {1}", nameof(DeleteStockItemAsync), ex);}return response.ToHttpResponse();}} }
View Code
接下来设置依赖注入,ASP.NET Core自带依赖注入,不需要第三方框架
修改根目录下Startup 类,
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.Swagger; using WideWorldImporters.API.Controllers; using WideWorldImporters.API.Models;namespace WideWorldImporters.API {public class Startup{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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);//注入数据库上下文对象services.AddDbContext<WideWorldImportersDbContext>(options =>{options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));//从配置文件中获取数据库连接字符串 });//--------------上面是框架系统的访问,下面是应用程序的注入--------------------services.AddScoped<ILogger, Logger<WarehouseController>>();//只用这里写了这一句,apiController里的注入才有效//注入丝袜哥Swaggerservices.AddSwaggerGen(options =>{options.SwaggerDoc("v1", new Info {Title = "WideWorldImporters API", Version = "v1"});var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);options.IncludeXmlComments(xmlPath);});}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseSwagger();app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/swagger/v1/swagger.json", "WideWorldImporters API V1");});app.UseMvc();}} }
View Code
在appsettings.json文件中添加数据库连接字符串
{"ConnectionStrings": {"DefaultConnection": "Server=(localdb);Database=WideWorldImportersDb;Trusted_Connection=True;MultipleActiveResultSets=true"},"Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*" }
设置项目属性的swagger生成的文件,丝袜哥就是靠这个文件来生成UI的。
设置完,记得保存!
代码写完了,数据库还没有,需要利用EF Core迁移并生成数据库
在命令行输入迁移命令: add-migration AddEntity
生成了迁移文件
然后更新到数据库,输入:update-database
数据库创建完毕。
运行项目试试!!!!
访问地址:
http://localhost:49956/api/v1/Warehouse/StockItem
好像有问题,明天继续吧.................................郁闷了
转载于:https://www.cnblogs.com/wanghaibin/p/10296774.html
在ASP.NET Core 2.2 中创建 Web API并结合Swagger相关推荐
- 在ASP.NET Core 2.0中创建Web API
目录 介绍 先决条件 软件 技能 使用代码 第01步 - 创建项目 第02步 - 安装Nuget包 步骤03 - 添加模型 步骤04 - 添加控制器 步骤05 - 设置依赖注入 步骤06 - 运行We ...
- 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目
今天,Visual Studio中没有内置工具来测试WEB API.使用浏览器,只能测试http GET请求.您需要使用Postman,SoapUI,Fiddler或Swagger等第三方工具来执行W ...
- 【视频教程】使用 ASP.NET Core 3.x 构建 RESTful Web API 已完结
使用 ASP.NET Core 3.x 构建 RESTful Web API 的视频教程已经完结,共50讲,约10.5小时. B站可看,点击原文链接. 度娘盘可下载完整视频: https://pan. ...
- ASP.NET Core 3.1 系列之 Web API 添加身份验证Jwt
ASP.NET Core 3.1 系列之 Web API 中间件篇 (一) 身份验证(Jwt)中间件使用步骤 添加 NuGet程序包 添加包:Microsoft.AspNetCore.Authenti ...
- 使用静态基类方案让 ASP.NET Core 实现遵循 HATEOAS Restful Web API
Hypermedia As The Engine Of Application State (HATEOAS) HATEOAS(Hypermedia as the engine of applicat ...
- php如何访问web api,如何在PHP中创建Web API服务?
SOAP和REST API是广泛使用的API. 考虑存在一个名为manage.php的PHP类,该类有助于管理数据库中的条目.class manage { private $entryId; func ...
- 将终结点图添加到你的ASP.NET Core应用程序中
在本文中,我将展示如何使用DfaGraphWriter服务在ASP.NET Core 3.0应用程序中可视化你的终结点路由.上面文章我向您演示了如何生成一个有向图(如我上篇文章[译]使用DOT语言和G ...
- 在Typescript中使用ASP.NET Core SignalR和React创建实时应用程序
目录 介绍 ScrumPoker应用程序 源代码 开发工具 基本步骤 后端代码 创建Hub 在Startup中注册集线器 创建持久性 让我们为客户端应用程序公开一些终端 启用Cors 前端代码 结论 ...
- ASP.NET Core 3.0中使用动态控制器路由
原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...
最新文章
- 面向完全初学者的Unity和C#游戏开发学习教程
- [转]Linux下pppoe配合Drcom插件上网方法介绍......
- python获取数据库列名_python sqlite3 查询操作及获取对应查询结果的列名
- 在VMware上装苹果系统后全屏
- Java算法--冒泡排序
- python爬去百度搜索结果_python实现提取百度搜索结果的方法
- 配置Java EE应用程序或“将Bien付诸实践”
- Bootstrap页面布局14 - BS按钮群组
- 王道计算机网络 应用层整理 超详细版
- Git GUI,Git Bash,Git CMD标签之间的区别
- hpux系统启动中被某个服务hang住的解决办法
- [bzoj3223]Tyvj 1729 文艺平衡树
- MySQL-第十三篇使用ResultSetMetaData分析结果集
- 51单片机 1-LED灯流水灯 练习3-流水灯(_crol_位移)
- BAT的校园大赛,都秀出了哪些肌肉?
- 【2016】【论文笔记】差频可调谐THz技术——
- 微观经济学--第4章 供给与需求的市场力量
- 引力波探测,冷冻电镜研究:两项诺奖GPU功不可没
- scrapy-splash java,小白程序员-运用Scrapy-splash爬取动态js页面
- 如何检索国家自然科学基金项目信息并下载结题报告
热门文章
- Workflow相关表简单分析
- docker下centos7 systemctl启动报错 docker Failed to get D-Bus connection 报错
- Spring+SpringMVC+maven使用@aspectJ添加切面
- [leetcode]143. Reorder List
- zookeeper之系列五:简单操作
- 对象与控件如何建立关联
- 通过u盘装window7
- ext教程_exe_作者blackant
- 问题 C: 编写函数:字符串的复制 之一 (Append Code)
- php背景图片透明度,css如何使用opacity属性给背景图片加透明度(代码)