diff --git a/.vs/ProjectEvaluation/simpletodoapiwithpg.metadata.v10.bin b/.vs/ProjectEvaluation/simpletodoapiwithpg.metadata.v10.bin new file mode 100644 index 0000000..6110686 Binary files /dev/null and b/.vs/ProjectEvaluation/simpletodoapiwithpg.metadata.v10.bin differ diff --git a/.vs/ProjectEvaluation/simpletodoapiwithpg.projects.v10.bin b/.vs/ProjectEvaluation/simpletodoapiwithpg.projects.v10.bin new file mode 100644 index 0000000..8a8139e Binary files /dev/null and b/.vs/ProjectEvaluation/simpletodoapiwithpg.projects.v10.bin differ diff --git a/.vs/ProjectEvaluation/simpletodoapiwithpg.strings.v10.bin b/.vs/ProjectEvaluation/simpletodoapiwithpg.strings.v10.bin new file mode 100644 index 0000000..83e494f Binary files /dev/null and b/.vs/ProjectEvaluation/simpletodoapiwithpg.strings.v10.bin differ diff --git a/.vs/SimpleTodoApiWithPg/ColorByRegexConfig.txt b/.vs/SimpleTodoApiWithPg/ColorByRegexConfig.txt new file mode 100644 index 0000000..a8e5dd4 --- /dev/null +++ b/.vs/SimpleTodoApiWithPg/ColorByRegexConfig.txt @@ -0,0 +1,10 @@ +// 此文件包含按正则表达式对文档选项卡进行着色的规则。每行都包含一个正则表达式,该表达式将针对文件的完整路径进行测试。与正则表达式匹配的所有文件都将共享一种颜色。 +// 可以通过右键单击选项卡并选择“设置制表符颜色”来自定义分配给任何文件组的颜色。 +// 正则表达式将按照它们在此文件中的显示顺序进行匹配。有关语法,请参阅 https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expressions。 +// 正则表达式匹配为不区分大小写。可以使用捕获组选项(如"(?-i:expression)")重写此行为。 +// 编辑此文件并保存更改以立即查看应用的更改。分析或计算表达式期间遇到的任何错误都将出现在名为 "按正则表达式显示颜色" 的窗格的输出窗口中。 +^.*\.cs$ +^.*\.fs$ +^.*\.vb$ +^.*\.cp?p?$ +^.*\.hp?p?$ diff --git a/.vs/SimpleTodoApiWithPg/DesignTimeBuild/.dtbcache.v2 b/.vs/SimpleTodoApiWithPg/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..a063852 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/SimpleTodoApiWithPg/FileContentIndex/25c513d7-515b-4ac0-b67b-ba0b2a3c284e.vsidx b/.vs/SimpleTodoApiWithPg/FileContentIndex/25c513d7-515b-4ac0-b67b-ba0b2a3c284e.vsidx new file mode 100644 index 0000000..2a3eb44 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/FileContentIndex/25c513d7-515b-4ac0-b67b-ba0b2a3c284e.vsidx differ diff --git a/.vs/SimpleTodoApiWithPg/FileContentIndex/7062b526-4573-455f-a6a3-6f68c43cdd52.vsidx b/.vs/SimpleTodoApiWithPg/FileContentIndex/7062b526-4573-455f-a6a3-6f68c43cdd52.vsidx new file mode 100644 index 0000000..5d00541 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/FileContentIndex/7062b526-4573-455f-a6a3-6f68c43cdd52.vsidx differ diff --git a/.vs/SimpleTodoApiWithPg/FileContentIndex/c94e85ec-7ca1-4331-8261-dcc83e7478f3.vsidx b/.vs/SimpleTodoApiWithPg/FileContentIndex/c94e85ec-7ca1-4331-8261-dcc83e7478f3.vsidx new file mode 100644 index 0000000..d567308 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/FileContentIndex/c94e85ec-7ca1-4331-8261-dcc83e7478f3.vsidx differ diff --git a/.vs/SimpleTodoApiWithPg/FileContentIndex/cca76511-8d74-48bd-bf47-3b8d58286f64.vsidx b/.vs/SimpleTodoApiWithPg/FileContentIndex/cca76511-8d74-48bd-bf47-3b8d58286f64.vsidx new file mode 100644 index 0000000..eb6365e Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/FileContentIndex/cca76511-8d74-48bd-bf47-3b8d58286f64.vsidx differ diff --git a/.vs/SimpleTodoApiWithPg/FileContentIndex/d6935050-fa29-47ea-94e5-da2587d1e359.vsidx b/.vs/SimpleTodoApiWithPg/FileContentIndex/d6935050-fa29-47ea-94e5-da2587d1e359.vsidx new file mode 100644 index 0000000..69f7f34 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/FileContentIndex/d6935050-fa29-47ea-94e5-da2587d1e359.vsidx differ diff --git a/.vs/SimpleTodoApiWithPg/config/applicationhost.config b/.vs/SimpleTodoApiWithPg/config/applicationhost.config new file mode 100644 index 0000000..cdd2df8 --- /dev/null +++ b/.vs/SimpleTodoApiWithPg/config/applicationhost.config @@ -0,0 +1,1026 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.vs/SimpleTodoApiWithPg/customized-groupid-color-f282ea13-0551-44cf-8646-b8083627ac40.json b/.vs/SimpleTodoApiWithPg/customized-groupid-color-f282ea13-0551-44cf-8646-b8083627ac40.json new file mode 100644 index 0000000..faccbe7 --- /dev/null +++ b/.vs/SimpleTodoApiWithPg/customized-groupid-color-f282ea13-0551-44cf-8646-b8083627ac40.json @@ -0,0 +1,9 @@ +{ + "Version": 1, + "ColorMap": { + "-1429170308": { + "GroupId": -1429170308, + "ColorIndex": 6 + } + } +} \ No newline at end of file diff --git a/.vs/SimpleTodoApiWithPg/v18/.futdcache.v2 b/.vs/SimpleTodoApiWithPg/v18/.futdcache.v2 new file mode 100644 index 0000000..9fd79d8 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/v18/.futdcache.v2 differ diff --git a/.vs/SimpleTodoApiWithPg/v18/.suo b/.vs/SimpleTodoApiWithPg/v18/.suo new file mode 100644 index 0000000..d70b7e1 Binary files /dev/null and b/.vs/SimpleTodoApiWithPg/v18/.suo differ diff --git a/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.backup.json b/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.backup.json new file mode 100644 index 0000000..3866d01 --- /dev/null +++ b/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.backup.json @@ -0,0 +1,123 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\code\\SimpleTodoApiWithPg\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\endpoints\\userendpoints.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:endpoints\\userendpoints.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\userservice\\userservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:userservice\\userservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\validators\\registerrequestvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:validators\\registerrequestvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\models\\requestmodels.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:models\\requestmodels.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\filters\\validationfilter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:filters\\validationfilter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 5, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "ValidationFilter.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Filters\\ValidationFilter.cs", + "RelativeDocumentMoniker": "Filters\\ValidationFilter.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Filters\\ValidationFilter.cs", + "RelativeToolTip": "Filters\\ValidationFilter.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACAAAABQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-10T03:34:07.652Z" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "RegisterRequestValidator.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Validators\\RegisterRequestValidator.cs", + "RelativeDocumentMoniker": "Validators\\RegisterRequestValidator.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Validators\\RegisterRequestValidator.cs", + "RelativeToolTip": "Validators\\RegisterRequestValidator.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAlAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T14:31:43.048Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "Program.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Program.cs", + "RelativeDocumentMoniker": "Program.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Program.cs", + "RelativeToolTip": "Program.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T13:19:43.049Z" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "RequestModels.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Models\\RequestModels.cs", + "RelativeDocumentMoniker": "Models\\RequestModels.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Models\\RequestModels.cs", + "RelativeToolTip": "Models\\RequestModels.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAywCYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T07:39:50.184Z" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "UserEndpoints.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Endpoints\\UserEndpoints.cs", + "RelativeDocumentMoniker": "Endpoints\\UserEndpoints.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Endpoints\\UserEndpoints.cs", + "RelativeToolTip": "Endpoints\\UserEndpoints.cs", + "ViewState": "AgIAACEAAAAAAAAAAAAAADUAAAANAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-08T14:40:19.751Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "UserService.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\UserService\\UserService.cs", + "RelativeDocumentMoniker": "UserService\\UserService.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\UserService\\UserService.cs", + "RelativeToolTip": "UserService\\UserService.cs", + "ViewState": "AgIAAGgAAAAAAAAAAAAAAHcAAAAlAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-08T06:47:44.742Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.json b/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.json new file mode 100644 index 0000000..8d9e87d --- /dev/null +++ b/.vs/SimpleTodoApiWithPg/v18/DocumentLayout.json @@ -0,0 +1,140 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\code\\SimpleTodoApiWithPg\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\appsettings.development.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:appsettings.development.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\endpoints\\userendpoints.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:endpoints\\userendpoints.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\userservice\\userservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:userservice\\userservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\validators\\registerrequestvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:validators\\registerrequestvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\models\\requestmodels.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:models\\requestmodels.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|c:\\code\\simpletodoapiwithpg\\filters\\validationfilter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B05B3AC1-7A56-9B3F-B9E1-F21523CC0473}|SimpleTodoApiWithPg.csproj|solutionrelative:filters\\validationfilter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "appsettings.Development.json", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\appsettings.Development.json", + "RelativeDocumentMoniker": "appsettings.Development.json", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\appsettings.Development.json", + "RelativeToolTip": "appsettings.Development.json", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAsAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2025-10-10T07:56:22.375Z", + "EditorCaption": "" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "ValidationFilter.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Filters\\ValidationFilter.cs", + "RelativeDocumentMoniker": "Filters\\ValidationFilter.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Filters\\ValidationFilter.cs", + "RelativeToolTip": "Filters\\ValidationFilter.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACAAAABQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-10T03:34:07.652Z" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "RegisterRequestValidator.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Validators\\RegisterRequestValidator.cs", + "RelativeDocumentMoniker": "Validators\\RegisterRequestValidator.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Validators\\RegisterRequestValidator.cs", + "RelativeToolTip": "Validators\\RegisterRequestValidator.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAlAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T14:31:43.048Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "Program.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Program.cs", + "RelativeDocumentMoniker": "Program.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Program.cs", + "RelativeToolTip": "Program.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T13:19:43.049Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "RequestModels.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Models\\RequestModels.cs", + "RelativeDocumentMoniker": "Models\\RequestModels.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Models\\RequestModels.cs", + "RelativeToolTip": "Models\\RequestModels.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAywCYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-09T07:39:50.184Z" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "UserEndpoints.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\Endpoints\\UserEndpoints.cs", + "RelativeDocumentMoniker": "Endpoints\\UserEndpoints.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\Endpoints\\UserEndpoints.cs", + "RelativeToolTip": "Endpoints\\UserEndpoints.cs", + "ViewState": "AgIAACEAAAAAAAAAAAAAADUAAAANAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-08T14:40:19.751Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "UserService.cs", + "DocumentMoniker": "C:\\code\\SimpleTodoApiWithPg\\UserService\\UserService.cs", + "RelativeDocumentMoniker": "UserService\\UserService.cs", + "ToolTip": "C:\\code\\SimpleTodoApiWithPg\\UserService\\UserService.cs", + "RelativeToolTip": "UserService\\UserService.cs", + "ViewState": "AgIAAGgAAAAAAAAAAAAAAHcAAAAlAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-08T06:47:44.742Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Data/AppDbContext.cs b/Data/AppDbContext.cs index b7fdd40..f2664ea 100644 --- a/Data/AppDbContext.cs +++ b/Data/AppDbContext.cs @@ -11,5 +11,7 @@ namespace SimpleTodoApiWithPg.Data // 定义一个 DbSet 属性,对应数据库中的 Todos 表 public DbSet Todos { get; set; } = default!; + public DbSet Users { get; set; } = default!; + public DbSet RefreshTokens { get; set; } = default!; } } \ No newline at end of file diff --git a/Endpoints/UserEndpoints.cs b/Endpoints/UserEndpoints.cs new file mode 100644 index 0000000..8d5bc3b --- /dev/null +++ b/Endpoints/UserEndpoints.cs @@ -0,0 +1,119 @@ +using FluentValidation; +using Microsoft.EntityFrameworkCore; +using SimpleTodoApiWithPg.Data; +using SimpleTodoApiWithPg.Models; +using SimpleTodoApiWithPg.UserService; +using System.ComponentModel.DataAnnotations; + + + +namespace SimpleTodoApiWithPg.Endpoints +{ + public static class UserEndpoints + { + + public static void MapUserEndpoints ( this WebApplication app) + { + + var usersApi = app.MapGroup("/users") + .CacheOutput() + .RequireAuthorization() + .WithTags("Users"); + + + usersApi.MapGet("/", async (UserServices userService) => + { + return await userService.GetUsersAsync(); + }).WithTags("获取所有用户"); + + usersApi.MapGet("/{id}", async (Guid id, UserServices userService) => + { + return await userService.GetoneUserAsync(id); + }).WithTags("根据id获取对应的用户信息"); + + usersApi.MapPost("/", async (RegisterRequest request, UserServices userService) => + { + var response = await userService.RegisterAsync(request); + if (!response.Success) + { + return Results.BadRequest(response); + } + return Results.Ok(response); + }).WithTags("用户注册接口") + .AllowAnonymous() + .AddEndpointFilter>() + .ProducesValidationProblem(); + + usersApi.MapPatch("/{id}", async (int id, UpdateUserRequest updateUser, UserServices userService) => + { + return await userService.UpdateUserAsync(id, updateUser); + }).WithTags("用户信息更新接口"); + + + usersApi.MapDelete("/{id}", async (Guid id,UserServices userService) => + { + return await userService.DeleteUserAsync(id); + }).WithTags("删除用户接口"); + + var loginauthApi = app.MapGroup("/api/auth") + .CacheOutput() + .WithTags("登录认证接口!"); + + loginauthApi.MapPost("/", async (UserServices userService, LoginRequest loginRequest) => + { + var response = await userService.LoginAuthAsync(loginRequest); + // 如果登录失败,返回一个带有错误码和错误信息的 BadRequest + if (!response.Success) + { + return Results.BadRequest(response); + } + + return Results.Ok(response); + }).WithTags("登录认证授权接口!"); + + // --- 新增刷新令牌端点 --- + loginauthApi.MapPost("/refresh-token", async ( + /* 这里可以定义一个DTO来接收RefreshToken */ + RefreshTokenRequest refreshToken, + AppDbContext dbContext, + UserServices userServices /* 注入UserServices来复用逻辑 */ + ) => + { + // 通过传入的 refreshToken 查找数据库中对应的记录 + var storedToken = await dbContext.RefreshTokens + .Include(rt => rt.User) // 同时加载关联的用户信息 + .FirstOrDefaultAsync(rt => rt.Token == refreshToken.RefreshToken); + + // 检查令牌是否存在、是否有效 + if (storedToken == null || !storedToken.IsActive) + { + return Results.BadRequest("无效的刷新令牌。"); + } + + // (安全增强) 使旧的刷新令牌失效 + storedToken.Revoked = DateTime.UtcNow; + + // 生成新的访问令牌 + var newAccessTokenExpiration = DateTime.UtcNow.AddMinutes(1); + var newAccessToken = userServices.GenerateJwtToken(storedToken.User, newAccessTokenExpiration); // 需要将 GenerateJwtToken 访问修饰符改为 public 或 internal + + // 生成新的刷新令牌 + var newRefreshToken = userServices.GenerateRefreshToken(); // GenerateRefreshToken 也需要 public/internal + newRefreshToken.UserId = storedToken.UserId; + await dbContext.RefreshTokens.AddAsync(newRefreshToken); + + await dbContext.SaveChangesAsync(); + + return Results.Ok(new AuthResponse + { + AccessToken = newAccessToken, + RefreshToken = newRefreshToken.Token, + AccessTokenExpiration = newAccessTokenExpiration + }); + }) + .WithTags("刷新令牌接口"); + } + + + } +} diff --git a/Filters/ValidationFilter.cs b/Filters/ValidationFilter.cs new file mode 100644 index 0000000..69c9b1c --- /dev/null +++ b/Filters/ValidationFilter.cs @@ -0,0 +1,45 @@ +// Filters/ValidationFilter.cs + +using FluentValidation; + +// 这是一个可复用的通用过滤器,T 是我们要验证的模型类型 +public class ValidationFilter : IEndpointFilter where T : class +{ + private readonly IValidator _validator; + + // 过滤器可以通过构造函数注入它需要的服务,这里我们注入对应的验证器 + public ValidationFilter(IValidator validator) + { + _validator = validator; + } + + public async ValueTask InvokeAsync( + EndpointFilterInvocationContext context, + EndpointFilterDelegate next) + { + // 1. 从端点参数中找到我们需要验证的对象 + // 我们假设它总是第一个参数,如果不是,可以修改这里的逻辑 + var validationTarget = context.Arguments.FirstOrDefault(a => a?.GetType() == typeof(T)) as T; + + // 如果在参数中找不到该类型的对象,直接跳过验证 + if (validationTarget is null) + { + // 或者可以返回一个错误,这取决于你的业务需求 + // return Results.BadRequest("Could not find validation target in request."); + return await next(context); + } + + // 2. 使用从DI容器注入的验证器进行验证 + var validationResult = await _validator.ValidateAsync(validationTarget); + + // 3. 如果验证失败,立即中断请求并返回一个标准的400 ValidationProblem + if (!validationResult.IsValid) + { + // 将 FluentValidation 的错误结果转换为 ASP.NET Core 标准的错误响应 + return Results.ValidationProblem(validationResult.ToDictionary()); + } + + // 4. 如果验证成功,则继续执行后续的过滤器或端点本身 + return await next(context); + } +} \ No newline at end of file diff --git a/HTML/idexe.html b/HTML/idexe.html new file mode 100644 index 0000000..56bdf59 --- /dev/null +++ b/HTML/idexe.html @@ -0,0 +1,581 @@ + + + + + + ASP.NET Core Minimal API CRUD Test + + + + ASP.NET Core Minimal API CRUD 测试 + 确保您的 ASP.NET Core 应用正在运行,并监听以下基准 URL。 + + + + + 待办事项 (Todos) CRUD + + + + 获取所有待办事项 + 获取所有 Todo + + + + + + 根据 ID 获取待办事项 + 待办事项 ID: + + 获取 Todo + + + + + + 创建待办事项 + 标题: + + 已完成: + + 用户ID (关联的用户): + + 创建 Todo + + + + + + 更新待办事项 + 待办事项 ID: + + 新标题: + + 已完成: + + 用户ID (关联的用户): + + 更新 Todo + + + + + + 删除待办事项 + 待办事项 ID: + + 删除 Todo + + + + + + + 用户 (Users) CRUD + + + + 获取所有用户 + 获取所有 User + + + + + + 根据 ID 获取用户 + 用户 ID: + + 获取 User + + + + + + 用户验证 (Check User Credentials) + 用户名: + + 密码哈希: + + 验证用户 + + + + + + 创建用户 + 用户名: + + 邮箱: + + 密码哈希 (例如: plainTextPassword的哈希值): + + 创建 User + + + + + + 更新用户 + 用户 ID: + + 新用户名: + + 新邮箱: + + 新密码哈希: + + 更新 User + + + + + + 删除用户 + 用户 ID: + + 删除 User + + + + + + + + \ No newline at end of file diff --git a/Migrations/20250922140100_InitialCreate.Designer.cs b/Migrations/20250922140100_InitialCreate.Designer.cs deleted file mode 100644 index 9346171..0000000 --- a/Migrations/20250922140100_InitialCreate.Designer.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using SimpleTodoApiWithPg.Data; - -#nullable disable - -namespace SimpleTodoApiWithPg.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20250922140100_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.9") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("SimpleTodoApiWithPg.Models.Todo", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("IsCompleted") - .HasColumnType("boolean"); - - b.Property("Title") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Todos"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Migrations/20250922140100_InitialCreate.cs b/Migrations/20250922140100_InitialCreate.cs deleted file mode 100644 index 1fd09ec..0000000 --- a/Migrations/20250922140100_InitialCreate.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace SimpleTodoApiWithPg.Migrations -{ - /// - public partial class InitialCreate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Todos", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Title = table.Column(type: "text", nullable: false), - IsCompleted = table.Column(type: "boolean", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Todos", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Todos"); - } - } -} diff --git a/Migrations/20251009024853_InitialCreateWithGuidIds.Designer.cs b/Migrations/20251009024853_InitialCreateWithGuidIds.Designer.cs new file mode 100644 index 0000000..3c331e2 --- /dev/null +++ b/Migrations/20251009024853_InitialCreateWithGuidIds.Designer.cs @@ -0,0 +1,117 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using SimpleTodoApiWithPg.Data; + +#nullable disable + +namespace SimpleTodoApiWithPg.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20251009024853_InitialCreateWithGuidIds")] + partial class InitialCreateWithGuidIds + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("Revoked") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.Todo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Todos"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.HasOne("SimpleTodoApiWithPg.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20251009024853_InitialCreateWithGuidIds.cs b/Migrations/20251009024853_InitialCreateWithGuidIds.cs new file mode 100644 index 0000000..a49acda --- /dev/null +++ b/Migrations/20251009024853_InitialCreateWithGuidIds.cs @@ -0,0 +1,83 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace SimpleTodoApiWithPg.Migrations +{ + /// + public partial class InitialCreateWithGuidIds : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Todos", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Title = table.Column(type: "text", nullable: false), + IsCompleted = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Todos", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Username = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + Email = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + PasswordHash = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RefreshTokens", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Token = table.Column(type: "text", nullable: false), + Expires = table.Column(type: "timestamp with time zone", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Revoked = table.Column(type: "timestamp with time zone", nullable: true), + UserId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RefreshTokens", x => x.Id); + table.ForeignKey( + name: "FK_RefreshTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RefreshTokens_UserId", + table: "RefreshTokens", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RefreshTokens"); + + migrationBuilder.DropTable( + name: "Todos"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/Migrations/20251009035553_Initial3.Designer.cs b/Migrations/20251009035553_Initial3.Designer.cs new file mode 100644 index 0000000..c015fbf --- /dev/null +++ b/Migrations/20251009035553_Initial3.Designer.cs @@ -0,0 +1,117 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using SimpleTodoApiWithPg.Data; + +#nullable disable + +namespace SimpleTodoApiWithPg.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20251009035553_Initial3")] + partial class Initial3 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("Revoked") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.Todo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Todos"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.HasOne("SimpleTodoApiWithPg.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20251009035553_Initial3.cs b/Migrations/20251009035553_Initial3.cs new file mode 100644 index 0000000..98f5ed5 --- /dev/null +++ b/Migrations/20251009035553_Initial3.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace SimpleTodoApiWithPg.Migrations +{ + /// + public partial class Initial3 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + } + } +} diff --git a/Migrations/AppDbContextModelSnapshot.cs b/Migrations/AppDbContextModelSnapshot.cs index a6466c7..cb3b299 100644 --- a/Migrations/AppDbContextModelSnapshot.cs +++ b/Migrations/AppDbContextModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; @@ -21,13 +22,40 @@ namespace SimpleTodoApiWithPg.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("Revoked") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + modelBuilder.Entity("SimpleTodoApiWithPg.Models.Todo", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + .HasColumnType("uuid"); b.Property("IsCompleted") .HasColumnType("boolean"); @@ -40,6 +68,46 @@ namespace SimpleTodoApiWithPg.Migrations b.ToTable("Todos"); }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("SimpleTodoApiWithPg.Models.RefreshToken", b => + { + b.HasOne("SimpleTodoApiWithPg.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); #pragma warning restore 612, 618 } } diff --git a/Models/RequestModels.cs b/Models/RequestModels.cs new file mode 100644 index 0000000..f6dd03b --- /dev/null +++ b/Models/RequestModels.cs @@ -0,0 +1,44 @@ +using System.ComponentModel.DataAnnotations; + +namespace SimpleTodoApiWithPg.Models +{ + public class UpdateUserRequest + { + // 设为可空类型,表示这些字段可以选择性更新 + [MaxLength(50)] + public string? Username { get; set; } + + [MaxLength(100)] + [EmailAddress] // 仍然应用验证 + public string? Email { get; set; } + + // 密码更新处理:提供一个用于接收新明文密码的字段 + // 注意:不应该有 PasswordHash 字段! + [MaxLength(50)] + public string? NewPassword { get; set; } + } + + public class LoginRequest + { + [Required(ErrorMessage = "用户名不能为空")] + [MaxLength(50, ErrorMessage = "用户名长度不能超过50个字符")] + public string Username { get; set; } = null!; // null! 表示编译器知道它不会是null + + [Required(ErrorMessage = "密码不能为空")] + [MaxLength(50,ErrorMessage = "密码长度不能超过50个字符!")] + // 可以添加 MinLength/MaxLength 验证 + public string Password { get; set; } = null!; // 明文密码 + } + + public class RegisterRequest() + { + public required string Username { get; set; } + + public required string Email { get; set; } + } + + + public record RefreshTokenRequest(string RefreshToken); + + +} diff --git a/Models/ResponseModels.cs b/Models/ResponseModels.cs new file mode 100644 index 0000000..70fcd72 --- /dev/null +++ b/Models/ResponseModels.cs @@ -0,0 +1,50 @@ +namespace SimpleTodoApiWithPg.Models +{ + // 这是一个泛型记录 (generic record),用于包装所有 API 的返回数据 + public record ApiResponse( + bool Success, + string Message, + T? Data, + int Code = 200 + ); + + // 提供一个静态类,方便快速创建标准响应 + public static class ApiResponse + { + public static ApiResponse Ok(T data, string message = "操作成功") + { + return new ApiResponse(true, message, data); + } + + // **** 关键修改在这里:让 Fail 方法也变为泛型 **** + // 它接受一个类型参数 T,并返回 ApiResponse + // default(T) 对于引用类型(如 AuthResponse)会返回 null + public static ApiResponse Fail(string message, int code = 400) + { + return new ApiResponse(false, message, default(T), code); + } + + // 您可以保留一个非泛型版本的 Fail 方便在某些无需特定 Data 类型的地方使用 + // 但在需要特定返回类型的地方,请使用泛型版本 + public static ApiResponse Fail(string message, int code = 400) + { + return new ApiResponse(false, message, null, code); + } + } + + // 更新登录成功后返回的 DTO + public class AuthResponse + { + public string AccessToken { get; set; } = null!; + public string RefreshToken { get; set; } = null!; + public DateTime AccessTokenExpiration { get; set; } + } + + public class RegisterResponse + { + public string? Username { get; set; } + public string? Email { get; set; } + public string? Password { get; set; } + public Guid UserId { get; set; } + } +} diff --git a/Models/Todo.cs b/Models/Todo.cs index 944a1ba..7853b3f 100644 --- a/Models/Todo.cs +++ b/Models/Todo.cs @@ -2,7 +2,7 @@ namespace SimpleTodoApiWithPg.Models { public class Todo { - public int Id { get; set; } + public Guid Id { get; set; } = Guid.CreateVersion7(); public string Title { get; set; } = string.Empty; // 待办事项标题 public bool IsCompleted { get; set; } // 是否已完成 } diff --git a/Models/User.cs b/Models/User.cs new file mode 100644 index 0000000..6f03bb5 --- /dev/null +++ b/Models/User.cs @@ -0,0 +1,56 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace SimpleTodoApiWithPg.Models +{ + public class User + { + [Key] // 标识 Id 为主键 + //[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 数据库自动生成(例如 PostgreSQL 的 SERIAL 类型) + public Guid Id { get; set; } = Guid.CreateVersion7(); + + [Required] // 标识为非空字段 + [MaxLength(50)] // 限制字符串最大长度 + public string Username { get; set; } = null!; + + [Required(ErrorMessage = "邮箱是必填项。")] + [EmailAddress(ErrorMessage = "邮箱格式不正确。")] // + [StringLength(50, MinimumLength = 5, ErrorMessage = "邮箱长度必须在 {2} 到 {1} 个字符之间。")] // + public string Email { get; set; } = null!; + + // 密码通常会存储哈希值,而不是明文 + [Required] + [MaxLength(100)] + public string PasswordHash { get; set; } = null!; + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + // 如果需要,可以添加导航属性,例如,一个用户可以有多个 Todo + // public ICollection Todos { get; set; } = new List(); + } + + public class RefreshToken + { + [Key] + public Guid Id { get; set; } = Guid.CreateVersion7(); + + [Required] + public string Token { get; set; } = null!; // 存储 refresh token 的字符串 + + [Required] + public DateTime Expires { get; set; } // 过期时间 + + public bool IsExpired => DateTime.UtcNow >= Expires; // 计算属性,判断是否已过期 + + public DateTime Created { get; set; } // 创建时间 + + public DateTime? Revoked { get; set; } // 撤销时间 (可空) + + public bool IsActive => Revoked == null && !IsExpired; // 计算属性,判断是否有效 + + // 外键关联到 User 表 + public Guid UserId { get; set; } + [ForeignKey("UserId")] + public User User { get; set; } = null!; + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index e6f065a..6282cdd 100644 --- a/Program.cs +++ b/Program.cs @@ -1,11 +1,119 @@ +using FluentValidation; // <--- 关键!这是现在唯一需要的 using +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; using SimpleTodoApiWithPg.Data; -using SimpleTodoApiWithPg.Models; -using Microsoft.AspNetCore.Http.HttpResults; -using Microsoft.AspNetCore.Mvc; +using SimpleTodoApiWithPg.Endpoints; +using SimpleTodoApiWithPg.UserService; +using System.Security.Cryptography.X509Certificates; var builder = WebApplication.CreateBuilder(args); +builder.Logging.AddConsole(); //日志服务 +builder.Services.AddScoped(); //注册用户服务 +// 1. 添加OpenAPI/Swagger生成器服务到容器 +builder.Services.AddEndpointsApiExplorer(); // 这个服务负责发现和描述API端点 +builder.Services.AddSwaggerGen(); // 这个服务负责根据端点描述生成OpenAPI JSON文档 + +// 1. 扫描并注册你项目里的所有验证器 +builder.Services.AddValidatorsFromAssemblyContaining(includeInternalTypes: true); +// 注册所有 validator(按包含类型或指定程序集) + + + + + +var certPath = builder.Configuration["Jwt:CertificatePath"]; +var certPassword = builder.Configuration["Jwt:CertificatePassword"]; +var certificate = X509CertificateLoader.LoadPkcs12FromFile(certPath!, certPassword); + +builder.Services.AddAuthentication(options => +{ + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}) +.AddJwtBearer(options => +{ + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = builder.Configuration["Jwt:Issuer"], + ValidAudience = builder.Configuration["Jwt:Audience"], + // 使用证书的公钥进行验证 + IssuerSigningKey = new ECDsaSecurityKey(certificate.GetECDsaPublicKey()!), + // 确保指定正确的签名算法 + // 对于 ECDSA P-256,应该是 "ES256" + ValidAlgorithms = [SecurityAlgorithms.EcdsaSha256] // 可选,增加安全性 + }; + + // 新增:配置认证事件 + options.Events = new JwtBearerEvents + { + // 当认证失败,需要向客户端发起质询(Challenge)时触发 + OnChallenge = context => + { + // 阻止默认的响应行为,我们将来完全自定义响应 + context.HandleResponse(); + + context.Response.StatusCode = 401; + context.Response.ContentType = "application/json"; + + // 默认的错误信息 + var message = "身份验证失败,请检查您的 Token。"; + + // 检查具体的失败原因,如果是 Token 过期,就给出更明确的提示 + // AuthenticateFailure 属性包含了认证失败时的异常信息 + if (context.AuthenticateFailure is SecurityTokenExpiredException) + { + message = "您的 Token 已过期,请重新登录或刷新 Token。"; + } + + // 您也可以在这里记录日志,方便排查问题 + // logger.LogError(context.AuthenticateFailure, "An authentication error occurred."); + + var response = new + { + success = false, + message = message + }; + + // 将自定义的响应内容写入 Response Body + return context.Response.WriteAsJsonAsync(response); + } + }; + +}); + +builder.Services.AddAuthorization(); + + +// === 配置 CORS === +// 定义一个 CORS 策略名称 +var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; + +// 添加 CORS 服务到依赖注入容器 +builder.Services.AddCors(options => +{ + options.AddPolicy(name: MyAllowSpecificOrigins, + policy => + { + // 允许所有来源进行访问。 + // 注意:这在生产环境中是极度不安全的,仅用于本地开发和测试。 + // 在生产环境中,您应该明确指定允许的源: + // policy.WithOrigins("http://localhost:8080", "https://yourfrontend.com") + // 或者,如果您直接打开HTML文件,其来源是'null',您可以明确允许它: + // policy.WithOrigins("null") // 在此测试场景下,这是一个选项,但AllowAnyOrigin更通用 + + policy.AllowAnyOrigin() // 允许任何来源的请求 + .AllowAnyHeader() // 允许任何请求头 + .AllowAnyMethod(); // 允许任何 HTTP 方法 (GET, POST, PUT, DELETE) + }); +}); + + // === 配置 EF Core 连接 PostgreSQL === // 从配置中获取连接字符串 var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); @@ -14,8 +122,19 @@ var connectionString = builder.Configuration.GetConnectionString("DefaultConnect builder.Services.AddDbContext(options => options.UseNpgsql(connectionString)); // 使用 Npgsql 作为 PostgreSQL 提供者 + var app = builder.Build(); +// 2. 在管道中启用中间件 (通常只在开发环境中启用) +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); // 这个中间件负责提供生成的 swagger.json 文件 + app.UseSwaggerUI(); // 这个中间件负责提供交互式的Swagger UI界面 +} +// === CORS 中间件必须放在其他中间件之前 (例如路由,授权,认证等) === +// 启用 CORS +app.UseCors(MyAllowSpecificOrigins); + // === 应用数据库迁移 (仅在开发环境中推荐) === // 在应用启动时自动应用所有挂起的数据库迁移 using (var scope = app.Services.CreateScope()) @@ -26,68 +145,144 @@ using (var scope = app.Services.CreateScope()) // === 定义 API 端点 (Endpoints) === -// GET /todos - 获取所有待办事项 -app.MapGet("/todos", async (AppDbContext dbContext) => -{ - var todos = await dbContext.Todos.ToListAsync(); - return TypedResults.Ok(todos); -}); -// GET /todos/{id} - 根据 ID 获取单个待办事项 -app.MapGet("/todos/{id}", async (int id, AppDbContext dbContext) => -{ - var todo = await dbContext.Todos.FindAsync(id); - return todo is not null - ? TypedResults.Ok(todo) - : Results.NotFound($"待办事项 (ID: {id}) 不存在。"); -}); +// GET / - 根路径,返回一个简单的消息 +app.MapGet("/", () => "Hello World!"); +app.MapUserEndpoints(); +app.UseAuthentication(); +app.UseAuthorization(); -// POST /todos - 新增一个待办事项 -app.MapPost("/todos", async (Todo todo, AppDbContext dbContext) => -{ - // EF Core 会自动处理 ID 的生成(如果是自增主键) - dbContext.Todos.Add(todo); - await dbContext.SaveChangesAsync(); // 保存更改到数据库 +//app.MapPatch("/users", async (User user, UserService userService) => +//{ +// return await userService.PatchUserAsync(user); +//}); +//// GET /todos - 获取所有待办事项 +//app.MapGet("/todos", async (AppDbContext dbContext) => +//{ +// var todos = await dbContext.Todos.ToListAsync(); +// return TypedResults.Ok(todos); +//}); - // 回传 201 Created 并提供新资源的位置 - return Results.Created($"/todos/{todo.Id}", todo); -}); +//// GET /users - 获取所有用户 +//app.MapGet("/users", async (AppDbContext dbContext) => +//{ +// var users = await dbContext.Users.ToListAsync(); +// return TypedResults.Ok(users); +//}); -// PUT /todos/{id} - 更新指定的待办事项 -app.MapPut("/todos/{id}", async (int id, Todo inputTodo, AppDbContext dbContext) => -{ - // 查找现有待办事项 - var existingTodo = await dbContext.Todos.FindAsync(id); +//// GET /todos/{id} - 根据 ID 获取单个待办事项 +//app.MapGet("/todos/{id}", async (int id, AppDbContext dbContext) => +//{ +// var todo = await dbContext.Todos.FindAsync(id); +// return todo is not null +// ? TypedResults.Ok(todo) +// : Results.NotFound($"待办事项 (ID: {id}) 不存在。"); +//}); - if (existingTodo is null) - { - return Results.NotFound($"待办事项 (ID: {id}) 不存在。"); - } +// GET /users/{id} - 根据 ID 获取单个用户 +//app.MapGet("/users/{id}", async (int id, AppDbContext dbContext) => +//{ +// var user = await dbContext.Users.FindAsync(id); +// return user is not null +// ? TypedResults.Ok(user) +// : Results.NotFound($"用户 (ID: {id}) 不存在。"); +//}); - // 更新属性 - existingTodo.Title = inputTodo.Title; - existingTodo.IsCompleted = inputTodo.IsCompleted; +//// POST /todos - 新增一个待办事项 +//app.MapPost("/todos", async (Todo todo, AppDbContext dbContext) => +//{ +// // EF Core 会自动处理 ID 的生成(如果是自增主键) +// dbContext.Todos.Add(todo); +// await dbContext.SaveChangesAsync(); // 保存更改到数据库 - await dbContext.SaveChangesAsync(); // 保存更改到数据库 +// // 回传 201 Created 并提供新资源的位置 +// return Results.Created($"/todos/{todo.Id}", todo); +//}); - return Results.NoContent(); // 回传 204 No Content 表示成功但无内容回传 -}); -// DELETE /todos/{id} - 删除指定的待办事项 -app.MapDelete("/todos/{id}", async (int id, AppDbContext dbContext) => -{ - var todoToDelete = await dbContext.Todos.FindAsync(id); +//// POST /users - 新增一个用户 +//app.MapPost("/users", async (User user, AppDbContext dbContext) => +//{ +// user.PasswordHash = RandomNumberGenerator.GetString("0123456789",22); +// Console.WriteLine(user.PasswordHash); +// user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(user.PasswordHash,10,true); // 哈希密码 +// // EF Core 会自动处理 ID 的生成(如果是自增主键) +// dbContext.Users.Add(user); +// await dbContext.SaveChangesAsync(); // 保存更改到数据库 - if (todoToDelete is null) - { - return Results.NotFound($"待办事项 (ID: {id}) 不存在。"); - } +// // 回传 201 Created 并提供新资源的位置 +// return Results.Created($"/users/{user.Id}", user); +//}); - dbContext.Todos.Remove(todoToDelete); - await dbContext.SaveChangesAsync(); // 保存更改到数据库 - - return TypedResults.Ok($"待办事项 (ID: {id}) 已成功删除。"); -}); +//// PUT /todos/{id} - 更新指定的待办事项 +//app.MapPut("/todos/{id}", async (int id, Todo inputTodo, AppDbContext dbContext) => +//{ +// // 查找现有待办事项 +// var existingTodo = await dbContext.Todos.FindAsync(id); + +// if (existingTodo is null) +// { +// return Results.NotFound($"待办事项 (ID: {id}) 不存在。"); +// } + +// // 更新属性 +// existingTodo.Title = inputTodo.Title; +// existingTodo.IsCompleted = inputTodo.IsCompleted; + +// await dbContext.SaveChangesAsync(); // 保存更改到数据库 + +// return Results.NoContent(); // 回传 204 No Content 表示成功但无内容回传 +//}); + + +//// PUT /users/{id} - 更新指定的用户 +//app.MapPut("/users/{id}", async (int id, User inputUser, AppDbContext dbContext) => +//{ +// // 查找现有用户 +// var existingUser = await dbContext.Users.FindAsync(id); +// if (existingUser is null) +// { +// return Results.NotFound($"用户 (ID: {id}) 不存在。"); +// } + +// // 更新属性 +// existingUser.Username = inputUser.Username; +// existingUser.Email = inputUser.Email; +// existingUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(inputUser.PasswordHash,10,true); // 哈希密码 + +// await dbContext.SaveChangesAsync(); + +// return Results.NoContent(); +//}); + +//// DELETE /todos/{id} - 删除指定的待办事项 +//app.MapDelete("/todos/{id}", async (int id, AppDbContext dbContext) => +//{ +// var todoToDelete = await dbContext.Todos.FindAsync(id); + +// if (todoToDelete is null) +// { +// return Results.NotFound($"待办事项 (ID: {id}) 不存在。"); +// } + +// dbContext.Todos.Remove(todoToDelete); +// await dbContext.SaveChangesAsync(); // 保存更改到数据库 + +// return TypedResults.Ok($"待办事项 (ID: {id}) 已成功删除。"); +//}); + +//// DELETE /users/{id} - 删除指定的用户 +//app.MapDelete("/users/{id}", async (int id, AppDbContext dbContext) => +//{ +// var userToDelete = await dbContext.Users.FindAsync(id); + +// if (userToDelete is null) return Results.NotFound("用户不存在"); +// { +// dbContext.Users.Remove(userToDelete); +// await dbContext.SaveChangesAsync(); // 保存更改到数据库 +// return TypedResults.Ok("用户已成功删除"); +// } +//}); // 运行应用程式 app.Run(); diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json index e75cd3f..77ed671 100644 --- a/Properties/launchSettings.json +++ b/Properties/launchSettings.json @@ -5,7 +5,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5071", + "applicationUrl": "http://localhost:5562", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -14,7 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7256;http://localhost:5071", + "applicationUrl": "https://localhost:7256;http://localhost:5562", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/SimpleTodoApiWithPg.csproj b/SimpleTodoApiWithPg.csproj index 9d41342..ac9dd58 100644 --- a/SimpleTodoApiWithPg.csproj +++ b/SimpleTodoApiWithPg.csproj @@ -7,11 +7,22 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive all + + + + + + + PreserveNewest + diff --git a/SimpleTodoApiWithPg.csproj.user b/SimpleTodoApiWithPg.csproj.user new file mode 100644 index 0000000..c404400 --- /dev/null +++ b/SimpleTodoApiWithPg.csproj.user @@ -0,0 +1,9 @@ + + + + https + + + ProjectDebugger + + \ No newline at end of file diff --git a/SimpleTodoApiWithPg.http b/SimpleTodoApiWithPg.http new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/SimpleTodoApiWithPg.http @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UserService/UserService.cs b/UserService/UserService.cs new file mode 100644 index 0000000..ca10122 --- /dev/null +++ b/UserService/UserService.cs @@ -0,0 +1,207 @@ +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using SimpleTodoApiWithPg.Data; +using SimpleTodoApiWithPg.Models; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; + +namespace SimpleTodoApiWithPg.UserService +{ + // Services/UserService.cs + public class UserServices + { + private readonly AppDbContext _dbContext; + private readonly ILogger _logger; // 在服务构造函数中注入 + private readonly IConfiguration _configuration; + + public UserServices(AppDbContext dbContext, IConfiguration configuration, ILogger logger) + { + _dbContext = dbContext; + _logger = logger; + _configuration = configuration; + } + + + //前更新用户接口,暂时未使用 + public async Task, BadRequest>> PatchUserAsync(User user) + { + _logger.LogInformation("Attempting to patch user in UserService: {Username}", user.Username); + + var existingUser = await _dbContext.Users.FirstOrDefaultAsync(u => u.Username == user.Username); + if (existingUser == null) + { + _logger.LogWarning("User '{Username}' not found during patch.", user.Username); + return TypedResults.BadRequest("用户名不存在,登录失败!。"); + } + + if (!BCrypt.Net.BCrypt.Verify(user.PasswordHash, existingUser.PasswordHash, true)) + { + _logger.LogWarning("Incorrect password for user '{Username}' during patch.", user.Username); + return TypedResults.BadRequest("密码错误,请重新输入。"); + } + + // 假设这里执行更新逻辑 + // existingUser.SomeProperty = user.SomeProperty; + // await _dbContext.SaveChangesAsync(); + + _logger.LogInformation("User '{Username}' patched successfully.", user.Username); + return TypedResults.Ok(existingUser); + } + + //获取所有用户接口 + public async Task>, BadRequest>> GetUsersAsync() + { + var users = await _dbContext.Users.ToListAsync(); + return TypedResults.Ok(users); + } + + //根据id获取对应用户接口 + public async Task, NotFound>> GetoneUserAsync(Guid id) + { + var user = await _dbContext.Users.FindAsync(id); + if (user == null) { return TypedResults.NotFound($"要查询的id:{id}不存在"); } + return TypedResults.Ok(user); + } + + //用户注册接口 + public async Task> RegisterAsync(RegisterRequest request) + { + var exuser = await _dbContext.Users.AnyAsync(u => u.Username == request.Username); + if (exuser) { return ApiResponse.Fail($"用户名:{request.Username}已存在,注册失败!", 400); }; + //if (request.Username.Length <5 || request.Email.Length < 5 ) { return ApiResponse.Fail($"用户名或邮箱不符合规范,注册失败!", 400);}; + + var password = RandomNumberGenerator.GetString("0123456789",15); + var user = new User(); + user.Username = request.Username; + user.Email = request.Email; + user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(password, 10, true); + _dbContext.Users.Add(user); + await _dbContext.SaveChangesAsync(); + return ApiResponse.Ok(new RegisterResponse + { + Username = user.Username, + Email = user.Email, + Password = password, + UserId = user.Id + }); + } + + //更新用户接口 + public async Task, NotFound>> UpdateUserAsync(int id, UpdateUserRequest updateUser) + { + var existingUser = await _dbContext.Users.FindAsync(id); + if (existingUser == null) { return TypedResults.NotFound($"要更新的用户id:{id}不存在!"); }; + + if (updateUser.Username != null) + { + existingUser.Username = updateUser.Username; + } + if (!string.IsNullOrEmpty(updateUser.NewPassword)) + { + existingUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(updateUser.NewPassword,10,true); + } + if (updateUser.Email != null) + { + existingUser.Email = updateUser.Email; + } + + await _dbContext.SaveChangesAsync(); + + return TypedResults.Ok(existingUser); + } + + //删除指定用户接口 + public async Task, NotFound>> DeleteUserAsync(Guid id) + { + var existingUser = await _dbContext.Users.FindAsync(id); + if (existingUser == null) + { + return TypedResults.NotFound($"指定要删除的用户:{id}不存在!"); + } + _dbContext.Users.Remove(existingUser); + await _dbContext.SaveChangesAsync(); + return TypedResults.Ok($"指定的用户:{existingUser.Username}删除成功!"); + } + + //登录认证接口 + public async Task> LoginAuthAsync(LoginRequest loginRequest) + { + var existingUser = await _dbContext.Users.FirstOrDefaultAsync(u => u.Username == loginRequest.Username); + if (existingUser == null || !BCrypt.Net.BCrypt.Verify(loginRequest.Password, existingUser.PasswordHash, true)) + { + _logger.LogError("用户登录失败!{request}"," ---用户名: "+loginRequest.Username+" ---密码: "+loginRequest.Password); + return ApiResponse.Fail("用户名或密码错误!",400); + } + // 1. 生成 JWT (Access Token) + var accessTokenExpiration = DateTime.UtcNow.AddMinutes(1); // 访问令牌有效期15分钟 + var accessToken = GenerateJwtToken(existingUser, accessTokenExpiration); + + // 2. 生成刷新令牌 + var refreshToken = GenerateRefreshToken(); + refreshToken.UserId = existingUser.Id; + await _dbContext.RefreshTokens.AddAsync(refreshToken); + + // (可选但推荐) 清理该用户旧的、无效的刷新令牌 + var oldRefreshTokens = await _dbContext.RefreshTokens + .Where(rt => rt.UserId == existingUser.Id && (rt.Revoked != null || rt.Expires <= DateTime.UtcNow)) + .ToListAsync(); + _dbContext.RefreshTokens.RemoveRange(oldRefreshTokens); + + await _dbContext.SaveChangesAsync(); + + // 3. 返回令牌对 + return ApiResponse.Ok(new AuthResponse + { + AccessToken = accessToken, + RefreshToken = refreshToken.Token, + AccessTokenExpiration = accessTokenExpiration + }); + } + + + //创建令牌接口 + public string GenerateJwtToken(User user, DateTime expires) + { + // 加载证书以获取私钥进行签名 + var certPath = _configuration["Jwt:CertificatePath"]!; + var certPassword = _configuration["Jwt:CertificatePassword"]!; + var certificate = X509CertificateLoader.LoadPkcs12FromFile(certPath, certPassword,X509KeyStorageFlags.EphemeralKeySet); + + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Sub, user.Username), + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), + new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()) + }; + + var token = new JwtSecurityToken( + issuer: _configuration["Jwt:Issuer"], + audience: _configuration["Jwt:Audience"], + claims: claims, + expires: expires, + // 使用证书的私钥通过 ECDSA-SHA256 算法进行签名 + signingCredentials: new SigningCredentials(new ECDsaSecurityKey(certificate.GetECDsaPrivateKey()!), SecurityAlgorithms.EcdsaSha256) + ); + + return new JwtSecurityTokenHandler().WriteToken(token); + } + + //创建刷新令牌接口 + public RefreshToken GenerateRefreshToken() + { + var randomNumber = new byte[64]; + using var rng = RandomNumberGenerator.Create(); + rng.GetBytes(randomNumber); + + return new RefreshToken + { + Token = Convert.ToBase64String(randomNumber), + Expires = DateTime.UtcNow.AddDays(1), // 刷新令牌有效期7天 + Created = DateTime.UtcNow + }; + } + } +} diff --git a/Validators/RegisterRequestValidator.cs b/Validators/RegisterRequestValidator.cs new file mode 100644 index 0000000..793a184 --- /dev/null +++ b/Validators/RegisterRequestValidator.cs @@ -0,0 +1,18 @@ +using FluentValidation; +using SimpleTodoApiWithPg.Models; + + +public class RegisterRequestValidator : AbstractValidator +{ + public RegisterRequestValidator() + { + RuleFor(x => x.Username) + .NotEmpty().WithMessage("用户名是必填的。") + .Length(3, 20).WithMessage("用户名长度必须在 {MinLength} 到 {MaxLength} 之间。"); + + RuleFor(x => x.Email) + .NotEmpty().WithMessage("邮箱是必填的。") + .EmailAddress().WithMessage("请输入有效的邮箱地址。"); + + } +} diff --git a/appsettings.Development.json b/appsettings.Development.json index 5661b31..5d50cd3 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -7,6 +7,6 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "DefaultConnection": "Host=localhost;Port=5555;Database=aspdb;Username=postgres;Password=123456" + "DefaultConnection": "Host=localhost;Port=5432;Database=aspnetcoredb;Username=aspnetcoredb;Password=2rRN26JTrFp4edGF" } } \ No newline at end of file diff --git a/appsettings.json b/appsettings.json index 10f68b8..50c7e1c 100644 --- a/appsettings.json +++ b/appsettings.json @@ -5,5 +5,11 @@ "Microsoft.AspNetCore": "Warning" } }, + "jwt": { + "Issuer": "baidu.com", + "Audience": "baidu.com", + "CertificatePath": "ecc-certificate.pfx", // 证书文件名 (相对于应用根目录) + "CertificatePassword": "UpRTXjaHdJaPCAjgjTTt" // 您在生成证书时设置的密码 + }, "AllowedHosts": "*" } diff --git a/bin/Debug/net9.0/BCrypt.Net-Next.dll b/bin/Debug/net9.0/BCrypt.Net-Next.dll new file mode 100644 index 0000000..42d9082 Binary files /dev/null and b/bin/Debug/net9.0/BCrypt.Net-Next.dll differ diff --git a/bin/Debug/net9.0/FluentValidation.DependencyInjectionExtensions.dll b/bin/Debug/net9.0/FluentValidation.DependencyInjectionExtensions.dll new file mode 100644 index 0000000..ffa2dc1 Binary files /dev/null and b/bin/Debug/net9.0/FluentValidation.DependencyInjectionExtensions.dll differ diff --git a/bin/Debug/net9.0/FluentValidation.dll b/bin/Debug/net9.0/FluentValidation.dll new file mode 100644 index 0000000..bfd0db6 Binary files /dev/null and b/bin/Debug/net9.0/FluentValidation.dll differ diff --git a/bin/Debug/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll b/bin/Debug/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll new file mode 100644 index 0000000..86f2e38 Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll new file mode 100644 index 0000000..f85ae59 Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll new file mode 100644 index 0000000..4c4d3ab Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll new file mode 100644 index 0000000..170078a Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll new file mode 100644 index 0000000..6c736d2 Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.dll new file mode 100644 index 0000000..9f30508 Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.Protocols.dll differ diff --git a/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll b/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll new file mode 100644 index 0000000..009ce65 Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll differ diff --git a/bin/Debug/net9.0/Microsoft.OpenApi.dll b/bin/Debug/net9.0/Microsoft.OpenApi.dll new file mode 100644 index 0000000..6fd0d6d Binary files /dev/null and b/bin/Debug/net9.0/Microsoft.OpenApi.dll differ diff --git a/bin/Debug/net9.0/SimpleTodoApiWithPg.deps.json b/bin/Debug/net9.0/SimpleTodoApiWithPg.deps.json index 35617df..7f0a6da 100644 --- a/bin/Debug/net9.0/SimpleTodoApiWithPg.deps.json +++ b/bin/Debug/net9.0/SimpleTodoApiWithPg.deps.json @@ -8,13 +8,46 @@ ".NETCoreApp,Version=v9.0": { "SimpleTodoApiWithPg/1.0.0": { "dependencies": { + "BCrypt.Net-Next": "4.0.3", + "FluentValidation.DependencyInjectionExtensions": "12.0.0", + "Microsoft.AspNetCore.Authentication.JwtBearer": "9.0.9", "Microsoft.EntityFrameworkCore.Design": "9.0.9", - "Npgsql.EntityFrameworkCore.PostgreSQL": "9.0.4" + "Npgsql.EntityFrameworkCore.PostgreSQL": "9.0.4", + "Swashbuckle.AspNetCore": "9.0.6", + "System.IdentityModel.Tokens.Jwt": "8.14.0" }, "runtime": { "SimpleTodoApiWithPg.dll": {} } }, + "BCrypt.Net-Next/4.0.3": { + "runtime": { + "lib/net6.0/BCrypt.Net-Next.dll": { + "assemblyVersion": "4.0.3.0", + "fileVersion": "4.0.3.0" + } + } + }, + "FluentValidation/12.0.0": { + "runtime": { + "lib/net8.0/FluentValidation.dll": { + "assemblyVersion": "12.0.0.0", + "fileVersion": "12.0.0.0" + } + } + }, + "FluentValidation.DependencyInjectionExtensions/12.0.0": { + "dependencies": { + "FluentValidation": "12.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.9" + }, + "runtime": { + "lib/net8.0/FluentValidation.DependencyInjectionExtensions.dll": { + "assemblyVersion": "12.0.0.0", + "fileVersion": "12.0.0.0" + } + } + }, "Humanizer.Core/2.14.1": { "runtime": { "lib/net6.0/Humanizer.dll": { @@ -23,6 +56,17 @@ } } }, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.9": { + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + }, + "runtime": { + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll": { + "assemblyVersion": "9.0.9.0", + "fileVersion": "9.0.925.42003" + } + } + }, "Microsoft.Bcl.AsyncInterfaces/7.0.0": { "runtime": { "lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": { @@ -379,6 +423,7 @@ } } }, + "Microsoft.Extensions.ApiDescription.Server/9.0.0": {}, "Microsoft.Extensions.Caching.Abstractions/9.0.9": { "dependencies": { "Microsoft.Extensions.Primitives": "9.0.9" @@ -487,6 +532,79 @@ } } }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.dll": { + "assemblyVersion": "8.0.1.0", + "fileVersion": "8.0.1.50722" + } + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": { + "assemblyVersion": "8.0.1.0", + "fileVersion": "8.0.1.50722" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "9.0.9", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, + "Microsoft.OpenApi/1.6.25": { + "runtime": { + "lib/netstandard2.0/Microsoft.OpenApi.dll": { + "assemblyVersion": "1.6.25.0", + "fileVersion": "1.6.25.0" + } + } + }, "Mono.TextTemplating/3.0.0": { "dependencies": { "System.CodeDom": "6.0.0" @@ -522,6 +640,44 @@ } } }, + "Swashbuckle.AspNetCore/9.0.6": { + "dependencies": { + "Microsoft.Extensions.ApiDescription.Server": "9.0.0", + "Swashbuckle.AspNetCore.Swagger": "9.0.6", + "Swashbuckle.AspNetCore.SwaggerGen": "9.0.6", + "Swashbuckle.AspNetCore.SwaggerUI": "9.0.6" + } + }, + "Swashbuckle.AspNetCore.Swagger/9.0.6": { + "dependencies": { + "Microsoft.OpenApi": "1.6.25" + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll": { + "assemblyVersion": "9.0.6.0", + "fileVersion": "9.0.6.1840" + } + } + }, + "Swashbuckle.AspNetCore.SwaggerGen/9.0.6": { + "dependencies": { + "Swashbuckle.AspNetCore.Swagger": "9.0.6" + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll": { + "assemblyVersion": "9.0.6.0", + "fileVersion": "9.0.6.1840" + } + } + }, + "Swashbuckle.AspNetCore.SwaggerUI/9.0.6": { + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll": { + "assemblyVersion": "9.0.6.0", + "fileVersion": "9.0.6.1840" + } + } + }, "System.CodeDom/6.0.0": { "runtime": { "lib/net6.0/System.CodeDom.dll": { @@ -591,6 +747,18 @@ } } }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "assemblyVersion": "8.14.0.0", + "fileVersion": "8.14.0.60815" + } + } + }, "System.IO.Pipelines/7.0.0": {}, "System.Reflection.Metadata/7.0.0": { "dependencies": { @@ -615,6 +783,27 @@ "serviceable": false, "sha512": "" }, + "BCrypt.Net-Next/4.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-W+U9WvmZQgi5cX6FS5GDtDoPzUCV4LkBLkywq/kRZhuDwcbavOzcDAr3LXJFqHUi952Yj3LEYoWW0jbEUQChsA==", + "path": "bcrypt.net-next/4.0.3", + "hashPath": "bcrypt.net-next.4.0.3.nupkg.sha512" + }, + "FluentValidation/12.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8NVLxtMUXynRHJIX3Hn1ACovaqZIJASufXIIFkD0EUbcd5PmMsL1xUD5h548gCezJ5BzlITaR9CAMrGe29aWpA==", + "path": "fluentvalidation/12.0.0", + "hashPath": "fluentvalidation.12.0.0.nupkg.sha512" + }, + "FluentValidation.DependencyInjectionExtensions/12.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-B28fBRL1UjhGsBC8fwV6YBZosh+SiU1FxdD7l7p5dGPgRlVI7UnM+Lgzmg+unZtV1Zxzpaw96UY2MYfMaAd8cg==", + "path": "fluentvalidation.dependencyinjectionextensions/12.0.0", + "hashPath": "fluentvalidation.dependencyinjectionextensions.12.0.0.nupkg.sha512" + }, "Humanizer.Core/2.14.1": { "type": "package", "serviceable": true, @@ -622,6 +811,13 @@ "path": "humanizer.core/2.14.1", "hashPath": "humanizer.core.2.14.1.nupkg.sha512" }, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.9": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U5gW2DS/yAE9X0Ko63/O2lNApAzI/jhx4IT1Th6W0RShKv6XAVVgLGN3zqnmcd6DtAnp5FYs+4HZrxsTl0anLA==", + "path": "microsoft.aspnetcore.authentication.jwtbearer/9.0.9", + "hashPath": "microsoft.aspnetcore.authentication.jwtbearer.9.0.9.nupkg.sha512" + }, "Microsoft.Bcl.AsyncInterfaces/7.0.0": { "type": "package", "serviceable": true, @@ -720,6 +916,13 @@ "path": "microsoft.entityframeworkcore.relational/9.0.9", "hashPath": "microsoft.entityframeworkcore.relational.9.0.9.nupkg.sha512" }, + "Microsoft.Extensions.ApiDescription.Server/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1Kzzf7pRey40VaUkHN9/uWxrKVkLu2AQjt+GVeeKLLpiEHAJ1xZRsLSh4ZZYEnyS7Kt2OBOPmsXNdU+wbcOl5w==", + "path": "microsoft.extensions.apidescription.server/9.0.0", + "hashPath": "microsoft.extensions.apidescription.server.9.0.0.nupkg.sha512" + }, "Microsoft.Extensions.Caching.Abstractions/9.0.9": { "type": "package", "serviceable": true, @@ -790,6 +993,55 @@ "path": "microsoft.extensions.primitives/9.0.9", "hashPath": "microsoft.extensions.primitives.9.0.9.nupkg.sha512" }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "hashPath": "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "hashPath": "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "path": "microsoft.identitymodel.logging/8.14.0", + "hashPath": "microsoft.identitymodel.logging.8.14.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "path": "microsoft.identitymodel.protocols/8.0.1", + "hashPath": "microsoft.identitymodel.protocols.8.0.1.nupkg.sha512" + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "path": "microsoft.identitymodel.protocols.openidconnect/8.0.1", + "hashPath": "microsoft.identitymodel.protocols.openidconnect.8.0.1.nupkg.sha512" + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "path": "microsoft.identitymodel.tokens/8.14.0", + "hashPath": "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512" + }, + "Microsoft.OpenApi/1.6.25": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZahSqNGtNV7N0JBYS/IYXPkLVexL/AZFxo6pqxv6A7Uli7Q7zfitNjkaqIcsV73Ukzxi4IlJdyDgcQiMXiH8cw==", + "path": "microsoft.openapi/1.6.25", + "hashPath": "microsoft.openapi.1.6.25.nupkg.sha512" + }, "Mono.TextTemplating/3.0.0": { "type": "package", "serviceable": true, @@ -811,6 +1063,34 @@ "path": "npgsql.entityframeworkcore.postgresql/9.0.4", "hashPath": "npgsql.entityframeworkcore.postgresql.9.0.4.nupkg.sha512" }, + "Swashbuckle.AspNetCore/9.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-q/UfEAgrk6qQyjHXgsW9ILw0YZLfmPtWUY4wYijliX6supozC+TkzU0G6FTnn/dPYxnChjM8g8lHjWHF6VKy+A==", + "path": "swashbuckle.aspnetcore/9.0.6", + "hashPath": "swashbuckle.aspnetcore.9.0.6.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.Swagger/9.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Bgyc8rWRAYwDrzjVHGbavvNE38G1Dfgf1McHYm+WUr4TxkvEAXv8F8B1z3Kmz4BkDCKv9A/1COa2t7+Ri5+pLg==", + "path": "swashbuckle.aspnetcore.swagger/9.0.6", + "hashPath": "swashbuckle.aspnetcore.swagger.9.0.6.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.SwaggerGen/9.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yYrDs5qpIa4UXP+a02X0ZLQs6HSd1C8t6hF6J1fnxoawi3PslJg1yUpLBS89HCbrDACzmwEGG25il+8aa0zdnw==", + "path": "swashbuckle.aspnetcore.swaggergen/9.0.6", + "hashPath": "swashbuckle.aspnetcore.swaggergen.9.0.6.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.SwaggerUI/9.0.6": { + "type": "package", + "serviceable": true, + "sha512": "sha512-WGsw/Yop9b16miq8TQd4THxuEgkP5cH3+DX93BrX9m0OdPcKNtg2nNm77WQSAsA+Se+M0bTiu8bUyrruRSeS5g==", + "path": "swashbuckle.aspnetcore.swaggerui/9.0.6", + "hashPath": "swashbuckle.aspnetcore.swaggerui.9.0.6.nupkg.sha512" + }, "System.CodeDom/6.0.0": { "type": "package", "serviceable": true, @@ -867,6 +1147,13 @@ "path": "system.composition.typedparts/7.0.0", "hashPath": "system.composition.typedparts.7.0.0.nupkg.sha512" }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "hashPath": "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512" + }, "System.IO.Pipelines/7.0.0": { "type": "package", "serviceable": true, diff --git a/bin/Debug/net9.0/SimpleTodoApiWithPg.dll b/bin/Debug/net9.0/SimpleTodoApiWithPg.dll index 8fc7c28..2b7aa2b 100644 Binary files a/bin/Debug/net9.0/SimpleTodoApiWithPg.dll and b/bin/Debug/net9.0/SimpleTodoApiWithPg.dll differ diff --git a/bin/Debug/net9.0/SimpleTodoApiWithPg.exe b/bin/Debug/net9.0/SimpleTodoApiWithPg.exe index fa1def5..b60b110 100644 Binary files a/bin/Debug/net9.0/SimpleTodoApiWithPg.exe and b/bin/Debug/net9.0/SimpleTodoApiWithPg.exe differ diff --git a/bin/Debug/net9.0/SimpleTodoApiWithPg.pdb b/bin/Debug/net9.0/SimpleTodoApiWithPg.pdb index cee058c..5601db7 100644 Binary files a/bin/Debug/net9.0/SimpleTodoApiWithPg.pdb and b/bin/Debug/net9.0/SimpleTodoApiWithPg.pdb differ diff --git a/bin/Debug/net9.0/Swashbuckle.AspNetCore.Swagger.dll b/bin/Debug/net9.0/Swashbuckle.AspNetCore.Swagger.dll new file mode 100644 index 0000000..f0a5b88 Binary files /dev/null and b/bin/Debug/net9.0/Swashbuckle.AspNetCore.Swagger.dll differ diff --git a/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll b/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll new file mode 100644 index 0000000..5e6baa5 Binary files /dev/null and b/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll differ diff --git a/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll b/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll new file mode 100644 index 0000000..02337f3 Binary files /dev/null and b/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll differ diff --git a/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll b/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll new file mode 100644 index 0000000..5f487d8 Binary files /dev/null and b/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll differ diff --git a/bin/Debug/net9.0/appsettings.json b/bin/Debug/net9.0/appsettings.json index 10f68b8..50c7e1c 100644 --- a/bin/Debug/net9.0/appsettings.json +++ b/bin/Debug/net9.0/appsettings.json @@ -5,5 +5,11 @@ "Microsoft.AspNetCore": "Warning" } }, + "jwt": { + "Issuer": "baidu.com", + "Audience": "baidu.com", + "CertificatePath": "ecc-certificate.pfx", // 证书文件名 (相对于应用根目录) + "CertificatePassword": "UpRTXjaHdJaPCAjgjTTt" // 您在生成证书时设置的密码 + }, "AllowedHosts": "*" } diff --git a/bin/Debug/net9.0/ecc-certificate.pfx b/bin/Debug/net9.0/ecc-certificate.pfx new file mode 100644 index 0000000..ba54c14 Binary files /dev/null and b/bin/Debug/net9.0/ecc-certificate.pfx differ diff --git a/bin/Debug/net9.0/global.json b/bin/Debug/net9.0/global.json new file mode 100644 index 0000000..01fa100 --- /dev/null +++ b/bin/Debug/net9.0/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "9.0.203", + "rollForward": "latestFeature" + } +} \ No newline at end of file diff --git a/ecc-certificate.pfx b/ecc-certificate.pfx new file mode 100644 index 0000000..ba54c14 Binary files /dev/null and b/ecc-certificate.pfx differ diff --git a/global.json b/global.json new file mode 100644 index 0000000..01fa100 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "9.0.203", + "rollForward": "latestFeature" + } +} \ No newline at end of file diff --git a/obj/Debug/net9.0/ApiEndpoints.json b/obj/Debug/net9.0/ApiEndpoints.json new file mode 100644 index 0000000..74cf91e --- /dev/null +++ b/obj/Debug/net9.0/ApiEndpoints.json @@ -0,0 +1,232 @@ +[ + { + "ContainingType": "Program\u002B\u003C\u003Ec", + "Method": "\u003C\u003CMain\u003E$\u003Eb__0_4", + "RelativePath": "", + "HttpMethod": "GET", + "IsController": false, + "Order": 0, + "Parameters": [], + "ReturnTypes": [ + { + "Type": "System.String", + "MediaTypes": [ + "text/plain" + ], + "StatusCode": 200 + } + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_5", + "RelativePath": "api/auth/", + "HttpMethod": "POST", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "loginRequest", + "Type": "SimpleTodoApiWithPg.Models.LoginRequest", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "System.Void", + "MediaTypes": [], + "StatusCode": 200 + } + ], + "Tags": [ + "\u767B\u5F55\u8BA4\u8BC1\u6388\u6743\u63A5\u53E3!" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_6", + "RelativePath": "api/auth/refresh-token", + "HttpMethod": "POST", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "refreshToken", + "Type": "SimpleTodoApiWithPg.Models.RefreshTokenRequest", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "System.Void", + "MediaTypes": [], + "StatusCode": 200 + } + ], + "Tags": [ + "\u5237\u65B0\u4EE4\u724C\u63A5\u53E3" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_0", + "RelativePath": "users/", + "HttpMethod": "GET", + "IsController": false, + "Order": 0, + "Parameters": [], + "ReturnTypes": [ + { + "Type": "System.Collections.Generic.List\u00601[[SimpleTodoApiWithPg.Models.User, SimpleTodoApiWithPg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 200 + }, + { + "Type": "System.String", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 400 + } + ], + "Tags": [ + "\u83B7\u53D6\u6240\u6709\u7528\u6237" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_2", + "RelativePath": "users/", + "HttpMethod": "POST", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "request", + "Type": "SimpleTodoApiWithPg.Models.RegisterRequest", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "Microsoft.AspNetCore.Http.HttpValidationProblemDetails", + "MediaTypes": [ + "application/problem\u002Bjson" + ], + "StatusCode": 400 + } + ], + "Tags": [ + "\u7528\u6237\u6CE8\u518C\u63A5\u53E3" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_1", + "RelativePath": "users/{id}", + "HttpMethod": "GET", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "id", + "Type": "System.Guid", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "SimpleTodoApiWithPg.Models.User", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 200 + }, + { + "Type": "System.String", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 404 + } + ], + "Tags": [ + "\u6839\u636Eid\u83B7\u53D6\u5BF9\u5E94\u7684\u7528\u6237\u4FE1\u606F" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_3", + "RelativePath": "users/{id}", + "HttpMethod": "PATCH", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "id", + "Type": "System.Int32", + "IsRequired": true + }, + { + "Name": "updateUser", + "Type": "SimpleTodoApiWithPg.Models.UpdateUserRequest", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "SimpleTodoApiWithPg.Models.User", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 200 + }, + { + "Type": "System.String", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 404 + } + ], + "Tags": [ + "\u7528\u6237\u4FE1\u606F\u66F4\u65B0\u63A5\u53E3" + ] + }, + { + "ContainingType": "SimpleTodoApiWithPg.Endpoints.UserEndpoints\u002B\u003C\u003Ec", + "Method": "\u003CMapUserEndpoints\u003Eb__0_4", + "RelativePath": "users/{id}", + "HttpMethod": "DELETE", + "IsController": false, + "Order": 0, + "Parameters": [ + { + "Name": "id", + "Type": "System.Guid", + "IsRequired": true + } + ], + "ReturnTypes": [ + { + "Type": "System.String", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 200 + }, + { + "Type": "System.String", + "MediaTypes": [ + "application/json" + ], + "StatusCode": 404 + } + ], + "Tags": [ + "\u5220\u9664\u7528\u6237\u63A5\u53E3" + ] + } +] \ No newline at end of file diff --git a/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.OpenApiFiles.cache b/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.OpenApiFiles.cache new file mode 100644 index 0000000..ce2551b --- /dev/null +++ b/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.OpenApiFiles.cache @@ -0,0 +1 @@ +SimpleTodoApiWithPg.json diff --git a/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.json b/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.json new file mode 100644 index 0000000..6108fae --- /dev/null +++ b/obj/Debug/net9.0/EndpointInfo/SimpleTodoApiWithPg.json @@ -0,0 +1,403 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "SimpleTodoApiWithPg", + "version": "1.0" + }, + "paths": { + "/api/auth": { + "post": { + "tags": [ + "登录认证授权接口!" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/users/{id}": { + "get": { + "tags": [ + "根据id获取对应的用户信息" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + } + }, + "delete": { + "tags": [ + "删除用户接口" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + } + }, + "patch": { + "tags": [ + "用户信息更新接口" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/users": { + "get": { + "tags": [ + "获取所有用户" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + } + }, + "post": { + "tags": [ + "用户注册接口" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterRequest" + } + } + }, + "required": true + }, + "responses": { + "400": { + "description": "Bad Request", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/HttpValidationProblemDetails" + } + } + } + } + } + } + }, + "/api/auth/refresh-token": { + "post": { + "tags": [ + "刷新令牌接口" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshTokenRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/": { + "get": { + "tags": [ + "SimpleTodoApiWithPg" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "HttpValidationProblemDetails": { + "type": "object", + "properties": { + "type": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "status": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "instance": { + "type": "string", + "nullable": true + }, + "errors": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "nullable": true + } + }, + "additionalProperties": { } + }, + "LoginRequest": { + "required": [ + "password", + "username" + ], + "type": "object", + "properties": { + "username": { + "maxLength": 50, + "minLength": 1, + "type": "string" + }, + "password": { + "maxLength": 50, + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "RefreshTokenRequest": { + "type": "object", + "properties": { + "refreshToken": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "RegisterRequest": { + "required": [ + "email", + "username" + ], + "type": "object", + "properties": { + "username": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateUserRequest": { + "type": "object", + "properties": { + "username": { + "maxLength": 50, + "type": "string", + "nullable": true + }, + "email": { + "maxLength": 100, + "type": "string", + "format": "email", + "nullable": true + }, + "newPassword": { + "maxLength": 50, + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "User": { + "required": [ + "email", + "passwordHash", + "username" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "username": { + "maxLength": 50, + "minLength": 1, + "type": "string" + }, + "email": { + "maxLength": 50, + "minLength": 5, + "type": "string", + "format": "email" + }, + "passwordHash": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + } + } + } +} \ No newline at end of file diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfo.cs b/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfo.cs index 8ed1bc5..87caeca 100644 --- a/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfo.cs +++ b/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfo.cs @@ -1,9 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 // //------------------------------------------------------------------------------ @@ -13,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("SimpleTodoApiWithPg")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8ab52738c086cb1a3aa894122cfb801985cf1b9b")] [assembly: System.Reflection.AssemblyProductAttribute("SimpleTodoApiWithPg")] [assembly: System.Reflection.AssemblyTitleAttribute("SimpleTodoApiWithPg")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfoInputs.cache b/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfoInputs.cache index f9ff335..ce1e0bb 100644 --- a/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfoInputs.cache +++ b/obj/Debug/net9.0/SimpleTodoApiWithPg.AssemblyInfoInputs.cache @@ -1 +1 @@ -e0a450d7f7ecf2071ba072fc6f6c15983dfaa6fea6288c9b6a218625a530e48f +bc56e06accd466e2627943e8dc62f6bb1f983bfa111ed39fecd5b88f6b089ded diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cs b/obj/Debug/net9.0/SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cs new file mode 100644 index 0000000..a8a0fb0 --- /dev/null +++ b/obj/Debug/net9.0/SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("Swashbuckle.AspNetCore.SwaggerGen")] + +// 由 MSBuild WriteCodeFragment 类生成。 + diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.assets.cache b/obj/Debug/net9.0/SimpleTodoApiWithPg.assets.cache index 1ff6eae..dc77d83 100644 Binary files a/obj/Debug/net9.0/SimpleTodoApiWithPg.assets.cache and b/obj/Debug/net9.0/SimpleTodoApiWithPg.assets.cache differ diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.AssemblyReference.cache b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.AssemblyReference.cache index 69f88ad..5321ba9 100644 Binary files a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.AssemblyReference.cache and b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.AssemblyReference.cache differ diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.BuildWithSkipAnalyzers b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.BuildWithSkipAnalyzers new file mode 100644 index 0000000..e69de29 diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache index 730fe02..a8adbf3 100644 --- a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache +++ b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -2bce65f69d2c68eb81bc3d1d692a255f9f87885472ee7fbdc1d07c93d722e3a8 +0effd9d609e1d00c69ee989d814ac6a47d1f1ea54efb5cc3ae49700f1991fab2 diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.FileListAbsolute.txt b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.FileListAbsolute.txt index 1dd0be3..37a3ed8 100644 --- a/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.FileListAbsolute.txt +++ b/obj/Debug/net9.0/SimpleTodoApiWithPg.csproj.FileListAbsolute.txt @@ -1,12 +1,22 @@ +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.csproj.AssemblyReference.cache +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.GeneratedMSBuildEditorConfig.editorconfig +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.AssemblyInfoInputs.cache +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.AssemblyInfo.cs +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cache C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\appsettings.Development.json C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\appsettings.json +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\global.json C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.staticwebassets.endpoints.json +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\ecc-certificate.pfx C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.exe C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.deps.json C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.runtimeconfig.json C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\SimpleTodoApiWithPg.pdb +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\BCrypt.Net-Next.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Humanizer.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Bcl.AsyncInterfaces.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Build.Locator.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.CodeAnalysis.dll @@ -29,6 +39,12 @@ C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Extensions.Logging.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Extensions.Logging.Abstractions.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Extensions.Options.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.Extensions.Primitives.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.Abstractions.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.JsonWebTokens.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.Logging.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.Protocols.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.IdentityModel.Tokens.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Mono.TextTemplating.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Npgsql.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll @@ -38,6 +54,7 @@ C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.Composition.Convention.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.Composition.Hosting.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.Composition.Runtime.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.Composition.TypedParts.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.IdentityModel.Tokens.Jwt.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\System.Text.Json.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\cs\Microsoft.CodeAnalysis.resources.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\de\Microsoft.CodeAnalysis.resources.dll @@ -104,12 +121,6 @@ C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\ru\Microsoft.CodeAnalysis.Workspace C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\tr\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\zh-Hans\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\zh-Hant\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.csproj.AssemblyReference.cache -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.GeneratedMSBuildEditorConfig.editorconfig -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.AssemblyInfoInputs.cache -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.AssemblyInfo.cs -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.csproj.CoreCompileInputs.cache -C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cache C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\scopedcss\bundle\SimpleTodoApiWithPg.styles.css C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets.build.json C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets.development.json @@ -120,9 +131,17 @@ C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets\msbuild.build.Simpl C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets\msbuild.buildMultiTargeting.SimpleTodoApiWithPg.props C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets\msbuild.buildTransitive.SimpleTodoApiWithPg.props C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets.pack.json +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\staticwebassets.upToDateCheck.txt C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTo.008CF47A.Up2Date C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.dll C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\refint\SimpleTodoApiWithPg.dll C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.pdb C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.genruntimeconfig.cache C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\ref\SimpleTodoApiWithPg.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Microsoft.OpenApi.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Swashbuckle.AspNetCore.Swagger.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Swashbuckle.AspNetCore.SwaggerGen.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\Swashbuckle.AspNetCore.SwaggerUI.dll +C:\code\SimpleTodoApiWithPg\obj\Debug\net9.0\SimpleTodoApiWithPg.MvcApplicationPartsAssemblyInfo.cs +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\FluentValidation.dll +C:\code\SimpleTodoApiWithPg\bin\Debug\net9.0\FluentValidation.DependencyInjectionExtensions.dll diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.dll b/obj/Debug/net9.0/SimpleTodoApiWithPg.dll index 8fc7c28..2b7aa2b 100644 Binary files a/obj/Debug/net9.0/SimpleTodoApiWithPg.dll and b/obj/Debug/net9.0/SimpleTodoApiWithPg.dll differ diff --git a/obj/Debug/net9.0/SimpleTodoApiWithPg.pdb b/obj/Debug/net9.0/SimpleTodoApiWithPg.pdb index cee058c..5601db7 100644 Binary files a/obj/Debug/net9.0/SimpleTodoApiWithPg.pdb and b/obj/Debug/net9.0/SimpleTodoApiWithPg.pdb differ diff --git a/obj/Debug/net9.0/apphost.exe b/obj/Debug/net9.0/apphost.exe index fa1def5..b60b110 100644 Binary files a/obj/Debug/net9.0/apphost.exe and b/obj/Debug/net9.0/apphost.exe differ diff --git a/obj/Debug/net9.0/ref/SimpleTodoApiWithPg.dll b/obj/Debug/net9.0/ref/SimpleTodoApiWithPg.dll index 694d215..c344750 100644 Binary files a/obj/Debug/net9.0/ref/SimpleTodoApiWithPg.dll and b/obj/Debug/net9.0/ref/SimpleTodoApiWithPg.dll differ diff --git a/obj/Debug/net9.0/refint/SimpleTodoApiWithPg.dll b/obj/Debug/net9.0/refint/SimpleTodoApiWithPg.dll index 694d215..c344750 100644 Binary files a/obj/Debug/net9.0/refint/SimpleTodoApiWithPg.dll and b/obj/Debug/net9.0/refint/SimpleTodoApiWithPg.dll differ diff --git a/obj/Debug/net9.0/staticwebassets.references.upToDateCheck.txt b/obj/Debug/net9.0/staticwebassets.references.upToDateCheck.txt new file mode 100644 index 0000000..e69de29 diff --git a/obj/Debug/net9.0/staticwebassets.removed.txt b/obj/Debug/net9.0/staticwebassets.removed.txt new file mode 100644 index 0000000..e69de29 diff --git a/obj/SimpleTodoApiWithPg.csproj.nuget.dgspec.json b/obj/SimpleTodoApiWithPg.csproj.nuget.dgspec.json index fb60757..64295f6 100644 --- a/obj/SimpleTodoApiWithPg.csproj.nuget.dgspec.json +++ b/obj/SimpleTodoApiWithPg.csproj.nuget.dgspec.json @@ -13,13 +13,19 @@ "packagesPath": "C:\\Users\\heiye\\.nuget\\packages\\", "outputPath": "C:\\code\\SimpleTodoApiWithPg\\obj\\", "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], "configFilePaths": [ - "C:\\Users\\heiye\\AppData\\Roaming\\NuGet\\NuGet.Config" + "C:\\Users\\heiye\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" ], "originalTargetFrameworks": [ "net9.0" ], "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { @@ -44,6 +50,18 @@ "net9.0": { "targetAlias": "net9.0", "dependencies": { + "BCrypt.Net-Next": { + "target": "Package", + "version": "[4.0.3, )" + }, + "FluentValidation.DependencyInjectionExtensions": { + "target": "Package", + "version": "[12.0.0, )" + }, + "Microsoft.AspNetCore.Authentication.JwtBearer": { + "target": "Package", + "version": "[9.0.9, )" + }, "Microsoft.EntityFrameworkCore.Design": { "include": "Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive", "suppressParent": "All", @@ -53,6 +71,14 @@ "Npgsql.EntityFrameworkCore.PostgreSQL": { "target": "Package", "version": "[9.0.4, )" + }, + "Swashbuckle.AspNetCore": { + "target": "Package", + "version": "[9.0.6, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" } }, "imports": [ diff --git a/obj/SimpleTodoApiWithPg.csproj.nuget.g.props b/obj/SimpleTodoApiWithPg.csproj.nuget.g.props index 9bc4a73..bc41320 100644 --- a/obj/SimpleTodoApiWithPg.csproj.nuget.g.props +++ b/obj/SimpleTodoApiWithPg.csproj.nuget.g.props @@ -5,19 +5,23 @@ NuGet $(MSBuildThisFileDirectory)project.assets.json $(UserProfile)\.nuget\packages\ - C:\Users\heiye\.nuget\packages\ + C:\Users\heiye\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages PackageReference - 6.13.2 + 7.0.0 + + + + C:\Users\heiye\.nuget\packages\microsoft.extensions.apidescription.server\9.0.0 C:\Users\heiye\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.4 \ No newline at end of file diff --git a/obj/SimpleTodoApiWithPg.csproj.nuget.g.targets b/obj/SimpleTodoApiWithPg.csproj.nuget.g.targets index 40cac3c..9c79957 100644 --- a/obj/SimpleTodoApiWithPg.csproj.nuget.g.targets +++ b/obj/SimpleTodoApiWithPg.csproj.nuget.g.targets @@ -3,6 +3,7 @@ + diff --git a/obj/project.assets.json b/obj/project.assets.json index 43861b3..7f69134 100644 --- a/obj/project.assets.json +++ b/obj/project.assets.json @@ -2,6 +2,49 @@ "version": 3, "targets": { "net9.0": { + "BCrypt.Net-Next/4.0.3": { + "type": "package", + "compile": { + "lib/net6.0/BCrypt.Net-Next.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/BCrypt.Net-Next.dll": { + "related": ".xml" + } + } + }, + "FluentValidation/12.0.0": { + "type": "package", + "compile": { + "lib/net8.0/FluentValidation.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/FluentValidation.dll": { + "related": ".xml" + } + } + }, + "FluentValidation.DependencyInjectionExtensions/12.0.0": { + "type": "package", + "dependencies": { + "FluentValidation": "12.0.0", + "Microsoft.Extensions.Dependencyinjection.Abstractions": "2.1.0" + }, + "compile": { + "lib/net8.0/FluentValidation.DependencyInjectionExtensions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net8.0/FluentValidation.DependencyInjectionExtensions.dll": { + "related": ".xml" + } + } + }, "Humanizer.Core/2.14.1": { "type": "package", "compile": { @@ -15,6 +58,25 @@ } } }, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.9": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + }, + "compile": { + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll": { + "related": ".xml" + } + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ] + }, "Microsoft.Bcl.AsyncInterfaces/7.0.0": { "type": "package", "compile": { @@ -450,6 +512,17 @@ } } }, + "Microsoft.Extensions.ApiDescription.Server/9.0.0": { + "type": "package", + "build": { + "build/Microsoft.Extensions.ApiDescription.Server.props": {}, + "build/Microsoft.Extensions.ApiDescription.Server.targets": {} + }, + "buildMultiTargeting": { + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.props": {}, + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.targets": {} + } + }, "Microsoft.Extensions.Caching.Abstractions/9.0.9": { "type": "package", "dependencies": { @@ -638,6 +711,114 @@ "buildTransitive/net8.0/_._": {} } }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "type": "package", + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.0.1" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.0.1" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": { + "related": ".xml" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "Microsoft.IdentityModel.Logging": "8.14.0" + }, + "compile": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "related": ".xml" + } + } + }, + "Microsoft.OpenApi/1.6.25": { + "type": "package", + "compile": { + "lib/netstandard2.0/Microsoft.OpenApi.dll": { + "related": ".pdb;.xml" + } + }, + "runtime": { + "lib/netstandard2.0/Microsoft.OpenApi.dll": { + "related": ".pdb;.xml" + } + } + }, "Mono.TextTemplating/3.0.0": { "type": "package", "dependencies": { @@ -687,6 +868,72 @@ } } }, + "Swashbuckle.AspNetCore/9.0.6": { + "type": "package", + "dependencies": { + "Microsoft.Extensions.ApiDescription.Server": "9.0.0", + "Swashbuckle.AspNetCore.Swagger": "9.0.6", + "Swashbuckle.AspNetCore.SwaggerGen": "9.0.6", + "Swashbuckle.AspNetCore.SwaggerUI": "9.0.6" + }, + "build": { + "build/Swashbuckle.AspNetCore.props": {} + }, + "buildMultiTargeting": { + "buildMultiTargeting/Swashbuckle.AspNetCore.props": {} + } + }, + "Swashbuckle.AspNetCore.Swagger/9.0.6": { + "type": "package", + "dependencies": { + "Microsoft.OpenApi": "1.6.25" + }, + "compile": { + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll": { + "related": ".pdb;.xml" + } + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll": { + "related": ".pdb;.xml" + } + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ] + }, + "Swashbuckle.AspNetCore.SwaggerGen/9.0.6": { + "type": "package", + "dependencies": { + "Swashbuckle.AspNetCore.Swagger": "9.0.6" + }, + "compile": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll": { + "related": ".pdb;.xml" + } + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll": { + "related": ".pdb;.xml" + } + } + }, + "Swashbuckle.AspNetCore.SwaggerUI/9.0.6": { + "type": "package", + "compile": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll": { + "related": ".pdb;.xml" + } + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll": { + "related": ".pdb;.xml" + } + }, + "frameworkReferences": [ + "Microsoft.AspNetCore.App" + ] + }, "System.CodeDom/6.0.0": { "type": "package", "compile": { @@ -829,6 +1076,23 @@ "buildTransitive/net6.0/_._": {} } }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "type": "package", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.14.0", + "Microsoft.IdentityModel.Tokens": "8.14.0" + }, + "compile": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "related": ".xml" + } + } + }, "System.IO.Pipelines/7.0.0": { "type": "package", "compile": { @@ -915,6 +1179,67 @@ } }, "libraries": { + "BCrypt.Net-Next/4.0.3": { + "sha512": "W+U9WvmZQgi5cX6FS5GDtDoPzUCV4LkBLkywq/kRZhuDwcbavOzcDAr3LXJFqHUi952Yj3LEYoWW0jbEUQChsA==", + "type": "package", + "path": "bcrypt.net-next/4.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "bcrypt.net-next.4.0.3.nupkg.sha512", + "bcrypt.net-next.nuspec", + "ico.png", + "lib/net20/BCrypt.Net-Next.dll", + "lib/net20/BCrypt.Net-Next.xml", + "lib/net35/BCrypt.Net-Next.dll", + "lib/net35/BCrypt.Net-Next.xml", + "lib/net462/BCrypt.Net-Next.dll", + "lib/net462/BCrypt.Net-Next.xml", + "lib/net472/BCrypt.Net-Next.dll", + "lib/net472/BCrypt.Net-Next.xml", + "lib/net48/BCrypt.Net-Next.dll", + "lib/net48/BCrypt.Net-Next.xml", + "lib/net5.0/BCrypt.Net-Next.dll", + "lib/net5.0/BCrypt.Net-Next.xml", + "lib/net6.0/BCrypt.Net-Next.dll", + "lib/net6.0/BCrypt.Net-Next.xml", + "lib/netstandard2.0/BCrypt.Net-Next.dll", + "lib/netstandard2.0/BCrypt.Net-Next.xml", + "lib/netstandard2.1/BCrypt.Net-Next.dll", + "lib/netstandard2.1/BCrypt.Net-Next.xml", + "readme.md" + ] + }, + "FluentValidation/12.0.0": { + "sha512": "8NVLxtMUXynRHJIX3Hn1ACovaqZIJASufXIIFkD0EUbcd5PmMsL1xUD5h548gCezJ5BzlITaR9CAMrGe29aWpA==", + "type": "package", + "path": "fluentvalidation/12.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "fluent-validation-icon.png", + "fluentvalidation.12.0.0.nupkg.sha512", + "fluentvalidation.nuspec", + "lib/net8.0/FluentValidation.dll", + "lib/net8.0/FluentValidation.xml" + ] + }, + "FluentValidation.DependencyInjectionExtensions/12.0.0": { + "sha512": "B28fBRL1UjhGsBC8fwV6YBZosh+SiU1FxdD7l7p5dGPgRlVI7UnM+Lgzmg+unZtV1Zxzpaw96UY2MYfMaAd8cg==", + "type": "package", + "path": "fluentvalidation.dependencyinjectionextensions/12.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "fluent-validation-icon.png", + "fluentvalidation.dependencyinjectionextensions.12.0.0.nupkg.sha512", + "fluentvalidation.dependencyinjectionextensions.nuspec", + "lib/net8.0/FluentValidation.DependencyInjectionExtensions.dll", + "lib/net8.0/FluentValidation.DependencyInjectionExtensions.xml" + ] + }, "Humanizer.Core/2.14.1": { "sha512": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw==", "type": "package", @@ -933,6 +1258,22 @@ "logo.png" ] }, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.9": { + "sha512": "U5gW2DS/yAE9X0Ko63/O2lNApAzI/jhx4IT1Th6W0RShKv6XAVVgLGN3zqnmcd6DtAnp5FYs+4HZrxsTl0anLA==", + "type": "package", + "path": "microsoft.aspnetcore.authentication.jwtbearer/9.0.9", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "PACKAGE.md", + "THIRD-PARTY-NOTICES.TXT", + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll", + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.xml", + "microsoft.aspnetcore.authentication.jwtbearer.9.0.9.nupkg.sha512", + "microsoft.aspnetcore.authentication.jwtbearer.nuspec" + ] + }, "Microsoft.Bcl.AsyncInterfaces/7.0.0": { "sha512": "3aeMZ1N0lJoSyzqiP03hqemtb1BijhsJADdobn/4nsMJ8V1H+CrpuduUe4hlRdx+ikBQju1VGjMD1GJ3Sk05Eg==", "type": "package", @@ -1991,6 +2332,263 @@ "microsoft.entityframeworkcore.relational.nuspec" ] }, + "Microsoft.Extensions.ApiDescription.Server/9.0.0": { + "sha512": "1Kzzf7pRey40VaUkHN9/uWxrKVkLu2AQjt+GVeeKLLpiEHAJ1xZRsLSh4ZZYEnyS7Kt2OBOPmsXNdU+wbcOl5w==", + "type": "package", + "path": "microsoft.extensions.apidescription.server/9.0.0", + "hasTools": true, + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "build/Microsoft.Extensions.ApiDescription.Server.props", + "build/Microsoft.Extensions.ApiDescription.Server.targets", + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.props", + "buildMultiTargeting/Microsoft.Extensions.ApiDescription.Server.targets", + "microsoft.extensions.apidescription.server.9.0.0.nupkg.sha512", + "microsoft.extensions.apidescription.server.nuspec", + "tools/Newtonsoft.Json.dll", + "tools/dotnet-getdocument.deps.json", + "tools/dotnet-getdocument.dll", + "tools/dotnet-getdocument.runtimeconfig.json", + "tools/net462-x86/GetDocument.Insider.exe", + "tools/net462-x86/GetDocument.Insider.exe.config", + "tools/net462-x86/Microsoft.OpenApi.dll", + "tools/net462-x86/Microsoft.Win32.Primitives.dll", + "tools/net462-x86/System.AppContext.dll", + "tools/net462-x86/System.Buffers.dll", + "tools/net462-x86/System.Collections.Concurrent.dll", + "tools/net462-x86/System.Collections.NonGeneric.dll", + "tools/net462-x86/System.Collections.Specialized.dll", + "tools/net462-x86/System.Collections.dll", + "tools/net462-x86/System.ComponentModel.EventBasedAsync.dll", + "tools/net462-x86/System.ComponentModel.Primitives.dll", + "tools/net462-x86/System.ComponentModel.TypeConverter.dll", + "tools/net462-x86/System.ComponentModel.dll", + "tools/net462-x86/System.Console.dll", + "tools/net462-x86/System.Data.Common.dll", + "tools/net462-x86/System.Diagnostics.Contracts.dll", + "tools/net462-x86/System.Diagnostics.Debug.dll", + "tools/net462-x86/System.Diagnostics.DiagnosticSource.dll", + "tools/net462-x86/System.Diagnostics.FileVersionInfo.dll", + "tools/net462-x86/System.Diagnostics.Process.dll", + "tools/net462-x86/System.Diagnostics.StackTrace.dll", + "tools/net462-x86/System.Diagnostics.TextWriterTraceListener.dll", + "tools/net462-x86/System.Diagnostics.Tools.dll", + "tools/net462-x86/System.Diagnostics.TraceSource.dll", + "tools/net462-x86/System.Diagnostics.Tracing.dll", + "tools/net462-x86/System.Drawing.Primitives.dll", + "tools/net462-x86/System.Dynamic.Runtime.dll", + "tools/net462-x86/System.Globalization.Calendars.dll", + "tools/net462-x86/System.Globalization.Extensions.dll", + "tools/net462-x86/System.Globalization.dll", + "tools/net462-x86/System.IO.Compression.ZipFile.dll", + "tools/net462-x86/System.IO.Compression.dll", + "tools/net462-x86/System.IO.FileSystem.DriveInfo.dll", + "tools/net462-x86/System.IO.FileSystem.Primitives.dll", + "tools/net462-x86/System.IO.FileSystem.Watcher.dll", + "tools/net462-x86/System.IO.FileSystem.dll", + "tools/net462-x86/System.IO.IsolatedStorage.dll", + "tools/net462-x86/System.IO.MemoryMappedFiles.dll", + "tools/net462-x86/System.IO.Pipes.dll", + "tools/net462-x86/System.IO.UnmanagedMemoryStream.dll", + "tools/net462-x86/System.IO.dll", + "tools/net462-x86/System.Linq.Expressions.dll", + "tools/net462-x86/System.Linq.Parallel.dll", + "tools/net462-x86/System.Linq.Queryable.dll", + "tools/net462-x86/System.Linq.dll", + "tools/net462-x86/System.Memory.dll", + "tools/net462-x86/System.Net.Http.dll", + "tools/net462-x86/System.Net.NameResolution.dll", + "tools/net462-x86/System.Net.NetworkInformation.dll", + "tools/net462-x86/System.Net.Ping.dll", + "tools/net462-x86/System.Net.Primitives.dll", + "tools/net462-x86/System.Net.Requests.dll", + "tools/net462-x86/System.Net.Security.dll", + "tools/net462-x86/System.Net.Sockets.dll", + "tools/net462-x86/System.Net.WebHeaderCollection.dll", + "tools/net462-x86/System.Net.WebSockets.Client.dll", + "tools/net462-x86/System.Net.WebSockets.dll", + "tools/net462-x86/System.Numerics.Vectors.dll", + "tools/net462-x86/System.ObjectModel.dll", + "tools/net462-x86/System.Reflection.Extensions.dll", + "tools/net462-x86/System.Reflection.Primitives.dll", + "tools/net462-x86/System.Reflection.dll", + "tools/net462-x86/System.Resources.Reader.dll", + "tools/net462-x86/System.Resources.ResourceManager.dll", + "tools/net462-x86/System.Resources.Writer.dll", + "tools/net462-x86/System.Runtime.CompilerServices.Unsafe.dll", + "tools/net462-x86/System.Runtime.CompilerServices.VisualC.dll", + "tools/net462-x86/System.Runtime.Extensions.dll", + "tools/net462-x86/System.Runtime.Handles.dll", + "tools/net462-x86/System.Runtime.InteropServices.RuntimeInformation.dll", + "tools/net462-x86/System.Runtime.InteropServices.dll", + "tools/net462-x86/System.Runtime.Numerics.dll", + "tools/net462-x86/System.Runtime.Serialization.Formatters.dll", + "tools/net462-x86/System.Runtime.Serialization.Json.dll", + "tools/net462-x86/System.Runtime.Serialization.Primitives.dll", + "tools/net462-x86/System.Runtime.Serialization.Xml.dll", + "tools/net462-x86/System.Runtime.dll", + "tools/net462-x86/System.Security.Claims.dll", + "tools/net462-x86/System.Security.Cryptography.Algorithms.dll", + "tools/net462-x86/System.Security.Cryptography.Csp.dll", + "tools/net462-x86/System.Security.Cryptography.Encoding.dll", + "tools/net462-x86/System.Security.Cryptography.Primitives.dll", + "tools/net462-x86/System.Security.Cryptography.X509Certificates.dll", + "tools/net462-x86/System.Security.Principal.dll", + "tools/net462-x86/System.Security.SecureString.dll", + "tools/net462-x86/System.Text.Encoding.Extensions.dll", + "tools/net462-x86/System.Text.Encoding.dll", + "tools/net462-x86/System.Text.RegularExpressions.dll", + "tools/net462-x86/System.Threading.Overlapped.dll", + "tools/net462-x86/System.Threading.Tasks.Parallel.dll", + "tools/net462-x86/System.Threading.Tasks.dll", + "tools/net462-x86/System.Threading.Thread.dll", + "tools/net462-x86/System.Threading.ThreadPool.dll", + "tools/net462-x86/System.Threading.Timer.dll", + "tools/net462-x86/System.Threading.dll", + "tools/net462-x86/System.ValueTuple.dll", + "tools/net462-x86/System.Xml.ReaderWriter.dll", + "tools/net462-x86/System.Xml.XDocument.dll", + "tools/net462-x86/System.Xml.XPath.XDocument.dll", + "tools/net462-x86/System.Xml.XPath.dll", + "tools/net462-x86/System.Xml.XmlDocument.dll", + "tools/net462-x86/System.Xml.XmlSerializer.dll", + "tools/net462-x86/netstandard.dll", + "tools/net462/GetDocument.Insider.exe", + "tools/net462/GetDocument.Insider.exe.config", + "tools/net462/Microsoft.OpenApi.dll", + "tools/net462/Microsoft.Win32.Primitives.dll", + "tools/net462/System.AppContext.dll", + "tools/net462/System.Buffers.dll", + "tools/net462/System.Collections.Concurrent.dll", + "tools/net462/System.Collections.NonGeneric.dll", + "tools/net462/System.Collections.Specialized.dll", + "tools/net462/System.Collections.dll", + "tools/net462/System.ComponentModel.EventBasedAsync.dll", + "tools/net462/System.ComponentModel.Primitives.dll", + "tools/net462/System.ComponentModel.TypeConverter.dll", + "tools/net462/System.ComponentModel.dll", + "tools/net462/System.Console.dll", + "tools/net462/System.Data.Common.dll", + "tools/net462/System.Diagnostics.Contracts.dll", + "tools/net462/System.Diagnostics.Debug.dll", + "tools/net462/System.Diagnostics.DiagnosticSource.dll", + "tools/net462/System.Diagnostics.FileVersionInfo.dll", + "tools/net462/System.Diagnostics.Process.dll", + "tools/net462/System.Diagnostics.StackTrace.dll", + "tools/net462/System.Diagnostics.TextWriterTraceListener.dll", + "tools/net462/System.Diagnostics.Tools.dll", + "tools/net462/System.Diagnostics.TraceSource.dll", + "tools/net462/System.Diagnostics.Tracing.dll", + "tools/net462/System.Drawing.Primitives.dll", + "tools/net462/System.Dynamic.Runtime.dll", + "tools/net462/System.Globalization.Calendars.dll", + "tools/net462/System.Globalization.Extensions.dll", + "tools/net462/System.Globalization.dll", + "tools/net462/System.IO.Compression.ZipFile.dll", + "tools/net462/System.IO.Compression.dll", + "tools/net462/System.IO.FileSystem.DriveInfo.dll", + "tools/net462/System.IO.FileSystem.Primitives.dll", + "tools/net462/System.IO.FileSystem.Watcher.dll", + "tools/net462/System.IO.FileSystem.dll", + "tools/net462/System.IO.IsolatedStorage.dll", + "tools/net462/System.IO.MemoryMappedFiles.dll", + "tools/net462/System.IO.Pipes.dll", + "tools/net462/System.IO.UnmanagedMemoryStream.dll", + "tools/net462/System.IO.dll", + "tools/net462/System.Linq.Expressions.dll", + "tools/net462/System.Linq.Parallel.dll", + "tools/net462/System.Linq.Queryable.dll", + "tools/net462/System.Linq.dll", + "tools/net462/System.Memory.dll", + "tools/net462/System.Net.Http.dll", + "tools/net462/System.Net.NameResolution.dll", + "tools/net462/System.Net.NetworkInformation.dll", + "tools/net462/System.Net.Ping.dll", + "tools/net462/System.Net.Primitives.dll", + "tools/net462/System.Net.Requests.dll", + "tools/net462/System.Net.Security.dll", + "tools/net462/System.Net.Sockets.dll", + "tools/net462/System.Net.WebHeaderCollection.dll", + "tools/net462/System.Net.WebSockets.Client.dll", + "tools/net462/System.Net.WebSockets.dll", + "tools/net462/System.Numerics.Vectors.dll", + "tools/net462/System.ObjectModel.dll", + "tools/net462/System.Reflection.Extensions.dll", + "tools/net462/System.Reflection.Primitives.dll", + "tools/net462/System.Reflection.dll", + "tools/net462/System.Resources.Reader.dll", + "tools/net462/System.Resources.ResourceManager.dll", + "tools/net462/System.Resources.Writer.dll", + "tools/net462/System.Runtime.CompilerServices.Unsafe.dll", + "tools/net462/System.Runtime.CompilerServices.VisualC.dll", + "tools/net462/System.Runtime.Extensions.dll", + "tools/net462/System.Runtime.Handles.dll", + "tools/net462/System.Runtime.InteropServices.RuntimeInformation.dll", + "tools/net462/System.Runtime.InteropServices.dll", + "tools/net462/System.Runtime.Numerics.dll", + "tools/net462/System.Runtime.Serialization.Formatters.dll", + "tools/net462/System.Runtime.Serialization.Json.dll", + "tools/net462/System.Runtime.Serialization.Primitives.dll", + "tools/net462/System.Runtime.Serialization.Xml.dll", + "tools/net462/System.Runtime.dll", + "tools/net462/System.Security.Claims.dll", + "tools/net462/System.Security.Cryptography.Algorithms.dll", + "tools/net462/System.Security.Cryptography.Csp.dll", + "tools/net462/System.Security.Cryptography.Encoding.dll", + "tools/net462/System.Security.Cryptography.Primitives.dll", + "tools/net462/System.Security.Cryptography.X509Certificates.dll", + "tools/net462/System.Security.Principal.dll", + "tools/net462/System.Security.SecureString.dll", + "tools/net462/System.Text.Encoding.Extensions.dll", + "tools/net462/System.Text.Encoding.dll", + "tools/net462/System.Text.RegularExpressions.dll", + "tools/net462/System.Threading.Overlapped.dll", + "tools/net462/System.Threading.Tasks.Parallel.dll", + "tools/net462/System.Threading.Tasks.dll", + "tools/net462/System.Threading.Thread.dll", + "tools/net462/System.Threading.ThreadPool.dll", + "tools/net462/System.Threading.Timer.dll", + "tools/net462/System.Threading.dll", + "tools/net462/System.ValueTuple.dll", + "tools/net462/System.Xml.ReaderWriter.dll", + "tools/net462/System.Xml.XDocument.dll", + "tools/net462/System.Xml.XPath.XDocument.dll", + "tools/net462/System.Xml.XPath.dll", + "tools/net462/System.Xml.XmlDocument.dll", + "tools/net462/System.Xml.XmlSerializer.dll", + "tools/net462/netstandard.dll", + "tools/net9.0/GetDocument.Insider.deps.json", + "tools/net9.0/GetDocument.Insider.dll", + "tools/net9.0/GetDocument.Insider.exe", + "tools/net9.0/GetDocument.Insider.runtimeconfig.json", + "tools/net9.0/Microsoft.AspNetCore.Connections.Abstractions.dll", + "tools/net9.0/Microsoft.AspNetCore.Connections.Abstractions.xml", + "tools/net9.0/Microsoft.AspNetCore.Hosting.Server.Abstractions.dll", + "tools/net9.0/Microsoft.AspNetCore.Hosting.Server.Abstractions.xml", + "tools/net9.0/Microsoft.AspNetCore.Http.Features.dll", + "tools/net9.0/Microsoft.AspNetCore.Http.Features.xml", + "tools/net9.0/Microsoft.Extensions.Configuration.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.Diagnostics.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.Features.dll", + "tools/net9.0/Microsoft.Extensions.Features.xml", + "tools/net9.0/Microsoft.Extensions.FileProviders.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.Hosting.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.Logging.Abstractions.dll", + "tools/net9.0/Microsoft.Extensions.Options.dll", + "tools/net9.0/Microsoft.Extensions.Primitives.dll", + "tools/net9.0/Microsoft.Net.Http.Headers.dll", + "tools/net9.0/Microsoft.Net.Http.Headers.xml", + "tools/net9.0/Microsoft.OpenApi.dll", + "tools/netcoreapp2.1/GetDocument.Insider.deps.json", + "tools/netcoreapp2.1/GetDocument.Insider.dll", + "tools/netcoreapp2.1/GetDocument.Insider.runtimeconfig.json", + "tools/netcoreapp2.1/Microsoft.OpenApi.dll", + "tools/netcoreapp2.1/System.Diagnostics.DiagnosticSource.dll" + ] + }, "Microsoft.Extensions.Caching.Abstractions/9.0.9": { "sha512": "NgtRHOdPrAEacfjXLSrH/SRrSqGf6Vaa6d16mW2yoyJdg7AJr0BnBvxkv7PkCm/CHVyzojTK7Y+oUDEulqY1Qw==", "type": "package", @@ -2337,6 +2935,163 @@ "useSharedDesignerContext.txt" ] }, + "Microsoft.IdentityModel.Abstractions/8.14.0": { + "sha512": "iwbCpSjD3ehfTwBhtSNEtKPK0ICun6ov7Ibx6ISNA9bfwIyzI2Siwyi9eJFCJBwxowK9xcA1mj+jBWiigeqgcQ==", + "type": "package", + "path": "microsoft.identitymodel.abstractions/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Abstractions.dll", + "lib/net462/Microsoft.IdentityModel.Abstractions.xml", + "lib/net472/Microsoft.IdentityModel.Abstractions.dll", + "lib/net472/Microsoft.IdentityModel.Abstractions.xml", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net6.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net8.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/net9.0/Microsoft.IdentityModel.Abstractions.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.xml", + "microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "microsoft.identitymodel.abstractions.nuspec" + ] + }, + "Microsoft.IdentityModel.JsonWebTokens/8.14.0": { + "sha512": "4jOpiA4THdtpLyMdAb24dtj7+6GmvhOhxf5XHLYWmPKF8ApEnApal1UnJsKO4HxUWRXDA6C4WQVfYyqsRhpNpQ==", + "type": "package", + "path": "microsoft.identitymodel.jsonwebtokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net462/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net472/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.xml", + "microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.jsonwebtokens.nuspec" + ] + }, + "Microsoft.IdentityModel.Logging/8.14.0": { + "sha512": "eqqnemdW38CKZEHS6diA50BV94QICozDZEvSrsvN3SJXUFwVB9gy+/oz76gldP7nZliA16IglXjXTCTdmU/Ejg==", + "type": "package", + "path": "microsoft.identitymodel.logging/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Logging.dll", + "lib/net462/Microsoft.IdentityModel.Logging.xml", + "lib/net472/Microsoft.IdentityModel.Logging.dll", + "lib/net472/Microsoft.IdentityModel.Logging.xml", + "lib/net6.0/Microsoft.IdentityModel.Logging.dll", + "lib/net6.0/Microsoft.IdentityModel.Logging.xml", + "lib/net8.0/Microsoft.IdentityModel.Logging.dll", + "lib/net8.0/Microsoft.IdentityModel.Logging.xml", + "lib/net9.0/Microsoft.IdentityModel.Logging.dll", + "lib/net9.0/Microsoft.IdentityModel.Logging.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Logging.xml", + "microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "microsoft.identitymodel.logging.nuspec" + ] + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "sha512": "uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "type": "package", + "path": "microsoft.identitymodel.protocols/8.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/Microsoft.IdentityModel.Protocols.dll", + "lib/net462/Microsoft.IdentityModel.Protocols.xml", + "lib/net472/Microsoft.IdentityModel.Protocols.dll", + "lib/net472/Microsoft.IdentityModel.Protocols.xml", + "lib/net6.0/Microsoft.IdentityModel.Protocols.dll", + "lib/net6.0/Microsoft.IdentityModel.Protocols.xml", + "lib/net8.0/Microsoft.IdentityModel.Protocols.dll", + "lib/net8.0/Microsoft.IdentityModel.Protocols.xml", + "lib/net9.0/Microsoft.IdentityModel.Protocols.dll", + "lib/net9.0/Microsoft.IdentityModel.Protocols.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.xml", + "microsoft.identitymodel.protocols.8.0.1.nupkg.sha512", + "microsoft.identitymodel.protocols.nuspec" + ] + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "sha512": "AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "type": "package", + "path": "microsoft.identitymodel.protocols.openidconnect/8.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net462/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/net462/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "lib/net472/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/net472/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "lib/net6.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/net6.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "lib/net8.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/net8.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.xml", + "microsoft.identitymodel.protocols.openidconnect.8.0.1.nupkg.sha512", + "microsoft.identitymodel.protocols.openidconnect.nuspec" + ] + }, + "Microsoft.IdentityModel.Tokens/8.14.0": { + "sha512": "lKIZiBiGd36k02TCdMHp1KlNWisyIvQxcYJvIkz7P4gSQ9zi8dgh6S5Grj8NNG7HWYIPfQymGyoZ6JB5d1Lo1g==", + "type": "package", + "path": "microsoft.identitymodel.tokens/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/Microsoft.IdentityModel.Tokens.dll", + "lib/net462/Microsoft.IdentityModel.Tokens.xml", + "lib/net472/Microsoft.IdentityModel.Tokens.dll", + "lib/net472/Microsoft.IdentityModel.Tokens.xml", + "lib/net6.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net6.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net8.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net8.0/Microsoft.IdentityModel.Tokens.xml", + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll", + "lib/net9.0/Microsoft.IdentityModel.Tokens.xml", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll", + "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.xml", + "microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "microsoft.identitymodel.tokens.nuspec" + ] + }, + "Microsoft.OpenApi/1.6.25": { + "sha512": "ZahSqNGtNV7N0JBYS/IYXPkLVexL/AZFxo6pqxv6A7Uli7Q7zfitNjkaqIcsV73Ukzxi4IlJdyDgcQiMXiH8cw==", + "type": "package", + "path": "microsoft.openapi/1.6.25", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/netstandard2.0/Microsoft.OpenApi.dll", + "lib/netstandard2.0/Microsoft.OpenApi.pdb", + "lib/netstandard2.0/Microsoft.OpenApi.xml", + "microsoft.openapi.1.6.25.nupkg.sha512", + "microsoft.openapi.nuspec" + ] + }, "Mono.TextTemplating/3.0.0": { "sha512": "YqueG52R/Xej4VVbKuRIodjiAhV0HR/XVbLbNrJhCZnzjnSjgMJ/dCdV0akQQxavX6hp/LC6rqLGLcXeQYU7XA==", "type": "package", @@ -2386,6 +3141,74 @@ "postgresql.png" ] }, + "Swashbuckle.AspNetCore/9.0.6": { + "sha512": "q/UfEAgrk6qQyjHXgsW9ILw0YZLfmPtWUY4wYijliX6supozC+TkzU0G6FTnn/dPYxnChjM8g8lHjWHF6VKy+A==", + "type": "package", + "path": "swashbuckle.aspnetcore/9.0.6", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "build/Swashbuckle.AspNetCore.props", + "buildMultiTargeting/Swashbuckle.AspNetCore.props", + "docs/package-readme.md", + "swashbuckle.aspnetcore.9.0.6.nupkg.sha512", + "swashbuckle.aspnetcore.nuspec" + ] + }, + "Swashbuckle.AspNetCore.Swagger/9.0.6": { + "sha512": "Bgyc8rWRAYwDrzjVHGbavvNE38G1Dfgf1McHYm+WUr4TxkvEAXv8F8B1z3Kmz4BkDCKv9A/1COa2t7+Ri5+pLg==", + "type": "package", + "path": "swashbuckle.aspnetcore.swagger/9.0.6", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net8.0/Swashbuckle.AspNetCore.Swagger.dll", + "lib/net8.0/Swashbuckle.AspNetCore.Swagger.pdb", + "lib/net8.0/Swashbuckle.AspNetCore.Swagger.xml", + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll", + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.pdb", + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.xml", + "package-readme.md", + "swashbuckle.aspnetcore.swagger.9.0.6.nupkg.sha512", + "swashbuckle.aspnetcore.swagger.nuspec" + ] + }, + "Swashbuckle.AspNetCore.SwaggerGen/9.0.6": { + "sha512": "yYrDs5qpIa4UXP+a02X0ZLQs6HSd1C8t6hF6J1fnxoawi3PslJg1yUpLBS89HCbrDACzmwEGG25il+8aa0zdnw==", + "type": "package", + "path": "swashbuckle.aspnetcore.swaggergen/9.0.6", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerGen.pdb", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerGen.xml", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.pdb", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.xml", + "package-readme.md", + "swashbuckle.aspnetcore.swaggergen.9.0.6.nupkg.sha512", + "swashbuckle.aspnetcore.swaggergen.nuspec" + ] + }, + "Swashbuckle.AspNetCore.SwaggerUI/9.0.6": { + "sha512": "WGsw/Yop9b16miq8TQd4THxuEgkP5cH3+DX93BrX9m0OdPcKNtg2nNm77WQSAsA+Se+M0bTiu8bUyrruRSeS5g==", + "type": "package", + "path": "swashbuckle.aspnetcore.swaggerui/9.0.6", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerUI.pdb", + "lib/net8.0/Swashbuckle.AspNetCore.SwaggerUI.xml", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.pdb", + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.xml", + "package-readme.md", + "swashbuckle.aspnetcore.swaggerui.9.0.6.nupkg.sha512", + "swashbuckle.aspnetcore.swaggerui.nuspec" + ] + }, "System.CodeDom/6.0.0": { "sha512": "CPc6tWO1LAer3IzfZufDBRL+UZQcj5uS207NHALQzP84Vp/z6wF0Aa0YZImOQY8iStY0A2zI/e3ihKNPfUm8XA==", "type": "package", @@ -2594,6 +3417,30 @@ "useSharedDesignerContext.txt" ] }, + "System.IdentityModel.Tokens.Jwt/8.14.0": { + "sha512": "EYGgN/S+HK7S6F3GaaPLFAfK0UzMrkXFyWCvXpQWFYmZln3dqtbyIO7VuTM/iIIPMzkelg8ZLlBPvMhxj6nOAA==", + "type": "package", + "path": "system.identitymodel.tokens.jwt/8.14.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "README.md", + "lib/net462/System.IdentityModel.Tokens.Jwt.dll", + "lib/net462/System.IdentityModel.Tokens.Jwt.xml", + "lib/net472/System.IdentityModel.Tokens.Jwt.dll", + "lib/net472/System.IdentityModel.Tokens.Jwt.xml", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net6.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net8.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/net9.0/System.IdentityModel.Tokens.Jwt.xml", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll", + "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.xml", + "system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", + "system.identitymodel.tokens.jwt.nuspec" + ] + }, "System.IO.Pipelines/7.0.0": { "sha512": "jRn6JYnNPW6xgQazROBLSfpdoczRw694vO5kKvMcNnpXuolEixUyw6IBuBs2Y2mlSX/LdLvyyWmfXhaI3ND1Yg==", "type": "package", @@ -2777,12 +3624,18 @@ }, "projectFileDependencyGroups": { "net9.0": [ + "BCrypt.Net-Next >= 4.0.3", + "FluentValidation.DependencyInjectionExtensions >= 12.0.0", + "Microsoft.AspNetCore.Authentication.JwtBearer >= 9.0.9", "Microsoft.EntityFrameworkCore.Design >= 9.0.9", - "Npgsql.EntityFrameworkCore.PostgreSQL >= 9.0.4" + "Npgsql.EntityFrameworkCore.PostgreSQL >= 9.0.4", + "Swashbuckle.AspNetCore >= 9.0.6", + "System.IdentityModel.Tokens.Jwt >= 8.14.0" ] }, "packageFolders": { - "C:\\Users\\heiye\\.nuget\\packages\\": {} + "C:\\Users\\heiye\\.nuget\\packages\\": {}, + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} }, "project": { "version": "1.0.0", @@ -2793,13 +3646,19 @@ "packagesPath": "C:\\Users\\heiye\\.nuget\\packages\\", "outputPath": "C:\\code\\SimpleTodoApiWithPg\\obj\\", "projectStyle": "PackageReference", + "fallbackFolders": [ + "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" + ], "configFilePaths": [ - "C:\\Users\\heiye\\AppData\\Roaming\\NuGet\\NuGet.Config" + "C:\\Users\\heiye\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" ], "originalTargetFrameworks": [ "net9.0" ], "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { @@ -2824,6 +3683,18 @@ "net9.0": { "targetAlias": "net9.0", "dependencies": { + "BCrypt.Net-Next": { + "target": "Package", + "version": "[4.0.3, )" + }, + "FluentValidation.DependencyInjectionExtensions": { + "target": "Package", + "version": "[12.0.0, )" + }, + "Microsoft.AspNetCore.Authentication.JwtBearer": { + "target": "Package", + "version": "[9.0.9, )" + }, "Microsoft.EntityFrameworkCore.Design": { "include": "Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive", "suppressParent": "All", @@ -2833,6 +3704,14 @@ "Npgsql.EntityFrameworkCore.PostgreSQL": { "target": "Package", "version": "[9.0.4, )" + }, + "Swashbuckle.AspNetCore": { + "target": "Package", + "version": "[9.0.6, )" + }, + "System.IdentityModel.Tokens.Jwt": { + "target": "Package", + "version": "[8.14.0, )" } }, "imports": [ diff --git a/obj/project.nuget.cache b/obj/project.nuget.cache index 4b34690..112009c 100644 --- a/obj/project.nuget.cache +++ b/obj/project.nuget.cache @@ -1,10 +1,14 @@ { "version": 2, - "dgSpecHash": "hQuQRTWDcxc=", + "dgSpecHash": "kIoE/znXMRY=", "success": true, "projectFilePath": "C:\\code\\SimpleTodoApiWithPg\\SimpleTodoApiWithPg.csproj", "expectedPackageFiles": [ + "C:\\Users\\heiye\\.nuget\\packages\\bcrypt.net-next\\4.0.3\\bcrypt.net-next.4.0.3.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\fluentvalidation\\12.0.0\\fluentvalidation.12.0.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\fluentvalidation.dependencyinjectionextensions\\12.0.0\\fluentvalidation.dependencyinjectionextensions.12.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\humanizer.core\\2.14.1\\humanizer.core.2.14.1.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.aspnetcore.authentication.jwtbearer\\9.0.9\\microsoft.aspnetcore.authentication.jwtbearer.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\7.0.0\\microsoft.bcl.asyncinterfaces.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.build.framework\\17.8.3\\microsoft.build.framework.17.8.3.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.build.locator\\1.7.8\\microsoft.build.locator.1.7.8.nupkg.sha512", @@ -19,6 +23,7 @@ "C:\\Users\\heiye\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\9.0.9\\microsoft.entityframeworkcore.analyzers.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.entityframeworkcore.design\\9.0.9\\microsoft.entityframeworkcore.design.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\9.0.9\\microsoft.entityframeworkcore.relational.9.0.9.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.apidescription.server\\9.0.0\\microsoft.extensions.apidescription.server.9.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\9.0.9\\microsoft.extensions.caching.abstractions.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.caching.memory\\9.0.9\\microsoft.extensions.caching.memory.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\9.0.9\\microsoft.extensions.configuration.abstractions.9.0.9.nupkg.sha512", @@ -29,9 +34,20 @@ "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\9.0.9\\microsoft.extensions.logging.abstractions.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.options\\9.0.9\\microsoft.extensions.options.9.0.9.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\microsoft.extensions.primitives\\9.0.9\\microsoft.extensions.primitives.9.0.9.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.abstractions\\8.14.0\\microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\8.14.0\\microsoft.identitymodel.jsonwebtokens.8.14.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.logging\\8.14.0\\microsoft.identitymodel.logging.8.14.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.protocols\\8.0.1\\microsoft.identitymodel.protocols.8.0.1.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.protocols.openidconnect\\8.0.1\\microsoft.identitymodel.protocols.openidconnect.8.0.1.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.identitymodel.tokens\\8.14.0\\microsoft.identitymodel.tokens.8.14.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\microsoft.openapi\\1.6.25\\microsoft.openapi.1.6.25.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\mono.texttemplating\\3.0.0\\mono.texttemplating.3.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\npgsql\\9.0.3\\npgsql.9.0.3.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\npgsql.entityframeworkcore.postgresql\\9.0.4\\npgsql.entityframeworkcore.postgresql.9.0.4.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\swashbuckle.aspnetcore\\9.0.6\\swashbuckle.aspnetcore.9.0.6.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\swashbuckle.aspnetcore.swagger\\9.0.6\\swashbuckle.aspnetcore.swagger.9.0.6.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\swashbuckle.aspnetcore.swaggergen\\9.0.6\\swashbuckle.aspnetcore.swaggergen.9.0.6.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\swashbuckle.aspnetcore.swaggerui\\9.0.6\\swashbuckle.aspnetcore.swaggerui.9.0.6.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.codedom\\6.0.0\\system.codedom.6.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.collections.immutable\\7.0.0\\system.collections.immutable.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.composition\\7.0.0\\system.composition.7.0.0.nupkg.sha512", @@ -40,6 +56,7 @@ "C:\\Users\\heiye\\.nuget\\packages\\system.composition.hosting\\7.0.0\\system.composition.hosting.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.composition.runtime\\7.0.0\\system.composition.runtime.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.composition.typedparts\\7.0.0\\system.composition.typedparts.7.0.0.nupkg.sha512", + "C:\\Users\\heiye\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.14.0\\system.identitymodel.tokens.jwt.8.14.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.io.pipelines\\7.0.0\\system.io.pipelines.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.reflection.metadata\\7.0.0\\system.reflection.metadata.7.0.0.nupkg.sha512", "C:\\Users\\heiye\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
确保您的 ASP.NET Core 应用正在运行,并监听以下基准 URL。