DotNetCore技术集锦
.NET Core 和 .NET Standard 中的单元测试
应用程序体系结构指南、云设计模式、云采用框架等等
Global Error Handling in ASP.NET Core Web API
Creating a rolling file logging provider for ASP.NET Core 2.0
serilog日志写到文件-serilog-sinks-file
serilog日志配置参数-serilog-settings-configuration
NLog.Extensions.Logging - NLog provider for Microsoft.Extensions.Logging
NLog Targes:like LiteDB、MongoDB
How to Write a Custom Logging Provider in ASP.NET Core
Logging to a file in .Net Core
asp.net core 日志记录
ILogger级别:Trace = 0、Debug = 1、Information = 2、Warning = 3、Error = 4、Critical = 5 和 None = 6
Serilog.Extensions.Logging.File、NLog、log4net
从控制器操作名称中剪裁的异步后缀,即方法GetAllAsync,请求应是GetAll
Simplifying dependency injection for IConfigureOptions with the ConfigureOptions() helper
.NET Core Dependency Injection - One Interface, Multiple Implementations
Dependency Injection with Multiple Implementations in ASP.NET Core
Registering multiple implementations of the same interface in ASP.NET Core
asp.net core 部署至windows:
第一步:下载并安装.net core sdk,使用浏览器访问 https://dotnet.microsoft.com/download
第二步:下载并安装,使用浏览器访问 https://download.visualstudio.microsoft.com/download/pr/5bed16f2-fd1a-4027-bee3-3d6a1b5844cc/dd22ca2820fadb57fd5378e1763d27cd/dotnet-hosting-3.1.4-win.exe
将 ASP.NET Core 应用发布到 IIS:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/publish-to-iis?view=aspnetcore-3.1&tabs=visual-studio
Microsoft.AspNetCore.Authentication.OAuth
技术点:ASP.NET Core 身份认证中间件;
相关案例源码参考:
【钉钉、QQ/Weixin 登录】 https://github.com/Kiakaa/ExternalLoginMiddleWare
【QQ登录】https://www.nuget.org/packages/AspNet.Security.OAuth.QQ/
【微信登录】 https://www.nuget.org/packages/AspNet.Security.OAuth.Weixin/
AspNet.Security.OAuth.Providers
ASP.NET Core 中的那些认证中间件及一些重要知识点
技术点:ASP.NET Core 服务中实现运行状况检查;使用监视程序(AspNetCore.Diagnostics.HealthChecks、AspNetCore.HealthChecks.UI)
BETTER TIMEOUT HANDLING WITH HTTPCLIENT
技术点:HttpClient设置超时最佳实践。
.net core System.Net.Http Namespace
技术点:ASP.NET Core身份认证、授权。
技术点:async await最佳做法、误区解答
Designing Evolvable Web APIs with ASP.NET: Harnessing the Power of the Web
技术点:HttpClient
Introduction to ASP.NET Web API
技术点:ASP.NET Web API示例教程
.net core应用程序中的数据保护、加解密;加解密中的salt(盐):
// generate a 128-bit salt using a secure PRNG
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
    rng.GetBytes(salt);
}
//利用redis生成唯一的订单号
public async Task<string> GenerateOrderCodeAsync(string key,string prefix)
{
    if (string.IsNullOrEmpty(prefix)) prefix = "1";
    var value = await Db.StringIncrementAsync(key);
    return $"{prefix}{value.ToString().PadLeft(9,'0')}";
}
Microsoft.AspNetCore.DataProtection-示例0001
技术点:.net core数据保护、加解密;使用redis的数据保护包:Microsoft.AspNetCore.DataProtection.StackExchangeRedis
技术点:开源的服务注册与发现相关软件
Dynamic ASP.NET Core Configurations With Consul KV
技术点:asp.net core使用consul kv作为分布式配置中心。
技术点:ASP.NET Core 有可插拔的配置系统,可以从各种源读取配置数据。IOptions<T> 、IOptionsSnapshot<T>
技术点:ASP.NET Core IOptions的使用;ServiceCollectionExtensions中Action的使用
Injecting LiteDb as a service in ASP.NET Core
技术点:ASP.NET Core IOptions的使用;ASP.NET Core LiteDB;LiteDB 限制:https://github.com/mbdavid/LiteDB/wiki/How-LiteDB-Works
ASP.NET CORE Token Authentication and Authorization using JWT (No Cookies) – Part 1
Defensive database context for multi-tenant ASP.NET Core applications –多租户实现
List of ASP.NET Web API and HttpClient Samples
ASP.NET Core Dependency Injection Deep Dive
ASP.NET Core 2.2 - SMTP EmailSender Implementation
ASP.Net core 中Server.MapPath的替换方法
Http相关类
Microsoft.Net.Http.Headers.HeaderNames --headers
System.Net.Mime.MediaTypeNames
System.Net.Mime.MediaTypeNames.Application --Json
System.Net.Mime.MediaTypeNames.Image
System.Net.Mime.MediaTypeNames.Text --Xml
Asp.Net Core 机密管理:
dotnet user-secrets init --project src\Yibi\Yibi.csproj
dotnet user-secrets list --project src\Yibi\Yibi.csproj
dotnet user-secrets set "db_Password" "yourpassword" --project src\Yibi\Yibi.csproj
数据保护:
引入包:<PackageReference Include="Microsoft.AspNetCore.DataProtection.Extensions" Version="$(MicrosoftAspNetCorePackageVersion)" />
services.AddDataProtection()
        .ProtectKeysWithCertificate(accessTokenOptions.Value.SecretKey)
        .UseCustomCryptographicAlgorithms(new ManagedAuthenticatedEncryptorConfiguration
        {
            // A type that subclasses SymmetricAlgorithm
            EncryptionAlgorithmType = typeof(Aes),
            // Specified in bits
            //EncryptionAlgorithmKeySize = 256,
            // A type that subclasses KeyedHashAlgorithm
            ValidationAlgorithmType = typeof(HMACSHA256)
        })
        //.UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration
        //{
        //    EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        //    ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
        //})
        ;
var _dataProtectionProvider = provider.GetRequiredService<IDataProtectionProvider>();
var _protector = _dataProtectionProvider.CreateProtector("ProtectorName");
var input = "123456";
var encryptInput = _protector.Protect(input);
_protector = _dataProtectionProvider.CreateProtector("ProtectorName");
var decryptInput = _protector.Unprotect(encryptInput);
asp.net core 以编程方式发送电子邮件
1、SendGrid
2、MailKit and MimeKit
创建一个CancellationToken:var cancellationToken = default(CancellationToken);
.Net Core依赖注入代码片段集锦:
public static void Main(string[] args)
{
    // add data protection services
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddDataProtection();
    var services = serviceCollection.BuildServiceProvider();
    // create an instance of MyClass using the service provider
    var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
    instance.RunSample();
}
public class MyClass
{
    public void RunSample()
    {
        
    }
}
IServiceProvider:
HttpContext --RequestServices
var someservice = (ISomeService)context.HttpContext.RequestServices.GetService(typeof(ISomeService));
IApplicationBuilder --ApplicationServices:
public void Configure(IApplicationBuilder app)
{
    var serviceProvider = app.ApplicationServices;
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
IServiceProvider provider:
provider.CreateScope().ServiceProvider.GetServices(typeof(IStudentService));
//Accept有效而Content-Type无效
services.AddHttpClient(HttpClientNames.DingtalkClient, client =>
{
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
});
.net core跨域设置代码片段:
public void Configure(IApplicationBuilder app)
{
    app.UseCors(SpecificOrigins.SpecificOriginName);
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(SpecificOrigins.SpecificOriginName,
        builder =>
        {
            //builder.WithOrigins("http://signin.yunexpress.com", "https://signin.yunexpress.com")
            builder.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
    });
    return services.BuildServiceProvider();
}
[EnableCors( SpecificOrigins.SpecificOriginName )]
public class AuthenticationController{
    
}
asp.net core razor:
使用@: 或 <text> 可在c#代码中写js代码。
asp.net core IEndpointRouteBuilder 扩展示例
public static void MapOldParkingApiRoutes(this IEndpointRouteBuilder endpoints)
{
    endpoints.MapControllerRoute(
        name: Routes.OldParkingApiRouteName,
        pattern: "{[a-Z]}/openapi/v99999/parking/{action}",
        defaults: new { controller = "ParkingApi", action = "{action}" });
}
读取环境变量:Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
机密管理:
var config = provider.GetRequiredService<IConfiguration>();
databaseOptions.Value.ConnectionString = databaseOptions.Value.ConnectionString.Trim(';') + $";Password={config["db_Password"]};";
开发过程问题备忘
添加Swagger后未看到相关Controller的接口,访问Swagger页面看到:No operations defined in spec!
解决方法:在Controller上添加 [Route("api/v1/[controller]/[action]")]
Asp.Net Core 6 接口输出json首字母小写格式,改为首字母大写格式的方法:
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
在web.config配置运行环境:
<aspNetCore>
  <environmentVariables>
    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
  </environmentVariables>
</aspNetCore>
.NET CLI 使用发布配置文件 (.pubxml)进行发布:
dotnet publish src/ExSaf/ExSaf.csproj /p:PublishProfile=FolderProfile.pubxml -o F:\Publish\Web
对比dotnet publish -c Release -r win-x64 -p:UseAppHost=false -f net6.0 --self-contained false -o F:\Publish\Web,发现使用发布配置文件 (.pubxml)在F:\Publish\Web目录下的文件最小。
FolderProfile.pubxml:
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <DeleteExistingFiles>false</DeleteExistingFiles>
    <ExcludeApp_Data>false</ExcludeApp_Data>
    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>F:\Publish\ExSaf\Web-Cli-4</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish />
    <TargetFramework>net6.0</TargetFramework>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <ProjectGuid>493c2626-ec27-4d26-a4fa-e3c9a0637b75</ProjectGuid>
    <SelfContained>false</SelfContained>
	<EnvironmentName>Development</EnvironmentName>
  </PropertyGroup>
</Project>
问题:efcore:A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
解决:
sudo nano /etc/ssl/openssl.cnf --打开编辑openssl.cnf文件,经测试未成功...
[SqlClient 故障排除指南](https://docs.microsoft.com/zh-cn/sql/connect/ado-net/sqlclient-troubleshooting-guide?view=sql-server-ver15)
[Released: General Availability of Microsoft.Data.SqlClient 4.0]https://techcommunity.microsoft.com/t5/sql-server-blog/released-general-availability-of-microsoft-data-sqlclient-4-0/ba-p/2983346
微软sql server技术支持电话:8008203800按2转企业然后按3转技术咨询
.NET6.0新的连接字符串属性(如 encrypt、trustServerCertificate、trustStore、trustStorePassword、hostNameInCertificate)
[使用加密进行连接](https://docs.microsoft.com/zh-cn/sql/connect/jdbc/connecting-with-ssl-encryption?view=sql-server-ver15)
导入导出Excel相关类库:
DocumentFormat.OpenXml、EPPlus
Controller Action:
using (var stream = new MemoryStream())
{
    workbook.SaveAs(stream);
    var content = stream.ToArray();
    return File(
        content,
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "users.xlsx");
}
Timer使用:
public class TimerService : IDisposable
{
    private readonly static TimeSpan heartbeatTickRate = TimeSpan.FromSeconds(5);
    public async Task Start()
    {
        if (timer is null)
        {
            timer = new(heartbeatTickRate);
            using (timer)
            {
                while (await timer.WaitForNextTickAsync())
                {
                }
            }
        }
    }
    public void Dispose()
    {
        timer?.Dispose();
    }
}