Skip to content

Commit 048b0e4

Browse files
authored
Merge pull request #337 from Senparc/Develop
Develop
2 parents c5db8ba + 98db3b1 commit 048b0e4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+41469
-4
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ Senparc.CO2NET is already relied upon as the foundational library for Senparc se
2525
| MagicObject (New) | Senparc.CO2NET.MagicObject | [![Senparc.CO2NET.MagicObject][6.1]][6.2] [![Senparc.CO2NET.MagicObject][nuget-img-base-magic-object]][nuget-url-base-magic-object] | ![.NET 3.5][net35N] ![.NET 4.0][net40N] ![.NET 4.6.2][net462Y] ![.NET Core 2.0][core20Y]
2626

2727

28-
![.NET Core 2.0][core20Y] : Supports .NET Standard 2.0+ and .NET Core 2.1/3.1, .NET 5.0/6.0/7.0/8.0+
28+
![.NET Core 2.0][core20Y] : Supports .NET Standard 2.0+ and .NET Core 2.1/3.1, .NET 5.0/6.0/7.0/8.0/10.0+
29+
30+
> [!NOTE]
31+
> **.NET 10.0 is the recommended version** for new projects. It provides the latest features, performance improvements, and long-term support.
2932
3033
> [!NOTE]
3134
> CO2NET will gradually stop supporting .NET Framework 4.0 and earlier versions. Because the official update has stopped.

README.zh.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ Senparc.CO2NET 已经作为 [Senparc.Weixin SDK](https://github.com/JeffreySu/We
2727
| MagicObject(新) | Senparc.CO2NET.MagicObject | [![Senparc.CO2NET.MagicObject][6.1]][6.2] [![Senparc.CO2NET.MagicObject][nuget-img-base-magic-object]][nuget-url-base-magic-object] | ![.NET 3.5][net35N] ![.NET 4.0][net40N] ![.NET 4.6.2][net462Y] ![.NET Core 2.0][core20Y]
2828

2929

30-
![.NET Core 2.0][core20Y] : 同时支持 .NET Standard 2.0+ 及 .NET Core 2.1/3.1、.NET 5.0/6.0/7.0/8.0+
30+
![.NET Core 2.0][core20Y] : 同时支持 .NET Standard 2.0+ 及 .NET Core 2.1/3.1、.NET 5.0/6.0/7.0/8.0/10.0+
31+
32+
> [!NOTE]
33+
> **.NET 10.0 是新项目的推荐版本**,它提供了最新的功能、性能改进和长期支持。
3134
3235
> [!NOTE]
3336
> CO2NET 将逐步停止对 .NET Framework 4.0 及以下版本的支持。

Sample/Senparc.CO2NET.Sample-with-net10.sln

Lines changed: 228 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<Configurations>Debug;Release;Test</Configurations>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<None Remove="appsettings.Development.json" />
11+
<None Remove="appsettings.json" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<Content Include="appsettings.Development.json">
16+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
17+
</Content>
18+
<Content Include="appsettings.json">
19+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
20+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
21+
</Content>
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
26+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
27+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
28+
<PackageReference Include="Microsoft.Net.Http.Headers" Version="10.0.0" />
29+
30+
<!--<FrameworkReference Include="Microsoft.AspNetCore.App" />-->
31+
32+
</ItemGroup>
33+
34+
<ItemGroup>
35+
<ProjectReference Include="..\..\src\Senparc.CO2NET.APM\Senparc.CO2NET.APM.csproj" />
36+
<ProjectReference Include="..\..\src\Senparc.CO2NET.Cache.CsRedis\Senparc.CO2NET.Cache.CsRedis.csproj" />
37+
<ProjectReference Include="..\..\src\Senparc.CO2NET.Cache.Memcached\Senparc.CO2NET.Cache.Memcached.csproj" />
38+
<ProjectReference Include="..\..\src\Senparc.CO2NET.Cache.Redis.RedLock\redlock-cs\src\Senparc.CO2NET.Cache.Redis.RedLock.csproj" />
39+
<ProjectReference Include="..\..\src\Senparc.CO2NET.Cache.Redis\Senparc.CO2NET.Cache.Redis.csproj" />
40+
<ProjectReference Include="..\..\src\Senparc.CO2NET.WebApi\Senparc.CO2NET.WebApi.csproj" />
41+
<ProjectReference Include="..\..\src\Senparc.CO2NET\Senparc.CO2NET.csproj" />
42+
</ItemGroup>
43+
44+
</Project>
45+
110 KB
Loading
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Http;
9+
using Microsoft.AspNetCore.Http.Extensions;
10+
using Microsoft.AspNetCore.Http.Features;
11+
using Microsoft.AspNetCore.Mvc;
12+
using Microsoft.Extensions.Logging;
13+
using Senparc.CO2NET.Cache;
14+
using Senparc.CO2NET.HttpUtility;
15+
using Senparc.CO2NET.Sample.net10.Models;
16+
using Senparc.CO2NET.Trace;
17+
using Senparc.CO2NET.Utilities.HttpUtility.HttpPost;
18+
19+
namespace Senparc.CO2NET.Sample.net10.Controllers
20+
{
21+
public class HomeController : Controller
22+
{
23+
private readonly ILogger<HomeController> _logger;
24+
private readonly IServiceProvider _serviceProvider;
25+
26+
public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider /*,IBaseObjectCacheStrategy oCache*/)
27+
{
28+
_logger = logger;
29+
_serviceProvider = serviceProvider;
30+
}
31+
32+
public async Task<IActionResult> Index()
33+
{
34+
var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();
35+
var dt1 = SystemTime.Now;
36+
var count = await cache.GetAsync<int>("IndexTest");
37+
var dt2 = SystemTime.Now;
38+
count++;
39+
await cache.SetAsync("IndexTest", count);
40+
var dt3 = SystemTime.Now;
41+
42+
ViewData["IndexTest"] = count;
43+
ViewData["CacheType"] = cache.GetType();
44+
ViewData["CacheCost"] = $"缓存读取:{(dt2 - dt1).TotalMilliseconds}ms,缓存写入:{(dt3 - dt2).TotalMilliseconds}ms";
45+
46+
return View();
47+
}
48+
49+
/// <summary>
50+
/// 测试日志记录
51+
/// </summary>
52+
/// <returns></returns>
53+
public IActionResult LogTest()
54+
{
55+
var logMsg = $"加入到队列,通过 {Request.PathAndQuery()} 访问,{SystemTime.Now.ToString()}";
56+
SenparcTrace.SendCustomLog("日志记录测试", logMsg);
57+
return Content($"记录完成,请到【App_Data/SenparcTraceLog/SenparcTrace-{SystemTime.Now.ToString("yyyyMMdd")}.log】文件下查看记录,记录内容:{logMsg}");
58+
}
59+
60+
61+
#region Post 方法测试
62+
63+
#region Post 参数
64+
65+
/// <summary>
66+
/// Post方法测试
67+
/// </summary>
68+
/// <returns></returns>
69+
[HttpGet]
70+
public IActionResult PostParameter()
71+
{
72+
var formData = new Dictionary<string, string>()
73+
{
74+
{ "code", SystemTime.NowTicks.ToString() }
75+
};
76+
77+
var dt = SystemTime.Now;
78+
79+
var result = RequestUtility.HttpPost(_serviceProvider, "http://localhost:5172/Home/PostParameter", formData: formData);
80+
81+
result += $" | Cost:{SystemTime.DiffTotalMS(dt)}ms";
82+
return Content(result);
83+
}
84+
85+
86+
[HttpPost]
87+
public IActionResult PostParameter(string code)
88+
{
89+
HttpContext.Response.Cookies.Append("Time", SystemTime.Now.ToString());
90+
return Content($"已经到达Post目标地址。{SystemTime.Now}, code: {code}");
91+
}
92+
93+
#endregion
94+
95+
#region Post 文件
96+
97+
/// <summary>
98+
/// 记录耗时,并返回平均时间
99+
/// </summary>
100+
/// <param name="byStream"></param>
101+
/// <param name="cost"></param>
102+
/// <returns></returns>
103+
private async Task<double> RecordTimeCost(string byStream, TimeSpan cost)
104+
{
105+
var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();
106+
var cacheKey = $"RecordTimeCost-{byStream}";
107+
dynamic record;
108+
if (await cache.CheckExistedAsync(cacheKey))
109+
{
110+
record = await cache.GetAsync<dynamic>(cacheKey);
111+
record = new { ViewCount = record.ViewCount + 1, TotalCost = ((TimeSpan)record.TotalCost).Add(cost) };
112+
//record.ViewCount++;//增加访问量
113+
//record.TotalCost = ((TimeSpan)record.TotalCost).Add(cost);//增加总耗时
114+
}
115+
else
116+
{
117+
record = new { ViewCount = 1, TotalCost = cost };
118+
}
119+
120+
await cache.SetAsync(cacheKey, record, TimeSpan.FromMinutes(10));//更新信息
121+
122+
return ((TimeSpan)record.TotalCost).TotalMilliseconds / (int)record.ViewCount;
123+
}
124+
125+
public async Task<IActionResult> PostFile(string byStream = null)
126+
{
127+
var dt1 = SystemTime.Now;
128+
var filePath = Path.GetFullPath("App_Data/cover.png");//也可以上传其他任意文件
129+
var fileDictionary = new Dictionary<string, string>();
130+
if (byStream != null)
131+
{
132+
//使用Stream传入,而不是文件名
133+
SenparcTrace.SendCustomLog("Post 文件信息", $"使用文件流放入 fileDictionary 中,并将修改文件名。");
134+
using (var fs = System.IO.File.OpenRead(filePath))
135+
{
136+
var formFileData = new FormFileData(Path.GetFileName(filePath), fs);
137+
formFileData.FileName = $"changed-{formFileData.FileName}";//修改文件名
138+
fileDictionary["image"] = formFileData.GetFileValue();
139+
}
140+
}
141+
else
142+
{
143+
SenparcTrace.SendCustomLog("Post 文件信息", $"使用文件物理地址放入 fileDictionary 中,保留原文件名。");
144+
fileDictionary["image"] = filePath;
145+
}
146+
147+
var url = "http://localhost:5172/Home/PostFile";
148+
var result = await RequestUtility.HttpPostAsync(_serviceProvider, url, fileDictionary: fileDictionary);//获取图片的base64编码
149+
var note = byStream != null ? "使用文件流" : "使用文件名";
150+
var timeCost = SystemTime.NowDiff(dt1);
151+
var averageCost = await RecordTimeCost(byStream, timeCost);
152+
var html = $@"<html>
153+
<head>
154+
<meta http-equiv=Content-Type content=""text/html;charset=utf-8"">
155+
<title>CO2NET 文件 Post 测试 - {note}</title>
156+
</head>
157+
<body>
158+
<p>如果在下方看到《微信开发深度解析》图书封面,表示测试成功({note})。可通过 SenparcTrace 日志查看更多过调试信息日志。</p>
159+
<p>耗时:{timeCost.TotalMilliseconds} ms,平均:{averageCost} ms</p>
160+
<img src=""data:image/png; base64,{result}"" />
161+
</body>
162+
</html>";
163+
return Content(html, "text/html");
164+
}
165+
166+
[HttpPost]
167+
public async Task<IActionResult> PostFile(IFormFile image)
168+
{
169+
using (var ms = new MemoryStream())
170+
{
171+
await image.CopyToAsync(ms);
172+
ms.Seek(0, SeekOrigin.Begin);
173+
174+
byte[] bytes = new byte[ms.Length];
175+
await ms.ReadAsync(bytes, 0, bytes.Length);
176+
177+
var base64 = Convert.ToBase64String(bytes);
178+
179+
SenparcTrace.SendCustomLog("Post 文件信息", $"Name:{image.Name},FileName:{image.FileName},Length:{image.Length}");
180+
181+
return Content(base64, "text/plain");
182+
}
183+
}
184+
185+
[HttpPost]
186+
public async Task<IActionResult> TestGetRequestMemoryStreamAsync()
187+
{
188+
189+
var bodyStream = await Senparc.CO2NET.AspNet.HttpUtility.RequestUtility.GetRequestMemoryStreamAsync(Request);
190+
bodyStream.Position = 0;
191+
string content;
192+
using (StreamReader sr = new StreamReader(bodyStream))
193+
{
194+
content = await sr.ReadToEndAsync();
195+
}
196+
return Content("Post Body数据:" + content);
197+
}
198+
199+
#endregion
200+
201+
202+
203+
#endregion
204+
205+
public IActionResult Privacy()
206+
{
207+
return View();
208+
}
209+
210+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
211+
public IActionResult Error()
212+
{
213+
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
214+
}
215+
}
216+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Swashbuckle.AspNetCore.Annotations;
3+
4+
namespace Senparc.CO2NET.Sample.net10.Controllers
5+
{
6+
[Route("api/[controller]")]
7+
//[ApiController]
8+
public class ValuesController : ControllerBase
9+
{
10+
[HttpGet]
11+
[SwaggerOperationAttribute(Tags = new[] { "v1.0:版本1.0", "v2.0:版本2.0" })]
12+
[Route("/api/toget")]
13+
public string OnGet(string name, int value)
14+
{
15+
return $"{name}:{value}";
16+
}
17+
18+
[HttpPost]
19+
[SwaggerOperationAttribute(Tags = new[] { "v2.0:版本2.0" })]
20+
public string OnPost(string name, int value)
21+
{
22+
return $"{name}:{value}";
23+
}
24+
25+
}
26+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace Senparc.CO2NET.Sample.net10.Models
4+
{
5+
public class ErrorViewModel
6+
{
7+
public string RequestId { get; set; }
8+
9+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
10+
}
11+
}

0 commit comments

Comments
 (0)