ASP.NET Core | 笔记

2022-04-01 16:49:43 浏览数 (1)

引言

参考:

  • .NET Platform - .NET 所有开源代码

依赖注入

注入对相同接口的实现: 不一定会替换,如果通过 TryAddxxxx 注册,那么后面注册的无效(会判断是否已经存在实现,若有则不再添加)。 如果使用Addxxx注册,相同的接口将放在一个字典中,然后解析服务的时候解析最后一个。 但是之前注册的依然还在,可以通过遍历Services可以获取所有注册的接口。

依赖注入

AOP

Q:

A:

ASP.NET Core 中的静态文件

参考:

  • ASP.NET Core 中的静态文件 | Microsoft Docs

断点续传

参考:

  • 5653325/.NET-WPF-MinIO: WPF下使用MinIO的.NET SDK进行文件上传,并展示上传进度。
  • wangpengxpy/WebAPiResumeDownload: webapi断点续传几种方式及webclient断点续传下载
  • wangpengxpy/ASP.NETCoreResumeDownload: asp.net core断点续传
  • vivo 应用商店中的断点续传技术剖析 - SegmentFault 思否
  • 服务端基于Http的Range头规则实现断点续传或分段下载(C#) - SegmentFault 思否
  • C#断点续传 - 365lei - 博客园
  • C#实现文件断点续传下载的方法_C#教程_脚本之家
  • c# 断点续传的实现_C#教程_脚本之家
  • C#断点续传 - 365lei - 博客园
  • .net c# 文件分片/断点续传之下载--客户端_mengtoumingren的博客-CSDN博客

WebSocket

参考:

  • ASP.NET Core 中的 WebSocket 支持 | Microsoft Docs
  • WebSocket 教程 - 阮一峰的网络日志
  • 服务器开发- Asp.Net Core中的websocket,并封装一个简单的中间件 - 青城同学 - 博客园

发布

参考:

  • dotnet publish command - .NET CLI | Microsoft Docs
代码语言:javascript复制
dotnet publish [<PROJECT>|<SOLUTION>] [-a|--arch <ARCHITECTURE>]
    [-c|--configuration <CONFIGURATION>]
    [-f|--framework <FRAMEWORK>] [--force] [--interactive]
    [--manifest <PATH_TO_MANIFEST_FILE>] [--no-build] [--no-dependencies]
    [--no-restore] [--nologo] [-o|--output <OUTPUT_DIRECTORY>]
    [--os <OS>] [-r|--runtime <RUNTIME_IDENTIFIER>]
    [--self-contained [true|false]]
    [--no-self-contained] [-v|--verbosity <LEVEL>]
    [--version-suffix <VERSION_SUFFIX>]

dotnet publish -h|--help

在 ASP.NET Core 中 启用跨域

参考:

  • 在 ASP.NET CORE 中 (CORS) 跨 ASP.NET Core | Microsoft Docs

同一源 如果两个 URL 具有相同的方案、主机和端口,则它们具有相同的源 (RFC 6454) 。 这两个 URL 具有相同的来源:

  • https://example.com/foo.html
  • https://example.com/bar.html

这些 URL 的源与前两个 URL 不同:

  • https://example.net:不同的域
  • https://www.example.com/foo.html:不同的子域
  • http://example.com/foo.html:不同的方案
  • https://example.com:9000/foo.html:不同的端口

启用 CORS 有三种方法可以启用 CORS:

  • 在使用命名策略或默认策略的中间件中。
  • 使用 终结点路由。
  • 使用 [EnableCors] 属性。

将 [EnableCors] 属性与命名策略一起使用在限制支持 CORS 的终结点方面提供了最佳控制。 警告 UseCors 必须按正确的顺序调用 。 有关详细信息,请参阅 中间件顺序。 例如, UseCors 在使用 之前必须 UseResponseCaching 调用 UseResponseCaching

UseCors 添加 CORS 中间件。

  • 正确的 UseCors 调用必须位于 之后 UseRouting ,但在 之前 UseAuthorization 。 有关详细信息,请参阅 中间件顺序。
代码语言:javascript复制
app.UseRouting();
app.UseCors();
  • 使用中间件Caching时,在 UseCors 之前调用 UseResponseCaching 。

使用默认策略和中间件的 CORS

代码语言:javascript复制
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    // 注意: AddDefaultPolicy
    options.AddDefaultPolicy(
        builder =>
        {
            builder.WithOrigins("http://*.example.com",
                                "http://www.contoso.com");
        });
});

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

// 注意: UseCors(), 没有指定 CorsPolicyName
app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

补充:

使用默认策略, 允许任意跨域

代码语言:javascript复制
public void ConfigureServices(IServiceCollection services)
{
    // 任意跨域
    services.AddCors(options =>
    {
        options.AddDefaultPolicy(policyBuilder =>
        {
            policyBuilder.AllowAnyHeader()
                .AllowAnyMethod()
                .AllowAnyOrigin();
        });
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    // 注意
    app.UseCors();

    app.UseDefaultFiles();
    app.UseStaticFiles();

    app.UseAuthorization();
}

预检请求 preflight-requests

参考:

  • 预检请求

对于某些 CORS 请求,浏览器会在发出实际请求之前发送额外的 OPTIONS 请求。 此请求称为 预检请求。 如果满足以下 所有 条件,浏览器可以跳过预检请求:

  • 请求方法为 GET、HEAD 或 POST。
  • 应用不会设置、、、或以外的请求标头 Accept Accept-Language Content-Language Content-Type Last-Event-ID
  • Content-Type 标头(如果已设置)具有以下值之一:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

设置预检过期时间

Access-Control-Max-Age标头指定可以缓存对预检请求的响应的多久。 若要设置此标头,请调用 SetPreflightMaxAge :

代码语言:javascript复制
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("MySetPreflightExpirationPolicy",
        builder =>
        {
            builder.WithOrigins("http://example.com")
                   .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
        });
});

builder.Services.AddControllers();

var app = builder.Build();

使用终结点路由和 [HttpOptions] 测试 CORS

使用 基于每个终结点启用 CORS RequireCors 目前 不支持自动预检请求。

请考虑以下代码,该代码使用终结点路由来启用 CORS:

代码语言:javascript复制
// OPTIONS: api/TodoItems2/5
[HttpOptions("{id}")]
public IActionResult PreflightRoute(int id)
{
    return NoContent();
}

这时就无法自动响应预检请求,于是需要显式 响应 OPTIONS

Q&A

补充

SSH

参考:

  • sshnet/SSH.NET: SSH.NET is a Secure Shell (SSH) library for .NET, optimized for parallelism.
  • c# 使用ssh连接远程主机(ssh.net演示) - axel10 - 博客园

使用ssh客户端连接远程主机执行命令,并拿到输出结果:

代码语言:javascript复制
using (var sshClient = new SshClient("host", port,"username", "password"))
{
    sshClient.Connect();
    using (var cmd = sshClient.CreateCommand("ls -l"))
    {
        var res = cmd.Execute();
        Console.Write(res);
    }
}

使用sftp客户端上传文件:

代码语言:javascript复制
using (var sftpClient = new SftpClient("host", port,"username", "password"))
{
    sftpClient.Connect();
    sftpClient.UploadFile(File.Open(@"D:index.html", FileMode.Open),"/root/index.html");
}

下载文件:

代码语言:javascript复制
using (var sftpClient = new SftpClient("host", port,"username", "password"))
{
    sftpClient.Connect();
    using (var stream = File.Open(@"F:index.html", FileMode.OpenOrCreate))
    {
        sftpClient.DownloadFile("/root/index.html", stream);
    }
}

System.NullReferenceException: WebApi.Startup.ConfigureServices(IServiceCollection services)

参考:

  • asp.net core - System.NullReferenceException at Startup.ConfigureServices(IServiceCollection services) in windows server - Stack Overflow
代码语言:javascript复制
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at WebApi.Startup.ConfigureServices(IServiceCollection services) in F:CommeReposOneTreesrcFrameworkPresentationWebApiStartup.cs:line 58
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass12_0.<UseStartup>b__0(HostBuilderContext context, IServiceCollection services)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at WebApi.Program.Main(String[] args) in F:CommeReposOneTreesrcFrameworkPresentationWebApiProgram.cs:line 31

发现,当前不在 WebApi.dll 所处目录,通过 绝对路径 方式运行,会由于找不到 appsettings.json,而导致 _configurationnull 解决: 前往 WebApi.dll 所处目录,运行 dotnet WebApi.dll即可

MySql.Data.EntityFrameworkCore 8.0.22 仅与 Microsoft.EntityFrameworkCore 3.1 兼容

参考:

  • c# - Issue with scaffolding a MySql database with EF Core - Method not found: Void Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapping - Stack Overflow

MySql.Data.EntityFrameworkCore 8.0.22 仅与 Microsoft.EntityFrameworkCore 3.1 兼容。将所有 Microsoft.EntityFramework 包从 5.0.0 降级到 3.1.10 以修复错误。 随着 MySQL Connector/NET 8.0.23 于 2021 年 1 月 18 日的发布,Oracle 现在发布了一个与 Microsoft.EntityFramework 5.0 兼容的不同 NuGet 包:MySql.EntityFrameworkCore。 请参阅此处的版本兼容性表。 或者,您可以尝试切换到Pomelo.EntityFrameworkCore.MySql 5.0.0-alpha.2(或更高版本);请参阅其兼容包版本表。

插件系统

参考:

  • c# - ASP .NET Core MVC 2.1 mvc Views in plugin - Stack Overflow
  • xfrogcn/Xfrogcn.PluginFactory: .net core插件框架
  • 如何在 .NET Core 中使用和调试程序集可卸载性 | Microsoft Docs
  • 使用插件创建 .NET Core 应用程序 - .NET | Microsoft Docs
  • 如何在 .NET Core 中使用和调试程序集可卸载性 | Microsoft Docs
  • dotnetcore/Natasha: 基于 Roslyn 的 C# 动态程序集构建库,该库允许开发者在运行时使用 C# 代码构建域 / 程序集 / 类 / 结构体 / 枚举 / 接口 / 方法等,使得程序在运行的时候可以增加新的模块及功能。Natasha 集成了域管理/插件管理,可以实现域隔离,域卸载,热拔插等功能。 该库遵循完整的编译流程,提供完整的错误提示, 可自动添加引用,完善的数据结构构建模板让开发者只专注于程序集脚本的编写,兼容 stanadard2.0 / netcoreapp3.0 , 跨平台,统一、简便的链式 API。 且我们会尽快修复您的问题及回复您的 issue.
  • weikio/PluginFramework: Everything is a Plugin in .NET

加载 ControllerView

代码语言:javascript复制
var assembly = ...;
services.AddMvc()
    .AddApplicationPart(assembly)

View

代码语言:javascript复制
services.AddMvc().ConfigureApplicationPartManager(apm =>
    {
    foreach (var b in new CompiledRazorAssemblyApplicationPartFactory().GetApplicationParts(AssemblyLoadContext.Default.LoadFromAssemblyPath(".../ViewAssembypath/file.Views.dll")))
        apm.ApplicationParts.Add(b);
    });

合并dll

参考:

  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖 - walterlv

WPF 集成 ASP.NET Core

参考:

  • 使用asp.net core webapi 与 vue 搭建桌面客户端的新尝试 - 知乎

WebView

参考:

  • 【译】来看看 WebWindow,一个跨平台的 .NET Core webview 库 - 知乎
  • kklldog/AServer: AServer是基于asp.net core Kestrel封装的一个超迷你http服务器

进程管理

参考:

  • C#在窗体程序中运行控制台程序并管理其进程_madonghyu的博客-CSDN博客_c#调用进程之后管理
代码语言:javascript复制
public void FrpStart()
{
    if (p != null)
    {
        MessageBox.Show("进程已存在");
        return;
    }
    p = new Process
    {
        // Configure the process using the StartInfo properties.
        StartInfo =
            {
            	//调用的程序名称,比如windows下的cmd,linux下的sh或者bash,即这里要填写控制台程序的路径
                FileName = Utils.GetTempPath()   "/frpc.exe",
                //参数,MainConfig为配置文件路径
                Arguments = "-c "   MainConfig,
                //控制台程序所在的路径
                WorkingDirectory = Utils.GetTempPath(),
                WindowStyle = ProcessWindowStyle.Hidden,
                UseShellExecute = false,
                CreateNoWindow = true,
                //重定向输入输出
                RedirectStandardInput = true,
                RedirectStandardOutput = true
            }
    };
    //监听控制台的输出
    p.OutputDataReceived  = new DataReceivedEventHandler((sender, e) =>
    {
        // Prepend line numbers to each line of the output.
        if (!string.IsNullOrEmpty(e.Data))
        {
            append(e.Data);
        }
    });
    p.Start();
    p.BeginOutputReadLine();
}

注意上面新建进程的参数UseShellExecute = false,如果这里设置为false,那么FileName这个参数中控制台程序的只能用绝对路径,即WorkingDirectory参数无效。 如果不设置UseShellExecute为false,则无法重定向输出。 如果UseShellExecute = true,则FileName可以直接使用控制台程序的名字,前提是WorkingDirectory里面的路径是正确的。

代码语言:javascript复制
public void FrpStart()
{
	//检测是否存在残留的线程,并将其关闭
    Process[] existingPrivoxy = Process.GetProcessesByName("frpc");
    foreach (Process p in existingPrivoxy)
    {
        KillProcess(p);
    }
	..........
    p.Start();
    p.BeginOutputReadLine();
    //将其加入Job
    //Job的初始化省略了,可以在构造函数初始化,使用单例模式
    Job.AddProcess(p.Handle);
}

private static void KillProcess(Process p)
{
    try
    {
        p.CloseMainWindow();
        p.WaitForExit(100);
        if (!p.HasExited)
        {
            p.Kill();
            p.WaitForExit();
        }
    }
    catch (Exception e)
    {
    }
}

HttpClient 上传文件

代码语言:javascript复制
public int UpSound_Request(string address, string fileNamePath, string saveName, ProgressBar progressBar)
{
    int returnValue = 0;
    //要上传的文件
    FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
    //二进制对象
    BinaryReader r = new BinaryReader(fs);
    //时间戳
    string strBoundary = "----------"   DateTime.Now.Ticks.ToString("x");
    byte[] boundaryBytes = Encoding.ASCII.GetBytes("rn--"   strBoundary   "rn");
    //请求的头部信息
    StringBuilder sb = new StringBuilder();
    sb.Append("--");
    sb.Append(strBoundary);
    sb.Append("rn");
    sb.Append("Content-Disposition: form-data; name="");
    sb.Append("file");
    sb.Append(""; filename="");
    sb.Append(saveName);
    sb.Append("";");
    sb.Append("rn");
    sb.Append("Content-Type: ");
    sb.Append("application/octet-stream");
    sb.Append("rn");
    sb.Append("rn");
    string strPostHeader = sb.ToString();
    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);
    // 根据uri创建HttpWebRequest对象   
    HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(address));
    httpReq.Method = "POST";
    //对发送的数据不使用缓存   
    httpReq.AllowWriteStreamBuffering = false;
    //设置获得响应的超时时间(300秒)   
    httpReq.Timeout = 300000;
    httpReq.ContentType = "multipart/form-data; boundary="   strBoundary;
    long length = fs.Length   postHeaderBytes.Length   boundaryBytes.Length;
    long fileLength = fs.Length;
    httpReq.ContentLength = length;
    try
    {
        progressBar.Maximum = int.MaxValue;
        progressBar.Minimum = 0;
        progressBar.Value = 0;
        //每次上传400k  
        int bufferLength = 409600;
        byte[] buffer = new byte[bufferLength]; //已上传的字节数   
        long offset = 0;         //开始上传时间   
        DateTime startTime = DateTime.Now;
        int size = r.Read(buffer, 0, bufferLength);
        Stream postStream = httpReq.GetRequestStream();         //发送请求头部消息   
        postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
        while (size > 0)
        {
            postStream.Write(buffer, 0, size);
            offset  = size;
            progressBar.Value = (int)(offset * (int.MaxValue / length));
            TimeSpan span = DateTime.Now - startTime;
            double second = span.TotalSeconds;
            labTime.Text = "已用时:"   second.ToString("F2")   "秒";
            if (second > 0.001)
            {
                labSpeed.Text = "平均速度:"   (offset / 1024 / second).ToString("0.00")   "KB/秒";
            }
            else
            {
                labSpeed.Text = " 正在连接…";
            }
            labState.Text = "已上传:"   (offset * 100.0 / length).ToString("F2")   "%";
            labSize.Text = (offset / 1048576.0).ToString("F2")   "M/"   (fileLength / 1048576.0).ToString("F2")   "M";
            Application.DoEvents();
            size = r.Read(buffer, 0, bufferLength);
        }
        //添加尾部的时间戳   
        postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
        postStream.Close();
        //获取服务器端的响应   
        WebResponse webRespon = httpReq.GetResponse();
        Stream s = webRespon.GetResponseStream();
        //读取服务器端返回的消息  
        StreamReader sr = new StreamReader(s);
        String sReturnString = sr.ReadLine();
        s.Close();
        sr.Close();
        if (sReturnString == "Success")
        {
            returnValue = 1;
        }
        else if (sReturnString == "Error")
        {
            returnValue = 0;
        }
    }
    catch
    {
        returnValue = 0;
    }
    finally
    {
        fs.Close();
        r.Close();
    }
    return returnValue;
}

通过流式传输上传大型文件

参考:

  • 在 ASP.NET Core 中上传文件 | Microsoft Docs

解析 nuget 的 nupkg

参考:

  • sdk/NuGetExeRestoreCommand.cs · dotnet/sdk

自定义模板

参考:

  • dotnet new 自定义模板 - .NET CLI | Microsoft Docs
  • 自定义.NET Core项目模板 - 知乎
  • 从壹开始前后端分离 39 || 想创建自己的dotnet模板么?看这里 - 老张的哲学 - 博客园
  • 使用 .net core 自定义项目模板_沐雪大神-CSDN博客

JavaScript 拦截请求

参考:

  • 使用 JavaScript 拦截和跟踪浏览器中的 HTTP 请求 - Guide2IT - 博客园

创建 nuget 源代码 、符号包

参考:

  • 从零开始制作 NuGet 源代码包及个人总结(全面支持 .NET Core / .NET Framework / WPF 项目) - jack_Meng - 博客园
  • 如何使用新的符号包格式“.snupkg”发布 NuGet 符号包 | Microsoft Docs
  • 让你发布的nuget包支持源代码调试 - czd890 - 博客园

良好的调试体验依赖于调试符号的存在,因为它们提供了一些关键信息,例如已编译的代码与源代码之间的关联、局部变量的名称、堆栈跟踪等。 你可以使用符号包 (.snupkg) 来分发这些符号,并改善 NuGet 包的调试体验。 请注意,符号包并不是使调试符号可用于库使用者的唯一策略。 还可以通过以下项目属性在 dllexeembed 它们:<DebugType>embedded</DebugType>

创建符号包

如果使用 dotnet CLI 或 MSBuild,则除 .nupkg 文件外,还需要设置 IncludeSymbolsSymbolPackageFormat 属性以创建 .snupkg 文件。

  • 要么将以下属性添加到 .csproj 文件:
代码语言:javascript复制
<PropertyGroup>
    <IncludeSymbols>true</IncludeSymbols>
    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
  • 要么在命令行上指定这些属性:
代码语言:javascript复制
dotnet pack MyPackage.csproj -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg

代码语言:javascript复制
msbuild MyPackage.csproj /t:pack /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg

如果使用 NuGet.exe,除 .nupkg 文件外,可以使用以下命令创建一个 .snupkg 文件:

代码语言:javascript复制
nuget pack MyPackage.nuspec -Symbols -SymbolPackageFormat snupkg

nuget pack MyPackage.csproj -Symbols -SymbolPackageFormat snupkg

发布符号包

  1. 为方便起见,首先使用 NuGet 保存 API 密钥(请参阅发布包)。
代码语言:javascript复制
nuget SetApiKey Your-API-Key
  1. 将主包发布到 nuget.org 后,按如下方式推送符号包。
代码语言:javascript复制
nuget push MyPackage.snupkg
  1. 还可以 使用以下命令__同时推送主包和符号包__。 当前文件夹中必须同时有 .nupkg 和 .snupkg 文件。
代码语言:javascript复制
nuget push MyPackage.nupkg

NuGet 会将两个包发布到 nuget.org。MyPackage.nupkg 先发布,随后 MyPackage.snupkg 发布。

备注 如果没有发布符号包,请检查是否已将 NuGet.org 源配置为 https://api.nuget.org/v3/index.json。 只有 NuGet V3 API 才支持符号包发布。

WebTerm

参考:

  • webssh-xterm.js的简单使用 - 简书

拦截方法

参考:

  • C# 方法拦截器_lishuangquan1987的博客-CSDN博客_c# 拦截器

下载文件

参考:

  • 使用 C# 下载文件的十八般武艺 - Soar、毅 - 博客园
  • bezzad/Downloader: Fast and reliable multipart downloader with asynchronous progress events for .NET applications.
  • WELL-E/AutoUpdater: WPF AutoUpdater

Web 在线代理

参考:

  • jabbany/knProxy: Lightweight, PHP-based Web Proxy that can utilize whatever remote connecting ablities your server has to offer. It should work out of the box. No configuration needed. For educational purposes.
  • NicheOffice/php-web-proxy: Online Web Proxy Website Script Written in PHP

WebAPI 在线文档

  • Swashbuckle 和 ASP.NET Core 入门 | Microsoft Docs

Swashbuckle

参考:

  • asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档_weixin_33907511的博客-CSDN博客
代码语言:javascript复制
Install-Package Swashbuckle.AspNetCore -Version 6.2.3

Startup.cs

代码语言:javascript复制
public class Startup
{
    
    public void ConfigureServices(IServiceCollection services)
    {
        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(options =>
            {
                // https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-6.0&tabs=visual-studio
                options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
                {
                    Version = "v1",
                    Title = "爱发电 Badge",
                    Description = "爱发电 Badge - 由 Afdian.Server 构建",
                    TermsOfService = new Uri("https://github.com/yiyungent/Afdian.Sdk"),
                    Contact = new Microsoft.OpenApi.Models.OpenApiContact
                    {
                        Name = "Contact",
                        Url = new Uri("https://github.com/yiyungent/Afdian.Sdk/issues")
                    },
                    License = new Microsoft.OpenApi.Models.OpenApiLicense
                    {
                        Name = "MIT License",
                        Url = new Uri("https://github.com/yiyungent/Afdian.Sdk/blob/main/LICENSE")
                    },
                    //Extensions = new Microsoft.OpenApi.Models.OpenApiExtensibleDictionary<string, string>() { }
                });

                var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml";
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
            });
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseSwagger();
        app.UseSwaggerUI();
        
        // Others
        app.UseRouting();
        app.UseCors();

        app.UseDefaultFiles();
        app.UseStaticFiles();

        app.UseAuthorization();
        // ...
    }
    
}
Swashbuckle.AspNetCore请求上的 Authorization

参考:

  • Swashbuckle.AspNetCore请求上的空授权标头 - IT屋-程序员软件开发技术分享社区
代码语言:javascript复制
string bearerToken = Request.Headers["Authorization"];
代码语言:javascript复制
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info
    {
        Version = "v1",
        Title = "Employee Navigator",
        Description = "Authorization Key: Z29vZEtleQ==",
    });
    c.AddSecurityDefinition("Bearer", new ApiKeyScheme
    {
        Name = "Authorization",
        In = "header",
        Type = "apiKey",
        Description = "Authorization Key: Z29vZEtleQ=="
    });
    c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
    {
        { "Bearer", new[] { "readAccess", "writeAccess" } 
    });
    
});
多 API Version

参考:

  • asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档_weixin_33907511的博客-CSDN博客
补充

如何忽略一个接口 为 Controller 或者 Action 方法上添加特性标记 [ApiExplorerSettings(IgnoreApi =true)] 即可

.NET6 手动配置启动项地址

代码语言:javascript复制
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.WebHost.ConfigureKestrel((context, options) =>
{
  options.Listen(IPAddress.Any, 5001, listenOptions =>
  {
    listenOptions.UseHttps();
  });
});
var app = builder.Build();

## Kestrel 请求体最大为 50MB

代码语言:javascript复制
// 设置应用服务器Kestrel请求体最大为50MB 52428800
builder.WebHost.ConfigureKestrel(o => o.Limits.MaxRequestBodySize = null);

// 设置即重置文件上传的大小限制 
builder.Services.Configure<FormOptions>(o =>
{
    o.MultipartBodyLengthLimit = long.MaxValue;
});

参考

感谢帮助!

  • 本文作者: yiyun
  • 本文链接: https://moeci.com/posts/分类-dotnet/aspnetcore-notebook/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

0 人点赞