目录
1.Startup.cs文件介绍
.net Core WebApi的启动顺序是
先Program.cs->Startup.cs->Controllers文件夹中的内容
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 Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1
{
public class Startup
{
public Startup(IConfiguration configuration)
{
//初始化,依赖注入IOC
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();
//注册Swagger服务
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication11", Version = "v1", Description="23335" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//.net core中内置kestrel主机,管道模式,中间件,
//这里随意配置中间件,拓展性非常大
if (env.IsDevelopment())
{
//开发者模式的话,启动异常
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"));
app.Use(async (context, next) =>
{
//logger.LogInformation("M1request"); //使用中间件
await next(); //执行下一个中间件,
//logger.LogInformation("M1response"); //先执行一个,结束后返回到这个,再执行这个使用中间件
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();//结束
});
}
}
}
2.路由和URL路径
2.1显示信息:api/路由的名字/具体方法的名字
[Route("api/[controller]/[action]")]
效果:
2.2 加上Name,就是一个参数,实际上ABC是无效的
[HttpGet(Name = "ABC{id}")]
public string A(string id)
{
return id;
}
2.3不加Name,就是一个路径
[HttpGet("ABC{id}")]
public string A1(string id)
{
return id;
}
2.4带斜杠,就是一个子集的路径
[HttpGet("ABC/{id}")]
public string A2(string id)
{
return id;
}
2.5路径带参数
[HttpGet("ABC/{id}")]
public string A3(string id, string a)
{
return id + a;
}
3.返回数据的时间格式化
nuget安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson
只需要在Program.cs 文件下添加几行代码
找到builder.Services.AddControllers()
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});
4.AOP,面向切面
.net。先走构造,再走filter
.net core。先走filter,再走构造,再走filter
例如:onResourceExecuted() 做缓存资源,如果缓存里面有值,下次就不会执行了
Actionfilter,做日志,数据验证,性能监控,数据压缩
例如:onActionExecuing() 先执行。 onActionExecuted() 后执行
获取方法名字:context.RouteData.Values["action"] 参数:context.ActionArguments
全局->控制器->方法
core套娃:中间件,action
5.launchSettings中,设置直接访问
"launchUrl": "swagger/index.html"
6.鉴权授权,token
传统:session/cookies
1.鉴权中心授权
2.请求api+token,非对称可逆加密
7.缓存,性能优化
二八原则,20%是增删改,80%是查询
AOP,面向切面编程:
在执行某一个方法之前,做事情,再执行之后,再做事情。
5大filter,继承Attribute、IResourceFilter,实现接口,做缓存
先走onResourceExecuing() ,再走方法,最后走onResourceExecuted()
如果Nginx加了代理,代码又写了缓存,会产生问题。
网址第一次点击不变,代码产生缓存,第二次点击,网页变化了。
解决办法,内存缓存,使用Redis缓存。
依赖注入,IRedisStringService
8.增加注释
首先在代码中,正常加入注释
在生成的地方勾选
或者项目文件夹中加入
<PropertyGroup>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
然后在Startup.cs中加入代码即可
services.AddSwaggerGen(options => {
// 注释
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
// 第二个参数为是否显示控制器注释,我们选择true
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
});
效果
9.增加版本控制
首先在方法的前面增加版本控制
然后在Startup.cs中加入代码即可
services.AddSwaggerGen(options =>
{
// 注释
//var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
// 第二个参数为是否显示控制器注释,我们选择true
//options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
// 生成多个文档显示
typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
{
//添加文档介绍
options.SwaggerDoc(version, new OpenApiInfo
{
Title = $"项目名",
Version = version,
Description = $"项目名:{version}版本"
});
});
});
app.UseSwaggerUI(options =>
{
//options.SwaggerEndpoint($"/swagger/V1/swagger.json", $"版本选择:V1");
//如果只有一个版本也要和上方保持一致
typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
{
//切换版本操作
//参数一是使用的哪个json文件,参数二就是个名字
options.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"版本选择:{version}");
});
});
public enum ApiVersions
{
/// <summary>
/// 版本V1
/// </summary>
V1 = 1,
/// <summary>
/// 版本V2
/// </summary>
V2 = 2
}
效果
版本1,包含标记的版本V1和没有标记的版本
版本2,包含标记的版本V2和没有标记的版本
10.FromBody和FromForm的区别
首先我们建立一个类
public class Info
{
public string name { get; set; }
public int age { get; set; }
public bool Data { get; set; }
}
FromBody,接收的是一个单体对象,就是JSON串
[HttpPost]
public string TestFromBody([FromBody] Info info)
{
return info.name;
}
前端显示,可见是一个JSON字符串的样式,然后输入值
后端调用,可以看到每一个字段的值
FromForm,接收的是一个实体对象
[HttpPost]
public string TestFromForm([FromForm] Info info)
{
return info.name;
}
前端显示,是给对象中每一个字段赋值,和上面的有点不一样,虽然结果一样,表现方式不一样,明显上面的更加灵活,包含下面的方式。然后输入值
后端调用,也可以看到每一个字段的值
11.webapi返回值类型
[HttpGet]
public async Task<ActionResult<IEnumerable<Person>>> GetPerson(string ID)
{
return await db.Queryable<Person>().Where(s =>s.ID==ID).ToListAsync();
}
[HttpGet]
public async Task<ActionResult<string>> GetUser(string ID)
{
DataTable dt = await db.Ado.GetDataTableAsync($"sql")
return JsonConvert.SerializeObject(dt);
}
12.开发模式和生产模式
appsettings.Development.json,开发模式
appsettings.Production.json,生产模式
using Microsoft.AspNetCore.Mvc;
using System.Text;
namespace WebApplication3.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public readonly IConfiguration configuration;
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration) //注入
{
_logger = logger;
this.configuration = configuration;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
var secretByte = configuration["AuthenticationDemo:SecretKeyDemo"]; //访问变量
Console.WriteLine(secretByte);
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
13.定时任务
参考地址,感谢这位大佬。
https://www.cnblogs.com/ysmc/p/16456787.html
还有BackgroundService, Longbow.Tasks.dll
1.HostedServiceDemo.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Data;
namespace testNet6.Controllers
{
public class HostedServiceDemo : IHostedService, IDisposable
{
private Timer? timer;
public Task StartAsync(CancellationToken cancellationToken)
{
timer = new Timer(DoWork, "123", TimeSpan.Zero, TimeSpan.FromSeconds(1)); //5秒执行一次DoWork的方法
return Task.CompletedTask;
}
private void DoWork(object? state)
{
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"+state); //输出参数
}
public Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("StopAsync");
return Task.CompletedTask;
}
public void Dispose()
{
timer?.Dispose();
}
}
}
2.Program.cs中注入
builder.Services.AddHostedService<HostedServiceDemo>();
3.效果