相信大家前期 debug 需要做這些事情,有時候每隻寫一隻印出來,不如全部印出來。但我不建議全部印出來。
Warning
這是一個新手入3個月寫的,品質不敢保證,但我目前用應該不會跑出任何錯誤。大致上除錯還算滿方便。
最終範例
設定檔isLogShowHeader
和 IsLogShowPostBody
看需求是不是要設定,預設為false
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
public class RequestSpendTimeMiddleWare
{
private DateTime _startTime;
private readonly RequestDelegate _next;
private readonly ILogger<RequestSpendTimeMiddleWare> _logger;
private readonly IConfiguration _configuration;
public RequestSpendTimeMiddleWare(RequestDelegate next,
ILogger<RequestSpendTimeMiddleWare> logger,
IConfiguration configuration)
{
_next = next;
_logger = logger;
_configuration = configuration;
}
public async Task InvokeAsync(HttpContext context)
{
_logger.LogInformation("┌-----------------------------------┐");
_logger.LogInformation("Path: {path}", context.Request.Path);
_logger.LogInformation("Method: {method}", context.Request.Method);
bool isLogShowHeader = IsLogShowHeader();
if (isLogShowHeader)
{
_logger.LogInformation("Header: {Header}", context.Request.Headers);
}
_logger.LogInformation("Content-Type: {contentType}", context.Request.ContentType);
_logger.LogInformation("Query: {query}", context.Request.Query);
bool IsLogShowPostBody = this.IsLogShowPostBody();
_logger.LogInformation("showPostBody: {showPostBody}", IsLogShowPostBody);
if (IsLogShowPostBody)
{
_logger.LogInformation("Body: {body}", await GetPostBody(context));
}
_startTime = DateTime.Now;
// Call the next delegate/middleware in the pipeline
await _next(context);
_logger.LogInformation("執行花費:" + (DateTime.Now - _startTime).TotalSeconds.ToString() + "s");
_logger.LogInformation("└-----------------------------------┘");
}
private bool IsLogShowHeader()
{
return _configuration.GetValue<bool>("IsLogShowHeader");
}
private bool IsLogShowPostBody()
{
return _configuration.GetValue<bool>("IsLogShowPostBody");
}
private static async Task<string> GetPostBody(HttpContext context)
{
if (context.Request.Method == "GET")
{
return "";
}
else if (context.Request.Method == "POST" && context.Request.ContentType.Contains("multipart/form-data;"))
{
return JsonConvert.SerializeObject(context.Request.Form);
}
else
{
return await GetBody(context);
}
}
private static async Task<string> GetBody(HttpContext context)
{
string body;
context.Request.EnableBuffering();
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true))
{
body = await reader.ReadToEndAsync();
}
context.Request.Body.Position = 0;
return body;
}
}
|
問題記錄
1
2
3
4
5
6
7
8
|
using (var reader = new StreamReader(context.Request.Body))
{
requestContent = await reader.ReadToEndAsync();
if (!string.IsNullOrEmpty(requestContent))
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
}
|
實際上跑出 錯誤。
解決方法
參照這篇c# - How to get HttpRequest body in .net core? - Stack Overflow寫法我們看到EnableRewind
.Net Core不能用。後來這篇.NET Core 3.0 的重大變更 - .NET | Microsoft Docs看到改變寫法。
改完發現使用同步方法會有問題,找到Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead. - 天马3798 - 博客园調整設定就可以。但我覺得不需要這麼做,把程式調整非同步就能解決了。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private static async Task<string> GetBody(HttpContext context)
{
string body;
context.Request.EnableBuffering();
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true))
{
body = await reader.ReadToEndAsync();
}
context.Request.Body.Position = 0;
return body;
}
|
其他寫法,但我就不成功就是了,不知他們為什麼能跑…
ASP.NET Core 问题排查:Request.EnableRewind 后第一次读取不到 Request.Body - dudu - 博客园
舊版程式(留記錄,不要使用)
v1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
public class CheckXxxMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<CheckXxxMiddleware> _logger;
private readonly IConfiguration _configuration;
private readonly int HttpXxxValidResult = 400;
public CheckXxxMiddleware(RequestDelegate next, ILogger<CheckXxxMiddleware> logger, IConfiguration configuration)
{
_next = next;
_logger = logger;
_configuration = configuration;
}
public async Task Invoke(HttpContext context)
{
string tsString = await GetTsString(context);
if (string.IsNullOrEmpty(tsString))
{
context.Response.StatusCode = HttpCodeValidResult;
return;
}
...
}
private async Task<string> GetXxxString(HttpContext context)
{
string requestContent;
_logger.LogInformation("Method:{method}", context.Request.Method);
_logger.LogInformation("Path:{path}", context.Request.Path);
_logger.LogInformation("Content-Type:{contentType}", context.Request.ContentType);
_logger.LogInformation("Query:{query}", context.Request.Query);
if (context.Request.Method == "POST" && context.Request.ContentType.Contains("multipart/form-data;"))
{
var data = context.Request.Form;
_logger.LogDebug("data:{data}", data);
if (data.ContainsKey("Xxx"))
{
_logger.LogInformation("Xxx:{Xxx}", data["Xxx"]);
return data["Xxx"];
}
}
else if (context.Request.Method == "POST" && context.Request.ContentType.Contains("application/x-www-form-urlencoded"))
{
context.Request.EnableBuffering();
using (var reader = new StreamReader(context.Request.Body))
{
requestContent = await reader.ReadToEndAsync();
if (!string.IsNullOrEmpty(requestContent))
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
}
_logger.LogInformation("Body:{requestContent}", requestContent);
if (requestContent != null)
{
var queryString = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(requestContent);
_logger.LogInformation("queryString:{queryString}", queryString);
if (queryString.ContainsKey("Xxx"))
{
_logger.LogInformation("Xxx:{Xxx}", queryString["Xxx"]);
}
return queryString["Xxx"];
}
}
else if (context.Request.Method == "POST" && context.Request.ContentType.Contains("json")) //application/json
{
context.Request.EnableBuffering();
using (var reader = new StreamReader(context.Request.Body))
{
requestContent = await reader.ReadToEndAsync();
if (!string.IsNullOrEmpty(requestContent))
{
context.Request.Body.Seek(0, SeekOrigin.Begin);
}
}
_logger.LogInformation("Body:{requestContent}", requestContent);
if (requestContent != null)
{
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(requestContent);
_logger.LogInformation("dynamicObject:{d}", dict);
if (dict.ContainsKey("Xxx"))
{
_logger.LogInformation("Xxx:{Xxx}", dict["Xxx"]);
return dict["Xxx"];
}
}
}
else
{
if (context.Request.Query.ContainsKey("Xxx"))
{
return context.Request.Query["Xxx"];
}
}
return null;
}
}
|