在ASP.NET Core 2.2 中创建 Web API并结合Swagger
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在ASP.NET Core 2.2 中创建 Web API并结合Swagger,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含23119字,纯文字阅读大概需要34分钟。
内容图文
一、创建 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 21publicint? StockItemID { get; set; } 22 23publicstring StockItemName { get; set; } 24 25publicint? SupplierID { get; set; } 26 27publicint? ColorID { get; set; } 28 29publicint? UnitPackageID { get; set; } 30 31publicint? OuterPackageID { get; set; } 32 33publicstring Brand { get; set; } 34 35publicstring Size { get; set; } 36 37publicint? LeadTimeDays { get; set; } 38 39publicint? QuantityPerOuter { get; set; } 40 41publicbool? IsChillerStock { get; set; } 42 43publicstring Barcode { get; set; } 44 45publicdecimal? TaxRate { get; set; } 46 47publicdecimal? UnitPrice { get; set; } 48 49publicdecimal? RecommendedRetailPrice { get; set; } 50 51publicdecimal? TypicalWeightPerUnit { get; set; } 52 53publicstring MarketingComments { get; set; } 54 55publicstring InternalComments { get; set; } 56 57publicstring CustomFields { get; set; } 58 59publicstring Tags { get; set; } 60 61publicstring SearchDetails { get; set; } 62 63publicint? LastEditedBy { get; set; } 64 65public DateTime? ValidFrom { get; set; } 66 67public DateTime? ValidTo { get; set; } 68 } 69 70publicclass StockItemsConfiguration : IEntityTypeConfiguration<StockItem> 71 { 72publicvoid 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(); 101102// Computed columns103104 builder 105 .Property(p => p.StockItemID) 106 .HasColumnType("int") 107 .IsRequired() 108 .HasComputedColumnSql("NEXT VALUE FOR [Sequences].[StockItemID]"); 109110 builder 111 .Property(p => p.Tags) 112 .HasColumnType("nvarchar(max)") 113 .HasComputedColumnSql("json_query([CustomFields],N‘$.Tags‘)"); 114115 builder 116 .Property(p => p.SearchDetails) 117 .HasColumnType("nvarchar(max)") 118 .IsRequired() 119 .HasComputedColumnSql("concat([StockItemName],N‘ ‘,[MarketingComments])"); 120121// Columns with generated value on add or update122123 builder 124 .Property(p => p.ValidFrom) 125 .HasColumnType("datetime2") 126 .IsRequired() 127 .ValueGeneratedOnAddOrUpdate(); 128129 builder 130 .Property(p => p.ValidTo) 131 .HasColumnType("datetime2") 132 .IsRequired() 133 .ValueGeneratedOnAddOrUpdate(); 134 } 135 } 136137publicclass WideWorldImportersDbContext : DbContext 138 { 139public WideWorldImportersDbContext(DbContextOptions<WideWorldImportersDbContext> options) 140 : base(options) 141 { 142 } 143144protectedoverridevoid OnModelCreating(ModelBuilder modelBuilder) 145 { 146// Apply configurations for entity147148 modelBuilder 149 .ApplyConfiguration(new StockItemsConfiguration()); 150151base.OnModelCreating(modelBuilder); 152 } 153154public DbSet<StockItem> StockItems { get; set; } 155 } 156 }
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; } publicstaticasync Task<StockItem> GetStockItemsAsync(this WideWorldImportersDbContext dbContext, StockItem entity) => await dbContext.StockItems.FirstOrDefaultAsync(item => item.StockItemID == entity.StockItemID); publicstaticasync Task<StockItem> GetStockItemsByStockItemNameAsync(this WideWorldImportersDbContext dbContext, StockItem entity) => await dbContext.StockItems.FirstOrDefaultAsync(item => item.StockItemName == entity.StockItemName); } publicstaticclass IQueryableExtensions { publicstatic 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; } }
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)] publicstring StockItemName { get; set; } [Required] publicint? SupplierID { get; set; } publicint? ColorID { get; set; } [Required] publicint? UnitPackageID { get; set; } [Required] publicint? OuterPackageID { get; set; } [StringLength(100)] publicstring Brand { get; set; } [StringLength(40)] publicstring Size { get; set; } [Required] publicint? LeadTimeDays { get; set; } [Required] publicint? QuantityPerOuter { get; set; } [Required] publicbool? IsChillerStock { get; set; } [StringLength(100)] publicstring Barcode { get; set; } [Required] publicdecimal? TaxRate { get; set; } [Required] publicdecimal? UnitPrice { get; set; } publicdecimal? RecommendedRetailPrice { get; set; } [Required] publicdecimal? TypicalWeightPerUnit { get; set; } publicstring MarketingComments { get; set; } publicstring InternalComments { get; set; } publicstring CustomFields { get; set; } publicstring Tags { get; set; } [Required] publicstring SearchDetails { get; set; } [Required] publicint? LastEditedBy { get; set; } public DateTime? ValidFrom { get; set; } public DateTime? ValidTo { get; set; } } publicclass PutStockItemsRequest { [Required] [StringLength(200)] publicstring StockItemName { get; set; } [Required] publicint? SupplierID { get; set; } publicint? ColorID { get; set; } [Required] publicdecimal? UnitPrice { get; set; } } publicstaticclass Extensions { publicstatic 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 }; } }
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 14bool DidError { get; set; } 15 16string ErrorMessage { get; set; } 17 } 18 19publicinterface ISingleResponse<TModel> : IResponse 20 { 21 TModel Model { get; set; } 22 } 23 24publicinterface IListResponse<TModel> : IResponse 25 { 26 IEnumerable<TModel> Model { get; set; } 27 } 28 29publicinterface IPagedResponse<TModel> : IListResponse<TModel> 30 { 31int ItemsCount { get; set; } 32 33double PageCount { get; } 34 } 35 36publicclass Response : IResponse 37 { 38publicstring Message { get; set; } 39 40publicbool DidError { get; set; } 41 42publicstring ErrorMessage { get; set; } 43 } 44 45publicclass SingleResponse<TModel> : ISingleResponse<TModel> 46 { 47publicstring Message { get; set; } 48 49publicbool DidError { get; set; } 50 51publicstring ErrorMessage { get; set; } 52 53public TModel Model { get; set; } 54 } 55 56publicclass ListResponse<TModel> : IListResponse<TModel> 57 { 58publicstring Message { get; set; } 59 60publicbool DidError { get; set; } 61 62publicstring ErrorMessage { get; set; } 63 64public IEnumerable<TModel> Model { get; set; } 65 } 66 67publicclass PagedResponse<TModel> : IPagedResponse<TModel> 68 { 69publicstring Message { get; set; } 70 71publicbool DidError { get; set; } 72 73publicstring ErrorMessage { get; set; } 74 75public IEnumerable<TModel> Model { get; set; } 76 77publicint PageSize { get; set; } 78 79publicint PageNumber { get; set; } 80 81publicint ItemsCount { get; set; } 82 83publicdouble PageCount 84 => ItemsCount < PageSize ? 1 : (int)(((double)ItemsCount / PageSize) + 1); 85 } 86 87publicstaticclass ResponseExtensions 88 { 89publicstatic IActionResult ToHttpResponse(this IResponse response) 90 { 91var status = response.DidError ? HttpStatusCode.InternalServerError : HttpStatusCode.OK; 92 93returnnew ObjectResult(response) 94 { 95 StatusCode = (int)status 96 }; 97 } 98 99publicstatic IActionResult ToHttpResponse<TModel>(this ISingleResponse<TModel> response) 100 { 101var status = HttpStatusCode.OK; 102103if (response.DidError) 104 status = HttpStatusCode.InternalServerError; 105elseif (response.Model == null) 106 status = HttpStatusCode.NotFound; 107108returnnew ObjectResult(response) 109 { 110 StatusCode = (int)status 111 }; 112 } 113114publicstatic IActionResult ToHttpResponse<TModel>(this IListResponse<TModel> response) 115 { 116var status = HttpStatusCode.OK; 117118if (response.DidError) 119 status = HttpStatusCode.InternalServerError; 120elseif (response.Model == null) 121 status = HttpStatusCode.NoContent; 122123returnnew ObjectResult(response) 124 { 125 StatusCode = (int)status 126 }; 127 } 128 } 129 }
接下来开始添加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>publicasync 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)] publicasync 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)] publicasync 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 model response.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)] publicasync 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 entity entity.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)] publicasync 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(); } } }
接下来设置依赖注入,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.publicvoid 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里的注入才有效 //注入丝袜哥Swagger services.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.publicvoid 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(); } } }
在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.2 中创建 Web API并结合Swagger所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。