基础更新

main
bicijinlian 11 months ago
parent 11542e1dda
commit d453c312f2

@ -33,7 +33,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
@ -45,15 +45,7 @@
"languageId": "polyglot-notebook"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello World!\r\n"
]
}
],
"outputs": [],
"source": [
"#! csharp\n",
"Console.WriteLine(\"Hello World!\");"

@ -33,7 +33,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
@ -45,51 +45,7 @@
"languageId": "polyglot-notebook"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> D <20>еľ<D0B5>û<EFBFBD>б<EFBFBD>ǩ<EFBFBD><C7A9>\r\n",
" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><D0BA><EFBFBD> BB7D-E2E7\r\n",
"\r\n",
" d:\\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ\\ѧϰ<D1A7><CFB0>Ŀ\\HttpClientStudy\\Docs <20><>Ŀ¼\r\n",
"\r\n",
"2024/05/30 23:53 <DIR> .\r\n",
"2024/05/28 23:06 <DIR> ..\r\n",
"2024/05/28 23:36 <DIR> .vscode\r\n",
"2024/05/28 23:36 4,778 1.0<EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>.dib\r\n",
"2024/05/28 23:15 7,855 1.1.<2E><><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/30 23:53 27,025 1.2.ʹ<><CAB9>׼<EFBFBD><D7BC>.ipynb\r\n",
"2024/05/31 00:16 5,497 1.3.0.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 1,053 1.3.1.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.3.2.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.3.3.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ.ipynb\r\n",
"2024/05/26 23:55 965 1.3.4.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.3.5.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.ʹ<>ô<EFBFBD><C3B4><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.3.6.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.ʹ<><CAB9>Json.ipynb\r\n",
"2024/05/26 23:55 965 1.3.7.<2E><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>.ʹ<><CAB9>Cookie.ipynb\r\n",
"2024/05/26 23:55 965 1.4.0.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.1.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E><>ʼ<EFBFBD><CABC>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.2.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD>ӳ<EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.3.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E>ظ<EFBFBD>ʹ<EFBFBD><CAB9>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.4.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.ʹ<>ùܵ<C3B9>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.5.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD>ͻ<EFBFBD><CDBB>ͻ<EFBFBD><CDBB><EFBFBD>.ipynb\r\n",
"2024/05/26 23:55 965 1.4.6..<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.<2E><><EFBFBD><EFBFBD>ģʽ.ipynb\r\n",
"2024/05/26 23:55 965 1.4.7.<2E>߼<EFBFBD>ʹ<EFBFBD><CAB9>.Polly.ipynb\r\n",
"2024/05/28 00:31 1,496 1.5.<2E>ܽ<EFBFBD>.ipynb\r\n",
"2024/05/28 23:33 3,204 1.6.<2E><><EFBFBD><EFBFBD>.ipynb\r\n",
"2024/05/28 23:06 4,854 2.1.<2E>ں<EFBFBD><DABA>еĸ<D0B5><C4B8><EFBFBD>·<EFBFBD><C2B7>.ipynb\r\n",
"2024/05/26 23:55 <DIR> Assets\r\n",
"2024/05/28 01:12 <DIR> Publish\r\n",
"2024/05/28 23:06 112 ѧϰ.ps1\r\n",
"2024/05/26 23:55 181 ˵<><CBB5>.md\r\n",
" 24 <20><><EFBFBD>ļ<EFBFBD> 69,565 <20>ֽ<EFBFBD>\r\n",
" 5 <20><>Ŀ¼ 383,550,734,336 <20><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>\r\n",
"\r\n"
]
}
],
"outputs": [],
"source": [
"//引用项目\n",
"#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n",
@ -104,7 +60,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## 启动项目"
"## 2、Powershell 管理项目"
]
},
{
@ -173,8 +129,68 @@
"else {\n",
" $WebAppProc.Kill();\n",
" Write-Host \"$WebAppProcName 进程已退出\"\n",
"}\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3、C#类库管理项目"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"//启动已发布的WebApi项目\n",
"#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n",
"\n",
"{\n",
" var file = System.IO.Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe\",System.Environment.CurrentDirectory);\n",
"\n",
" file.Display();\n",
" var message = HttpClientStudy.Core.Utilities.DotnetCommondUtility.RunWebApp(file);\n",
"\n",
" Console.WriteLine(message);\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"//关闭项目进程\n",
"#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n",
"{\n",
" var message = HttpClientStudy.Core.Utilities.DotnetCommondUtility.SopWebApp();\n",
" Console.WriteLine(message);\n",
"}\n"
]
}
],
"metadata": {

@ -33,7 +33,7 @@ namespace HttpClientStudy.Config
public static IConfigurationBuilder AddWebApiConfiguration(this IConfigurationBuilder configuration)
{
//配置文件名称
configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
configuration.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
//配置文件根目录配置项目Dll文件所在目录(被其它项目引用时引用后dll的文件所在目录)
string configDellPath = Path.GetDirectoryName(typeof(WebApiConfig).Assembly.Location) ?? Directory.GetCurrentDirectory();

@ -65,5 +65,88 @@ namespace HttpClientStudy.Core.Utilities
return output;
}
/// <summary>
/// 新窗口启动WebApp项目
/// </summary>
/// <param name="startFile">包含全路径的WebApp项目</param>
/// <returns></returns>
public static string RunWebApp(string startFile)
{
string output = "";
try
{
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = $"Start-Process -FilePath '{startFile}'",
UseShellExecute = false,
CreateNoWindow = false,
};
Process process = new Process()
{
StartInfo = startInfo,
};
process.Start();
output = "新窗口启动WebApp项目已有实例在运行则窗口会自动关闭";
}
catch (Exception ex)
{
output = $"An error occurred: {ex.Message}";
}
return output;
}
/// <summary>
/// 启动新窗口,执行指定文件
/// </summary>
/// <param name="startFile">包含全路径的可执行文件</param>
/// <returns></returns>
public static string SopWebApp()
{
string output = "";
try
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = $"Stop-Process -Name '{projectAndMutexName}'",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
StandardOutputEncoding = Encoding.UTF8,
};
Process process = new Process()
{
StartInfo = startInfo,
};
process.Start();
process.WaitForExit();
output = process.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
output = $"An error occurred: {ex.Message}";
}
return output;
}
}
}

@ -43,9 +43,18 @@ namespace HttpClientStudy.UnitTest.UtilitiesTest
[Fact]
public void StartApp_Test()
{
var webapiDll = Path.GetFullPath("../../../../Docs/Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.dll");
var webapiDll = Path.GetFullPath("../../../../Docs/Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe");
var result = DotnetCommondUtility.ExecuteCommand(webapiDll);
var result = DotnetCommondUtility.RunWebApp(webapiDll);
_output.WriteLine(result);
}
[Fact]
public void StopApp_Test()
{
var result = DotnetCommondUtility.SopWebApp();
_output.WriteLine(result);
}

@ -1,4 +1,4 @@

using System.Text;
using System.Diagnostics;
using System.Threading ;
@ -17,44 +17,44 @@ using HttpClientStudy.Config;
namespace HttpClientStudy.WebApp
{
/// <summary>
/// HttpClient学习WebAPI项目
/// HttpClient学习WebAPI项目
/// </summary>
public class Program
{
/// <summary>
/// Main
/// </summary>
/// <param name="args">启动参数</param>
/// <param name="args">启动参数</param>
public static void Main(string[] args)
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
var mutex = new Mutex(true,projectAndMutexName,out bool createdResult);
if (createdResult == false)
{
Console.WriteLine($"已经有一个实例在运行,本实例退出!");
Console.WriteLine($"已经有一个实例在运行,本实例退出!");
return;
}
var builder = WebApplication.CreateBuilder(args);
#region 加载配置文件
#region 加载配置文件
var configBasePath = AppContext.BaseDirectory;
Console.WriteLine($"WebApp配置文件根目录{configBasePath}");
Console.WriteLine($"WebApp配置文件根目录{configBasePath}");
builder.Configuration.SetBasePath(configBasePath);
builder.Configuration.AddJsonFile("appsettings.json", false, true);
builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", true, true);
builder.Configuration.AddJsonFile($"configFiles/Config.json", false, true);
#endregion
#region 向容器注册服务
#region 向容器注册服务
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
//Session中间件依赖项
//Session中间件依赖项
builder.Services.AddDistributedMemoryCache();
//配置Session
//配置Session
builder.Services.AddSession(option =>
{
option.Cookie.Name = "HttpClientStudy";
@ -62,15 +62,15 @@ namespace HttpClientStudy.WebApp
option.IdleTimeout = TimeSpan.FromHours(1);
});
//配置Kestrel服务器选项
//配置Kestrel服务器选项
builder.Services.Configure<KestrelServerOptions>(option =>
{
//ASP.NET Core 3.0 之前的版本AllowSynchronousIO 默认是开启的
//设置 true :允许同步 IO 操作,这样允许接收Get请求中的请求体数据.但只能直接从流中读取,不能自动模型绑定。
//ASP.NET Core 3.0 之前的版本AllowSynchronousIO 默认是开启的
//设置 true :允许同步 IO 操作,这样允许接收Get请求中的请求体数据.但只能直接从流中读取,不能自动模型绑定。
option.AllowSynchronousIO = true;
});
//配置Form表单提交选项
//配置Form表单提交选项
builder.Services.Configure<FormOptions>(options =>
{
//options.BufferBody = true;
@ -80,43 +80,43 @@ namespace HttpClientStudy.WebApp
options.MultipartHeadersLengthLimit = int.MaxValue;
});
//配置Swagger
//配置Swagger
builder.Services.AddSwaggerGen(setup =>
{
#region 定义Swagger文档
//name参数即为SwaggerUI中SwaggerEndpoint方法参数中的{documentName}
//两者必须保持一致,否则异常
setup.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "HttpClient学习", Version = "第1版" });
#region 定义Swagger文档
//name参数即为SwaggerUI中SwaggerEndpoint方法参数中的{documentName}
//两者必须保持一致,否则异常
setup.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "HttpClient学习", Version = "第1版" });
#endregion
#region 包含xml注释
#region 包含xml注释
var xmlCommentFiles = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "HttpClientStudy.*.xml", System.IO.SearchOption.TopDirectoryOnly);
foreach (var xmlFile in xmlCommentFiles)
{
//includeControllerXmlComments参数是否启用控制器上的xml注释
//includeControllerXmlComments参数是否启用控制器上的xml注释
setup.IncludeXmlComments(filePath: xmlFile, includeControllerXmlComments: true);
setup.UseInlineDefinitionsForEnums();
}
#endregion
#region 放置接口Auth授权按钮
#region 放置接口Auth授权按钮
setup.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "请输入带有Bearer的TokenBearer {Token}",
Description = "请输入带有Bearer的TokenBearer {Token}",
//jwt默认的参数名称
//jwt默认的参数名称
Name = "Authorization",
//jwt默认存放 Authorization 信息的位置:此处为请求头中
//jwt默认存放 Authorization 信息的位置:此处为请求头中
In = ParameterLocation.Header,
//验证类型此处使用Api Key
//验证类型此处使用Api Key
Type = SecuritySchemeType.ApiKey
});
#endregion
#region 指定方案应用范围
#region 指定方案应用范围
setup.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
@ -133,11 +133,11 @@ namespace HttpClientStudy.WebApp
});
#endregion
//启用数据注解
//启用数据注解
setup.EnableAnnotations();
});
//配置CORS跨域
//配置CORS跨域
builder.Services.AddCors(option =>
{
option.AddPolicy("AllowAll", builder =>
@ -146,8 +146,8 @@ namespace HttpClientStudy.WebApp
});
});
//认证
builder.Services //认证基础架构
//认证
builder.Services //认证基础架构
.AddAuthentication(authOption =>
{
authOption.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
@ -156,18 +156,18 @@ namespace HttpClientStudy.WebApp
authOption.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authOption.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
//Cookie认证
//Cookie认证
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option =>
{
option.Cookie.Name = ".eds.editor.cookie.authentication.oa2";//设置存储用户登录信息用户Token信息的Cookie名称
option.Cookie.HttpOnly = true;//设置存储用户登录信息用户Token信息的Cookie无法通过客户端浏览器脚本(如JavaScript等)访问到
option.ExpireTimeSpan = TimeSpan.FromDays(3);// 过期时间
option.SlidingExpiration = true;// 是否在过期时间过半的时候,自动延期
option.Cookie.Name = ".eds.editor.cookie.authentication.oa2";//设置存储用户登录信息用户Token信息的Cookie名称
option.Cookie.HttpOnly = true;//设置存储用户登录信息用户Token信息的Cookie无法通过客户端浏览器脚本(如JavaScript等)访问到
option.ExpireTimeSpan = TimeSpan.FromDays(3);// 过期时间
option.SlidingExpiration = true;// 是否在过期时间过半的时候,自动延期
option.LoginPath = "/Account/Login";
option.LogoutPath = "/Account/LoginOut";
//option.AccessDeniedPath = "/Account/Login";
})
//认证
//认证
.AddJwtBearer(option =>
{
option.TokenValidationParameters = new TokenValidationParameters
@ -178,28 +178,28 @@ namespace HttpClientStudy.WebApp
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("0123456789abcdefghigklmnopqrstdf41sadfweqtdfghsdfgsdfweqr")),
//缓冲过期时间总的有效时间等于这个时间加上jwt的过期时间
//缓冲过期时间总的有效时间等于这个时间加上jwt的过期时间
ClockSkew = TimeSpan.FromSeconds(0)
};
});
//授权
//授权
builder.Services.AddAuthorization();
//健康检查
//健康检查
builder.Services.AddHealthChecks();
//普通类
//普通类
builder.Services.AddScoped(provider => new Account() { Id = 0, Name = "服务注入示例", Password = "123456", Role = "IoC" });
builder.Services.AddScoped(provider => new Account() { Id = 0, Name = "服务注入示例", Password = "123456", Role = "IoC" });
builder.Services.AddScoped<AccountService>();
#endregion
var app = builder.Build();
#region 配置Http管道
#region 配置Http管道
//耗时统计中间件
//耗时统计中间件
app.UseMiddleware<UsedTimeMiddleware>();
app.MapHealthChecks("api/health");

@ -1,4 +1,4 @@
{
{
"Logging": {
"LogLevel": {
"Default": "Information",

@ -1,4 +1,4 @@
{
{
"urls": "http://localhost:5189",
"Logging": {
"LogLevel": {

@ -1,8 +1,8 @@
using System.Diagnostics;
using System.Diagnostics;
using HttpClientStudy.Core.Utilities;
//启动WebApi程序
//启动WebApi程序
StartupUtility.StartWebApiProject();
var builder = WebApplication.CreateBuilder(args);
@ -27,26 +27,26 @@ app.UseAuthorization();
app.MapControllers();
#region 退出时关闭WebAPI进程
#region 退出时关闭WebAPI进程
/*
* 1退退
* 2退 ctl+c
* 3退 WebAPI退退
* 1退退
* 2退 ctl+c
* 3退 WebAPI退退
*/
// 获取 IHostApplicationLifetime 实例
// 获取 IHostApplicationLifetime 实例
var applicationLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
// 注册应用程序停止事件关闭WebApi
// 注册应用程序停止事件关闭WebApi
applicationLifetime.ApplicationStopping.Register(() =>
{
//注意:在 Visual Studio 2022 预览版中执行时异常正式版中正常。应该是预案版的Bug
//注意:在 Visual Studio 2022 预览版中执行时异常正式版中正常。应该是预案版的Bug
StartupUtility.ExitWebApiProject();
});
applicationLifetime.ApplicationStopped.Register(() =>
{
Console.WriteLine("程序已停止");
Console.WriteLine("程序已停止");
});
#endregion

@ -1,4 +1,4 @@
{
{
"Logging": {
"LogLevel": {
"Default": "Information",

@ -1,4 +1,4 @@
{
{
"Logging": {
"LogLevel": {
"Default": "Information",

Loading…
Cancel
Save