# 开发整理问题
# IConfiguration
1.配置文件值读取的顺序
/*
CLI > 环境变量 > appsettings.xx.json > appsettings.json
*/
//源代码解析
IHostingEnvironment hostingEnvironment = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", optional: true, reloadOnChange: true);
if (hostingEnvironment.IsDevelopment())
{
Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
if (assembly != null)
{
config.AddUserSecrets(assembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
# DI 注入详解
# netcore3.1 改 razorpage 需要重新编译解决
//1. 安装 Install-Package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
//2. 在service进行配置
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
//这段话就行
.AddRazorRuntimeCompilation();
}
# UnitTest 调试 WebAPI
//1. nuget 安装 Microsoft.AspNetCore.TestHost
//2. UnitTest项目增加测试辅助类
public class ClientProvider:IDisposable
{
private TestServer _server;
public HttpClient Client { get; private set; }
public ClientProvider()
{
//UseStartup<Startup> 对应webapi的startup类就行了
_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
Client = _server.CreateClient();
}
public void Dispose()
{
_server?.Dispose();
Client?.Dispose();
}
}
//3. 测试调用
public class EmployeeApiIntergrationTests
{
[Fact]
public async Task Test_GetAll()
{
using (var client = new ClientProvider().Client)
{
var response = await client.GetAsync("/api/employee");
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
}
}
# WebAPI 全局的 exception 捕捉
/*
1. 使用 `exceptionHandler` 去处理
2. 自己实现一个中间件去处理
*/
# AspnetCore3.1JSON 日期格式 UTC 异常处理
参考官网链接--JOSN.Text 和 Json.Net 的迁移
使用的库是JSON.Net,由于 3.1 没有设置 json 的格式操作的话,默认就是 UTC 的时间格式,所以导致数据呈现不对.
作为WEBAPI而言的话:JSON.Net是贯穿了整个数据输入和数据输出的规范,所以这个需要花时间去整理下。
//startup.cs里进行如下配置即可
services.AddControllers()
.AddNewtonsoftJson(options=> {
//设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//设置时区
options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
});
//还有一种处理方式使用JSON.Text进行操作,不使用JSON.Net
//startup.cs里进行如下配置即可
services.AddControllers().AddJsonOptions(options=> {
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
options.JsonSerializerOptions.Converters.Add(new DateTimeNullableConvert());
});
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.TryParse(reader.GetString(), out var dateTime) ? dateTime : default(DateTime);
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
public class DateTimeNullableConvert : JsonConverter<DateTime?>
{
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.TryParse(reader.GetString(), out var dateTime) ? dateTime : default(DateTime?);
}
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
# 获取 WEBAPI 请求 Body 内容
AspnetCore3.1之后,默认对应的读取 IO 流操作,服务器全部默认禁用同步读取操作:
Kestrel
HttpSys
IIS in-process
TestServer
实现增加对应的请求流支持
参考链接-github-issue
版本 2.2 到 3.1 的更改
IIS 配置同步读取 IO 流
//实现同步读取方案
//1.kestrel需要手动启用这个配置, Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
//kestrel服务器配置启用同步读取
webBuilder.ConfigureKestrel((context, options) =>
{
options.AllowSynchronousIO = true;
})
;
webBuilder.UseStartup<Startup>();
});
//2. IIS, startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IGreeting, Greeting>();
//IIS启用同步读取流
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
services.AddControllers()
//.AddXmlSerializerFormatters();
;
}
//实现异步读取方案
[HttpPost]
public async Task<IActionResult> TestQimenReqXML()
{
var contents = string.Empty;
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
contents = await reader.ReadToEndAsync();
}
var stu = topsdk_net_core.Util.XmlHelper.XmlDeserialize<Student>(contents);
return Content(contents, "text/xml");
}
# WebApi 序列化
支持请求和序列化 XML 参考链接
//1. 引用包 //Microsoft.AspNetCore.Mvc.Formatters.Xml //2. startup.cs配置 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddXmlSerializerFormatters(); //3. 请求XML格式进行反序列化 //响应 [HttpPost] [Produces("application/xml")] public Student TestQimenRps() { var stu = new Student { Age = 20, Name = "Jack" }; return stu; } //请求转为实体 [HttpPost] [Consumes("application/xml")] public Student TestQimenReq([FromBody]Student student) { var stu = new Student { Age = 20, Name = "Jack" }; return stu; } //JSON格式保持原样 [HttpPost] public Student TestQimenReqJson([FromBody] Student student) { var stu = new Student { Age = 20, Name = "Jack" }; return stu; }
# ApsNetCore 编码处理
根据
System.Text.Encoding.CodePagesnuget 主页 的描述,这个包能为程序提供Windows-1252, Shift-JIS, and GB2312三种编码。
//1. 安装nuget包
//System.Text.Encoding.CodePages
//2.在使用的地方,优先执行注册CodePages的操作,当然可以考虑直接配置全局默认直接注册
System.Text.Encoding.RegisterProvider (System.Text.CodePagesEncodingProvider.Instance);
# Https 接口调用
出现
基础连接已关闭的错误,参考链接
stackoverflow
//注意FrameWork的框架4.5或以上才支持
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;