diff --git a/R4MVC.sln b/R4MVC.sln
index af1b52a..4cef50e 100644
--- a/R4MVC.sln
+++ b/R4MVC.sln
@@ -1,98 +1,98 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29318.209
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".solution", ".solution", "{1E8F7AFD-5175-406A-9736-817C75DA1142}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- appveyor.yml = appveyor.yml
- CHANGELOG.md = CHANGELOG.md
- README.md = README.md
- RunGenerate.bat = RunGenerate.bat
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{30626644-0E8A-4610-A0A9-274E91F1A037}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E11DD8FA-FBC7-490C-88B7-15DB073FD903}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc", "src\R4Mvc\R4Mvc.csproj", "{0DF253A4-4093-4299-98A1-D28175DFEE34}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Test", "test\R4Mvc.Test\R4Mvc.Test.csproj", "{CFE51159-0850-415A-BAD0-FBFF607E772F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Tools", "src\R4Mvc.Tools\R4Mvc.Tools.csproj", "{1673B75E-E97D-4770-A1E3-86CF3C50A5E8}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Tools.Cli", "src\R4Mvc.Tools.Cli\R4Mvc.Tools.Cli.csproj", "{5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple", "samples\AspNetSimple\AspNetSimple.csproj", "{D8F18816-A3E6-4A59-8495-D2FC9D8413E2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetFeatureFolders", "samples\AspNetFeatureFolders\AspNetFeatureFolders.csproj", "{86B3FF8A-284E-4070-9120-D343366B18E2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple.Test", "test\AspNetSimple.Test\AspNetSimple.Test.csproj", "{75510011-133B-4A05-AD09-A399CDBFA3A5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleModels", "samples\SampleModels\SampleModels.csproj", "{8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple.NetCore3", "samples\AspNetSimple.NetCore3\AspNetSimple.NetCore3.csproj", "{4609AF1D-0942-43DA-9979-F92972A22A7A}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0DF253A4-4093-4299-98A1-D28175DFEE34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0DF253A4-4093-4299-98A1-D28175DFEE34}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0DF253A4-4093-4299-98A1-D28175DFEE34}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0DF253A4-4093-4299-98A1-D28175DFEE34}.Release|Any CPU.Build.0 = Release|Any CPU
- {CFE51159-0850-415A-BAD0-FBFF607E772F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CFE51159-0850-415A-BAD0-FBFF607E772F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CFE51159-0850-415A-BAD0-FBFF607E772F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CFE51159-0850-415A-BAD0-FBFF607E772F}.Release|Any CPU.Build.0 = Release|Any CPU
- {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Release|Any CPU.Build.0 = Release|Any CPU
- {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Release|Any CPU.Build.0 = Release|Any CPU
- {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Release|Any CPU.Build.0 = Release|Any CPU
- {86B3FF8A-284E-4070-9120-D343366B18E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {86B3FF8A-284E-4070-9120-D343366B18E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {86B3FF8A-284E-4070-9120-D343366B18E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {86B3FF8A-284E-4070-9120-D343366B18E2}.Release|Any CPU.Build.0 = Release|Any CPU
- {75510011-133B-4A05-AD09-A399CDBFA3A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {75510011-133B-4A05-AD09-A399CDBFA3A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {75510011-133B-4A05-AD09-A399CDBFA3A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {75510011-133B-4A05-AD09-A399CDBFA3A5}.Release|Any CPU.Build.0 = Release|Any CPU
- {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Release|Any CPU.Build.0 = Release|Any CPU
- {4609AF1D-0942-43DA-9979-F92972A22A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4609AF1D-0942-43DA-9979-F92972A22A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4609AF1D-0942-43DA-9979-F92972A22A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4609AF1D-0942-43DA-9979-F92972A22A7A}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {0DF253A4-4093-4299-98A1-D28175DFEE34} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
- {CFE51159-0850-415A-BAD0-FBFF607E772F} = {30626644-0E8A-4610-A0A9-274E91F1A037}
- {1673B75E-E97D-4770-A1E3-86CF3C50A5E8} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
- {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
- {D8F18816-A3E6-4A59-8495-D2FC9D8413E2} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
- {86B3FF8A-284E-4070-9120-D343366B18E2} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
- {75510011-133B-4A05-AD09-A399CDBFA3A5} = {30626644-0E8A-4610-A0A9-274E91F1A037}
- {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
- {4609AF1D-0942-43DA-9979-F92972A22A7A} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {B90C19F2-2B5E-42AD-AE1D-27AD17E4DDB4}
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32112.339
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "statscontr", "statscontr", "{1E8F7AFD-5175-406A-9736-817C75DA1142}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ appveyor.yml = appveyor.yml
+ CHANGELOG.md = CHANGELOG.md
+ README.md = README.md
+ RunGenerate.bat = RunGenerate.bat
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{30626644-0E8A-4610-A0A9-274E91F1A037}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E11DD8FA-FBC7-490C-88B7-15DB073FD903}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc", "src\R4Mvc\R4Mvc.csproj", "{0DF253A4-4093-4299-98A1-D28175DFEE34}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Test", "test\R4Mvc.Test\R4Mvc.Test.csproj", "{CFE51159-0850-415A-BAD0-FBFF607E772F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Tools", "src\R4Mvc.Tools\R4Mvc.Tools.csproj", "{1673B75E-E97D-4770-A1E3-86CF3C50A5E8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R4Mvc.Tools.Cli", "src\R4Mvc.Tools.Cli\R4Mvc.Tools.Cli.csproj", "{5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple", "samples\AspNetSimple\AspNetSimple.csproj", "{D8F18816-A3E6-4A59-8495-D2FC9D8413E2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetFeatureFolders", "samples\AspNetFeatureFolders\AspNetFeatureFolders.csproj", "{86B3FF8A-284E-4070-9120-D343366B18E2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple.Test", "test\AspNetSimple.Test\AspNetSimple.Test.csproj", "{75510011-133B-4A05-AD09-A399CDBFA3A5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleModels", "samples\SampleModels\SampleModels.csproj", "{8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetSimple.NetCore3", "samples\AspNetSimple.NetCore3\AspNetSimple.NetCore3.csproj", "{4609AF1D-0942-43DA-9979-F92972A22A7A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0DF253A4-4093-4299-98A1-D28175DFEE34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0DF253A4-4093-4299-98A1-D28175DFEE34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0DF253A4-4093-4299-98A1-D28175DFEE34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0DF253A4-4093-4299-98A1-D28175DFEE34}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CFE51159-0850-415A-BAD0-FBFF607E772F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CFE51159-0850-415A-BAD0-FBFF607E772F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CFE51159-0850-415A-BAD0-FBFF607E772F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CFE51159-0850-415A-BAD0-FBFF607E772F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1673B75E-E97D-4770-A1E3-86CF3C50A5E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8F18816-A3E6-4A59-8495-D2FC9D8413E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86B3FF8A-284E-4070-9120-D343366B18E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86B3FF8A-284E-4070-9120-D343366B18E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86B3FF8A-284E-4070-9120-D343366B18E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86B3FF8A-284E-4070-9120-D343366B18E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75510011-133B-4A05-AD09-A399CDBFA3A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75510011-133B-4A05-AD09-A399CDBFA3A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75510011-133B-4A05-AD09-A399CDBFA3A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75510011-133B-4A05-AD09-A399CDBFA3A5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4609AF1D-0942-43DA-9979-F92972A22A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4609AF1D-0942-43DA-9979-F92972A22A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4609AF1D-0942-43DA-9979-F92972A22A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4609AF1D-0942-43DA-9979-F92972A22A7A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {0DF253A4-4093-4299-98A1-D28175DFEE34} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
+ {CFE51159-0850-415A-BAD0-FBFF607E772F} = {30626644-0E8A-4610-A0A9-274E91F1A037}
+ {1673B75E-E97D-4770-A1E3-86CF3C50A5E8} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
+ {5AB61036-8938-4F03-84BD-BB5D2D8F4CDA} = {E11DD8FA-FBC7-490C-88B7-15DB073FD903}
+ {D8F18816-A3E6-4A59-8495-D2FC9D8413E2} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
+ {86B3FF8A-284E-4070-9120-D343366B18E2} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
+ {75510011-133B-4A05-AD09-A399CDBFA3A5} = {30626644-0E8A-4610-A0A9-274E91F1A037}
+ {8F6D7DDE-98A0-4808-BD91-C1CF2E0AAC69} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
+ {4609AF1D-0942-43DA-9979-F92972A22A7A} = {B9FF7D5E-784B-4C4A-B6E6-286C1E3D131E}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B90C19F2-2B5E-42AD-AE1D-27AD17E4DDB4}
+ EndGlobalSection
+EndGlobal
diff --git a/samples/AspNetFeatureFolders/AspNetFeatureFolders.csproj b/samples/AspNetFeatureFolders/AspNetFeatureFolders.csproj
index ed9cefe..c916a5c 100644
--- a/samples/AspNetFeatureFolders/AspNetFeatureFolders.csproj
+++ b/samples/AspNetFeatureFolders/AspNetFeatureFolders.csproj
@@ -1,7 +1,7 @@

- netcoreapp2.2
+ net5.0
false
diff --git a/samples/AspNetSimple.NetCore3/AspNetSimple.NetCore3.csproj b/samples/AspNetSimple.NetCore3/AspNetSimple.NetCore3.csproj
index bdf771d..f423110 100644
--- a/samples/AspNetSimple.NetCore3/AspNetSimple.NetCore3.csproj
+++ b/samples/AspNetSimple.NetCore3/AspNetSimple.NetCore3.csproj
@@ -2,7 +2,7 @@
false
- netcoreapp3.0
+ net5.0
diff --git a/samples/AspNetSimple.NetCore3/Properties/launchSettings.json b/samples/AspNetSimple.NetCore3/Properties/launchSettings.json
index 3618566..e2ea6c8 100644
--- a/samples/AspNetSimple.NetCore3/Properties/launchSettings.json
+++ b/samples/AspNetSimple.NetCore3/Properties/launchSettings.json
@@ -1,27 +1,27 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:51657",
- "sslPort": 44349
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "AspNetSimple.NetCore3": {
- "commandName": "Project",
- "launchBrowser": true,
- "applicationUrl": "https://localhost:5001;http://localhost:5000",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:57289/",
+ "sslPort": 44318
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "AspNetSimple.NetCore3": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000"
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/AspNetSimple/AspNetSimple.csproj b/samples/AspNetSimple/AspNetSimple.csproj
index 6cbae00..41d6674 100644
--- a/samples/AspNetSimple/AspNetSimple.csproj
+++ b/samples/AspNetSimple/AspNetSimple.csproj
@@ -5,22 +5,22 @@
- net462;netcoreapp2.2
+ net472;net5.0
- netcoreapp2.2
+ net5.0
-
+
-
+
-
+
@@ -29,4 +29,8 @@
+
+
+
+
diff --git a/samples/AspNetSimple/Properties/launchSettings.json b/samples/AspNetSimple/Properties/launchSettings.json
index 84edee4..5a6c5b4 100644
--- a/samples/AspNetSimple/Properties/launchSettings.json
+++ b/samples/AspNetSimple/Properties/launchSettings.json
@@ -1,27 +1,27 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:53433/",
- "sslPort": 0
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "AspNetSimple": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "http://localhost:53434/"
- }
- }
-}
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:61506/",
+ "sslPort": 44323
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "AspNetSimple": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "http://localhost:53434/"
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/SharedViews/Shared/LinkedView.cshtml b/samples/SharedViews/Shared/LinkedView.cshtml
new file mode 100644
index 0000000..545d1fd
--- /dev/null
+++ b/samples/SharedViews/Shared/LinkedView.cshtml
@@ -0,0 +1 @@
+This view came from a linked location!
\ No newline at end of file
diff --git a/src/R4Mvc.Tools.Cli/R4Mvc.Tools.Cli.csproj b/src/R4Mvc.Tools.Cli/R4Mvc.Tools.Cli.csproj
index 97a2f0f..e51eb18 100644
--- a/src/R4Mvc.Tools.Cli/R4Mvc.Tools.Cli.csproj
+++ b/src/R4Mvc.Tools.Cli/R4Mvc.Tools.Cli.csproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp2.1
+ net5.0
r4mvc
tools
true
@@ -21,9 +21,9 @@
1.0.0
$(VersionPrefix).$(BuildNumber)
-+ First version of the dotnet cli wrapper around R4Mvc.Tools
-+ New and improved command line parser
-+ Improved VS Instance selector for better build reliability
+ + First version of the dotnet cli wrapper around R4Mvc.Tools
+ + New and improved command line parser
+ + Improved VS Instance selector for better build reliability
@@ -32,7 +32,7 @@
-
+
diff --git a/src/R4Mvc.Tools/Commands/GenerateCommand.cs b/src/R4Mvc.Tools/Commands/GenerateCommand.cs
index 70c005b..dddf0dd 100644
--- a/src/R4Mvc.Tools/Commands/GenerateCommand.cs
+++ b/src/R4Mvc.Tools/Commands/GenerateCommand.cs
@@ -4,11 +4,14 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.Extensions.Configuration;
+
using Newtonsoft.Json;
+
using R4Mvc.Tools.CodeGen;
using R4Mvc.Tools.Commands.Core;
using R4Mvc.Tools.Extensions;
@@ -70,6 +73,7 @@ public async Task Run(string projectPath, IConfiguration configuration, string[]
Console.WriteLine("Loading project ...");
var projectRoot = Path.GetDirectoryName(projectPath);
var project = await workspace.OpenProjectAsync(projectPath);
+#if !IGNORE_MSBUILD_DIAGNOSTICS
if (workspace.Diagnostics.Count > 0)
{
var foundErrors = false;
@@ -82,6 +86,7 @@ public async Task Run(string projectPath, IConfiguration configuration, string[]
if (foundErrors)
return;
}
+#endif
// Prep the project Compilation object, and process the Controller public methods list
Console.WriteLine("Compiling project ...");
diff --git a/src/R4Mvc.Tools/Constants.cs b/src/R4Mvc.Tools/Constants.cs
index 41e916e..40cd3a9 100644
--- a/src/R4Mvc.Tools/Constants.cs
+++ b/src/R4Mvc.Tools/Constants.cs
@@ -20,6 +20,8 @@ internal static class Constants
internal const string JsonResultClass = ProjectName + ActionResultNamespace + "JsonResult";
internal const string ContentResultClass = ProjectName + ActionResultNamespace + "ContentResult";
internal const string FileResultClass = ProjectName + ActionResultNamespace + "FileResult";
+ internal const string PartialViewResultClass = ProjectName + ActionResultNamespace + "PartialViewResult";
+ internal const string ViewResultClass = ProjectName + ActionResultNamespace + "ViewResult";
internal const string RedirectResultClass = ProjectName + ActionResultNamespace + "RedirectResult";
internal const string RedirectToActionResultClass = ProjectName + ActionResultNamespace + "RedirectToActionResult";
internal const string RedirectToRouteResultClass = ProjectName + ActionResultNamespace + "RedirectToRouteResult";
@@ -29,6 +31,7 @@ internal static class Constants
internal const string PageJsonResultClass = ProjectName + PageActionResultNamespace + "JsonResult";
internal const string PageContentResultClass = ProjectName + PageActionResultNamespace + "ContentResult";
internal const string PageFileResultClass = ProjectName + PageActionResultNamespace + "FileResult";
+ internal const string PagePartialViewResultClass = ProjectName + PageActionResultNamespace + "PartialViewResult";
internal const string PageRedirectResultClass = ProjectName + PageActionResultNamespace + "RedirectResult";
internal const string PageRedirectToActionResultClass = ProjectName + PageActionResultNamespace + "RedirectToActionResult";
internal const string PageRedirectToRouteResultClass = ProjectName + PageActionResultNamespace + "RedirectToRouteResult";
diff --git a/src/R4Mvc.Tools/Locators/DefaultRazorViewLocator.cs b/src/R4Mvc.Tools/Locators/DefaultRazorViewLocator.cs
index 3a10b3e..c535803 100644
--- a/src/R4Mvc.Tools/Locators/DefaultRazorViewLocator.cs
+++ b/src/R4Mvc.Tools/Locators/DefaultRazorViewLocator.cs
@@ -1,84 +1,86 @@
-using System;
-using System.Collections.Generic;
-using R4Mvc.Tools.Extensions;
-using Path = System.IO.Path;
-
-namespace R4Mvc.Tools.Locators
-{
- public class DefaultRazorViewLocator : IViewLocator
- {
- protected const string ViewsFolder = "Views";
- protected const string AreasFolder = "Areas";
-
- private readonly IFileLocator _fileLocator;
- private readonly Settings _settings;
-
- public DefaultRazorViewLocator(IFileLocator fileLocator, Settings settings)
- {
- _fileLocator = fileLocator;
- _settings = settings;
- }
-
- protected virtual string GetViewsRoot(string projectRoot) => Path.Combine(projectRoot, ViewsFolder);
- protected virtual string GetAreaViewsRoot(string areaRoot, string areaName) => Path.Combine(areaRoot, ViewsFolder);
-
- public virtual IEnumerable Find(string projectRoot)
- {
- foreach (var (Area, Controller, Path) in FindControllerViewFolders(projectRoot))
- {
- if (!_fileLocator.DirectoryExists(Path))
- continue;
- foreach (var view in FindViews(projectRoot, Area, Controller, Path))
- yield return view;
- }
- }
-
- protected IEnumerable<(string Area, string Controller, string Path)> FindControllerViewFolders(string projectRoot)
- {
- var viewsRoot = GetViewsRoot(projectRoot);
- if (_fileLocator.DirectoryExists(viewsRoot))
- foreach (var controllerPath in _fileLocator.GetDirectories(viewsRoot))
- {
- var controllerName = Path.GetFileName(controllerPath);
- yield return (string.Empty, controllerName, controllerPath);
- }
-
- var areasPath = Path.Combine(projectRoot, AreasFolder);
- if (_fileLocator.DirectoryExists(areasPath))
- foreach (var areaRoot in _fileLocator.GetDirectories(areasPath))
- {
- var areaName = Path.GetFileName(areaRoot);
- viewsRoot = GetAreaViewsRoot(areaRoot, areaName);
- if (_fileLocator.DirectoryExists(viewsRoot))
- foreach (var controllerPath in _fileLocator.GetDirectories(viewsRoot))
- {
- var controllerName = Path.GetFileName(controllerPath);
- yield return (areaName, controllerName, controllerPath);
- }
- }
- }
-
- protected virtual IEnumerable FindViews(string projectRoot, string areaName, string controllerName, string controllerPath)
- {
- foreach (var file in _fileLocator.GetFiles(controllerPath, "*.cshtml"))
- {
- yield return GetView(projectRoot, file, controllerName, areaName);
- }
-
- foreach (var directory in _fileLocator.GetDirectories(controllerPath))
- {
- foreach (var file in _fileLocator.GetFiles(directory, "*.cshtml"))
- {
- yield return GetView(projectRoot, file, controllerName, areaName, Path.GetFileName(directory));
- }
- }
- }
-
- private View GetView(string projectRoot, string filePath, string controllerName, string areaName, string templateKind = null)
- {
- var relativePath = new Uri("~" + filePath.GetRelativePath(projectRoot).Replace("\\", "/"), UriKind.Relative);
- var templateKindSegment = templateKind != null ? templateKind + "/" : null;
- return new View(areaName, controllerName, Path.GetFileNameWithoutExtension(filePath), relativePath, templateKind);
- }
- }
-}
+using System;
+using System.Collections.Generic;
+
+using R4Mvc.Tools.Extensions;
+
+using Path = System.IO.Path;
+
+namespace R4Mvc.Tools.Locators
+{
+ public class DefaultRazorViewLocator : IViewLocator
+ {
+ protected const string ViewsFolder = "Views";
+ protected const string AreasFolder = "Areas";
+
+ private readonly IFileLocator _fileLocator;
+ private readonly Settings _settings;
+
+ public DefaultRazorViewLocator(IFileLocator fileLocator, Settings settings)
+ {
+ _fileLocator = fileLocator;
+ _settings = settings;
+ }
+
+ protected virtual string GetViewsRoot(string projectRoot) => Path.Combine(projectRoot, ViewsFolder);
+ protected virtual string GetAreaViewsRoot(string areaRoot, string areaName) => Path.Combine(areaRoot, ViewsFolder);
+
+ public virtual IEnumerable Find(string projectRoot)
+ {
+ foreach (var (Area, Controller, Path) in FindControllerViewFolders(projectRoot))
+ {
+ if (!_fileLocator.DirectoryExists(Path))
+ continue;
+ foreach (var view in FindViews(projectRoot, Area, Controller, Path))
+ yield return view;
+ }
+ }
+
+ protected IEnumerable<(string Area, string Controller, string Path)> FindControllerViewFolders(string projectRoot)
+ {
+ var viewsRoot = GetViewsRoot(projectRoot);
+ if (_fileLocator.DirectoryExists(viewsRoot))
+ foreach (var controllerPath in _fileLocator.GetDirectories(viewsRoot))
+ {
+ var controllerName = Path.GetFileName(controllerPath);
+ yield return (string.Empty, controllerName, controllerPath);
+ }
+
+ var areasPath = Path.Combine(projectRoot, AreasFolder);
+ if (_fileLocator.DirectoryExists(areasPath))
+ foreach (var areaRoot in _fileLocator.GetDirectories(areasPath))
+ {
+ var areaName = Path.GetFileName(areaRoot);
+ viewsRoot = GetAreaViewsRoot(areaRoot, areaName);
+ if (_fileLocator.DirectoryExists(viewsRoot))
+ foreach (var controllerPath in _fileLocator.GetDirectories(viewsRoot))
+ {
+ var controllerName = Path.GetFileName(controllerPath);
+ yield return (areaName, controllerName, controllerPath);
+ }
+ }
+ }
+
+ protected virtual IEnumerable FindViews(string projectRoot, string areaName, string controllerName, string controllerPath)
+ {
+ foreach (var file in _fileLocator.GetFiles(controllerPath, "*.cshtml"))
+ {
+ yield return GetView(projectRoot, file, controllerName, areaName);
+ }
+
+ foreach (var directory in _fileLocator.GetDirectories(controllerPath))
+ {
+ foreach (var file in _fileLocator.GetFiles(directory, "*.cshtml"))
+ {
+ yield return GetView(projectRoot, file, controllerName, areaName, Path.GetFileName(directory));
+ }
+ }
+ }
+
+ private View GetView(string projectRoot, string filePath, string controllerName, string areaName, string templateKind = null)
+ {
+ var relativePath = new Uri(("/" + filePath.GetRelativePath(projectRoot).Replace("\\", "/")).Replace("//", "/"), UriKind.Relative);
+ var templateKindSegment = templateKind != null ? templateKind + "/" : null;
+ return new View(areaName, controllerName, Path.GetFileNameWithoutExtension(filePath), relativePath, templateKind);
+ }
+ }
+}
diff --git a/src/R4Mvc.Tools/Locators/LinkedRazorViewLocator.cs b/src/R4Mvc.Tools/Locators/LinkedRazorViewLocator.cs
new file mode 100644
index 0000000..0f2b657
--- /dev/null
+++ b/src/R4Mvc.Tools/Locators/LinkedRazorViewLocator.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+
+namespace R4Mvc.Tools.Locators
+{
+ public class LinkedRazorViewLocator : DefaultRazorViewLocator
+ {
+ public LinkedRazorViewLocator(IFileLocator fileLocator, Settings settings) : base(fileLocator, settings)
+ {
+ }
+
+ public override IEnumerable Find(string projectRoot)
+ {
+ var csProject = Directory.EnumerateFiles(projectRoot, "*.csproj").SingleOrDefault();
+
+ if (csProject != null)
+ {
+ var xdoc = XDocument.Load(csProject);
+ var xmlNode = xdoc.Descendants("Content").Where(x => x.HasAttributes && x.Attribute("LinkBase") != null && x.Attribute("LinkBase").Value == ViewsFolder).SingleOrDefault();
+ if (xmlNode != null)
+ {
+ var includeFolder = xmlNode.Attribute("Include").Value.Replace("*", "").Replace("\\Views\\", "");
+ var newFolder = Path.GetFullPath(Path.Combine(projectRoot, includeFolder));
+ return base.Find(newFolder);
+ }
+ }
+ return new List();
+ }
+ }
+}
diff --git a/src/R4Mvc.Tools/Program.cs b/src/R4Mvc.Tools/Program.cs
index d51c40f..794248a 100644
--- a/src/R4Mvc.Tools/Program.cs
+++ b/src/R4Mvc.Tools/Program.cs
@@ -1,181 +1,184 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
-using R4Mvc.Tools.Commands;
-using R4Mvc.Tools.Commands.Core;
-using R4Mvc.Tools.Locators;
-using R4Mvc.Tools.Services;
-
-namespace R4Mvc.Tools
-{
- class Program
- {
- static async Task Main(string[] args)
- {
- Console.WriteLine($" R4Mvc Generator Tool v{GetVersion()}");
- Console.WriteLine();
-
- var commandLineConfig = BuildCommandLineConfig(ref args);
-
- var commands = CommandResolver.GetCommands();
- ICommand command = null;
- if (args.Length > 0)
- {
- command = commands.FirstOrDefault(c => c.Key.Equals(args[0], StringComparison.OrdinalIgnoreCase));
- if (command != null)
- RemoveItem(ref args, 0);
- }
- if (command == null)
- command = commands.OfType().First();
-
- string projectPath = null;
- if (!command.IsGlobal)
- {
- projectPath = GetProjectPath(commandLineConfig);
- if (projectPath == null)
- return;
- }
- var configuration = LoadConfiguration(projectPath, commandLineConfig);
-
- var services = new ServiceCollection();
- ConfigureServices(services, configuration);
-
- var serviceProvider = services.BuildServiceProvider();
-
- var commandRunner = serviceProvider.GetService(command.GetCommandType()) as ICommandRunner;
- await commandRunner.Run(projectPath, configuration, args);
- }
-
- internal static string GetVersion()
- {
- var assembly = typeof(Program).Assembly;
- var version = assembly.GetCustomAttribute()?.InformationalVersion;
- if (version == null)
- version = assembly.GetName().Version.ToString();
- return version;
- }
-
- static IConfigurationSource BuildCommandLineConfig(ref string[] args)
- {
- if (args.Length == 0)
- return null;
-
- var triggers = new[] { "-", "--", "/" };
- var commandArgs = new List();
- int i = 0;
- bool usingSpace = !args.Any(a => triggers.Any(s => a.StartsWith(s)) && a.Contains("="));
- while (i < args.Length)
- {
- var arg = args[i];
- var trigger = triggers.FirstOrDefault(s => arg.StartsWith(s));
- if (trigger == null)
- {
- i++;
- continue;
- }
-
- commandArgs.Add(args[i]);
- RemoveItem(ref args, i);
-
- if (usingSpace)
- {
- commandArgs.Add(args[i]);
- RemoveItem(ref args, i);
- }
- }
-
- return new ConfigurationBuilder()
- .AddCommandLine(commandArgs.ToArray(), new Dictionary
- {
- ["-p"] = "ProjectPath",
- ["-vsi"] = "vsinstance",
- })
- .Sources[0];
- }
-
- static void RemoveItem(ref string[] args, int index)
- {
- for (int i = index; i + 1 < args.Length; i++)
- args[i] = args[i + 1];
- Array.Resize(ref args, args.Length - 1);
- }
-
- static string GetProjectPath(IConfigurationSource configuration)
- {
- var config = new ConfigurationBuilder().Add(configuration).Build();
- var projectPath = config["ProjectPath"];
- if (string.IsNullOrWhiteSpace(projectPath))
- projectPath = Environment.CurrentDirectory;
- projectPath = Path.GetFullPath(projectPath);
-
- if (projectPath.EndsWith(".csproj") && File.Exists(projectPath))
- return projectPath;
-
- // Not pointing to a project file
- if (File.Exists(projectPath))
- projectPath = Path.GetDirectoryName(projectPath);
-
- if (!Directory.Exists(projectPath))
- {
- Console.Error.WriteLine("Project path doesn't exist");
- return null;
- }
-
- var projFiles = Directory.GetFiles(projectPath, "*.csproj");
- switch (projFiles.Length)
- {
- case 1:
- return projFiles[0];
-
- case 0:
- Console.Error.WriteLine("Project path not found. Pass one as a parameter or run this within the project directory.");
- return null;
-
- default:
- Console.Error.WriteLine("More than one project file found. Aborting, just to be safe!");
- return null;
- }
- }
-
- static IConfigurationRoot LoadConfiguration(string projectPath, IConfigurationSource commandLineConfig)
- {
- IConfigurationBuilder builder = new ConfigurationBuilder();
- if (projectPath != null)
- builder = builder.AddJsonFile(Path.Combine(Path.GetDirectoryName(projectPath), Constants.R4MvcSettingsFileName), optional: true);
- if (commandLineConfig != null)
- builder = builder.Add(commandLineConfig);
-
- return builder.Build();
- }
-
- static void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
- {
- services.AddOptions();
- services.Configure(configuration);
- services.AddTransient(sc => sc.GetService>().Value);
-
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
-
- foreach (var runnerType in CommandResolver.GetCommandRunnerTypes())
- services.AddTransient(runnerType);
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+
+using R4Mvc.Tools.Commands;
+using R4Mvc.Tools.Commands.Core;
+using R4Mvc.Tools.Locators;
+using R4Mvc.Tools.Services;
+
+namespace R4Mvc.Tools
+{
+ class Program
+ {
+ static async Task Main(string[] args)
+ {
+ Console.WriteLine($" R4Mvc Generator Tool v{GetVersion()}");
+ Console.WriteLine();
+
+ var commandLineConfig = BuildCommandLineConfig(ref args);
+
+ var commands = CommandResolver.GetCommands();
+ ICommand command = null;
+ if (args.Length > 0)
+ {
+ command = commands.FirstOrDefault(c => c.Key.Equals(args[0], StringComparison.OrdinalIgnoreCase));
+ if (command != null)
+ RemoveItem(ref args, 0);
+ }
+ if (command == null)
+ command = commands.OfType().First();
+
+ string projectPath = null;
+ if (!command.IsGlobal)
+ {
+ projectPath = GetProjectPath(commandLineConfig);
+ if (projectPath == null)
+ return;
+ }
+ var configuration = LoadConfiguration(projectPath, commandLineConfig);
+
+ var services = new ServiceCollection();
+ ConfigureServices(services, configuration);
+
+ var serviceProvider = services.BuildServiceProvider();
+
+ var commandRunner = serviceProvider.GetService(command.GetCommandType()) as ICommandRunner;
+ await commandRunner.Run(projectPath, configuration, args);
+ }
+
+ internal static string GetVersion()
+ {
+ var assembly = typeof(Program).Assembly;
+ var version = assembly.GetCustomAttribute()?.InformationalVersion;
+ if (version == null)
+ version = assembly.GetName().Version.ToString();
+ return version;
+ }
+
+ static IConfigurationSource BuildCommandLineConfig(ref string[] args)
+ {
+ if (args.Length == 0)
+ return null;
+
+ var triggers = new[] { "-", "--", "/" };
+ var commandArgs = new List();
+ int i = 0;
+ bool usingSpace = !args.Any(a => triggers.Any(s => a.StartsWith(s)) && a.Contains("="));
+ while (i < args.Length)
+ {
+ var arg = args[i];
+ var trigger = triggers.FirstOrDefault(s => arg.StartsWith(s));
+ if (trigger == null)
+ {
+ i++;
+ continue;
+ }
+
+ commandArgs.Add(args[i]);
+ RemoveItem(ref args, i);
+
+ if (usingSpace)
+ {
+ commandArgs.Add(args[i]);
+ RemoveItem(ref args, i);
+ }
+ }
+
+ return new ConfigurationBuilder()
+ .AddCommandLine(commandArgs.ToArray(), new Dictionary
+ {
+ ["-p"] = "ProjectPath",
+ ["-vsi"] = "vsinstance",
+ })
+ .Sources[0];
+ }
+
+ static void RemoveItem(ref string[] args, int index)
+ {
+ for (int i = index; i + 1 < args.Length; i++)
+ args[i] = args[i + 1];
+ Array.Resize(ref args, args.Length - 1);
+ }
+
+ static string GetProjectPath(IConfigurationSource configuration)
+ {
+ var config = new ConfigurationBuilder().Add(configuration).Build();
+ var projectPath = config["ProjectPath"];
+ if (string.IsNullOrWhiteSpace(projectPath))
+ projectPath = Environment.CurrentDirectory;
+ projectPath = Path.GetFullPath(projectPath);
+
+ if (projectPath.EndsWith(".csproj") && File.Exists(projectPath))
+ return projectPath;
+
+ // Not pointing to a project file
+ if (File.Exists(projectPath))
+ projectPath = Path.GetDirectoryName(projectPath);
+
+ if (!Directory.Exists(projectPath))
+ {
+ Console.Error.WriteLine("Project path doesn't exist");
+ return null;
+ }
+
+ var projFiles = Directory.GetFiles(projectPath, "*.csproj");
+ switch (projFiles.Length)
+ {
+ case 1:
+ return projFiles[0];
+
+ case 0:
+ Console.Error.WriteLine("Project path not found. Pass one as a parameter or run this within the project directory.");
+ return null;
+
+ default:
+ Console.Error.WriteLine("More than one project file found. Aborting, just to be safe!");
+ return null;
+ }
+ }
+
+ static IConfigurationRoot LoadConfiguration(string projectPath, IConfigurationSource commandLineConfig)
+ {
+ IConfigurationBuilder builder = new ConfigurationBuilder();
+ if (projectPath != null)
+ builder = builder.AddJsonFile(Path.Combine(Path.GetDirectoryName(projectPath), Constants.R4MvcSettingsFileName), optional: true);
+ if (commandLineConfig != null)
+ builder = builder.Add(commandLineConfig);
+
+ return builder.Build();
+ }
+
+ static void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
+ {
+ services.AddOptions();
+ services.Configure(configuration);
+ services.AddTransient(sc => sc.GetService>().Value);
+
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+
+ foreach (var runnerType in CommandResolver.GetCommandRunnerTypes())
+ services.AddTransient(runnerType);
+ }
+ }
+}
diff --git a/src/R4Mvc.Tools/Properties/launchSettings.json b/src/R4Mvc.Tools/Properties/launchSettings.json
index a131804..6f37632 100644
--- a/src/R4Mvc.Tools/Properties/launchSettings.json
+++ b/src/R4Mvc.Tools/Properties/launchSettings.json
@@ -1,11 +1,20 @@
-{
- "profiles": {
- "R4Mvc.Tools": {
- "commandName": "Project",
- "commandLineArgs_blank": "",
- "commandLineArgs": "generate -p \"..\\..\\..\\..\\..\\samples\\AspNetSimple.NetCore3\\AspNetSimple.NetCore3.csproj\"",
- "commandLineArgs2": "generate -p \"..\\..\\..\\..\\..\\samples\\AspNetSimple\\AspNetSimple.csproj\"",
- "commandLineArgs_aspNetFeatureFolders": "generate -p \"..\\..\\..\\..\\..\\samples\\AspNetFeatureFolders\\AspNetFeatureFolders.csproj\""
- }
- }
+{
+ "profiles": {
+ "R4Mvc.Tools.BackOffice": {
+ "commandName": "Project",
+ "commandLineArgs": "generate -p \"D:\\ProjetsGit\\OOGarden-Core\\Oog.BackOffice.Core\\Oog.BackOffice.Core.csproj\""
+ },
+ "R4Mvc.Tools.FrontOffice": {
+ "commandName": "Project",
+ "commandLineArgs": "generate -p \"D:\\ProjetsGit\\OOGarden-Core\\Oog.FrontOffice.Core\\Oog.FrontOffice.Core.csproj\""
+ },
+ "R4Mvc.Tools.CustomerArea": {
+ "commandName": "Project",
+ "commandLineArgs": "generate -p \"D:\\ProjetsGit\\OOGarden-Core\\Oog.CustomerArea.Core\\Oog.CustomerArea.Core.csproj\""
+ },
+ "R4Mvc.Tools.GardenTed": {
+ "commandName": "Project",
+ "commandLineArgs": "generate -p \"D:\\ProjetsGit\\OOGarden-Core\\Oog.GardenTed.Core\\Oog.GardenTed.Core.csproj\""
+ }
+ }
}
\ No newline at end of file
diff --git a/src/R4Mvc.Tools/R4Mvc.Tools.csproj b/src/R4Mvc.Tools/R4Mvc.Tools.csproj
index a6a6d67..83492ae 100644
--- a/src/R4Mvc.Tools/R4Mvc.Tools.csproj
+++ b/src/R4Mvc.Tools/R4Mvc.Tools.csproj
@@ -2,7 +2,7 @@
Exe
- net462
+ net472
latest
tools
True
@@ -22,14 +22,23 @@
1.0.0
$(VersionPrefix).$(BuildNumber)
-+ Adding the option to add extra namespaces to generated files
-! Now working with multi-targeted projects (#66)
-+ Now available as a dotnet cli tool (see R4Mvc.Tools.Cli package)
+ + Adding the option to add extra namespaces to generated files
+ ! Now working with multi-targeted projects (#66)
+ + Now available as a dotnet cli tool (see R4Mvc.Tools.Cli package)
true
+ TRACE;NETCOREAPP
+
+
+
+ TRACE;NETCOREAPP;IGNORE_MSBUILD_DIAGNOSTICS
+
+
+
+ TRACE;IGNORE_MSBUILD_DIAGNOSTICS
@@ -49,17 +58,20 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/R4Mvc.Tools/Services/ControllerGeneratorService.cs b/src/R4Mvc.Tools/Services/ControllerGeneratorService.cs
index c7191aa..1439b54 100644
--- a/src/R4Mvc.Tools/Services/ControllerGeneratorService.cs
+++ b/src/R4Mvc.Tools/Services/ControllerGeneratorService.cs
@@ -1,13 +1,16 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using R4Mvc.Tools.CodeGen;
using R4Mvc.Tools.Extensions;
+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static R4Mvc.Tools.Extensions.SyntaxNodeHelpers;
@@ -64,7 +67,7 @@ public ClassDeclarationSyntax GeneratePartialController(ControllerDefinition con
// build controller partial class node
var genControllerClass = new ClassBuilder(controller.Symbol.Name) // public partial {controllerClass}
.WithModifiers(SyntaxKind.PublicKeyword, SyntaxKind.PartialKeyword)
- .WithTypeParameters(controller.Symbol.TypeParameters.Select(tp => tp.Name).ToArray()); // optional
+ .WithTypeParameters(controller.Symbol.TypeParameters.Select(tp => tp.Name).ToArray()); // optional
// add a default constructor if there are some but none are zero length
var gotCustomConstructors = controller.Symbol.Constructors
@@ -322,6 +325,10 @@ private void AddMethodOverrides(ClassBuilder classBuilder, ITypeSymbol mvcSymbol
callInfoType = Constants.RedirectToActionResultClass;
else if (methodReturnType.InheritsFrom())
callInfoType = Constants.RedirectToRouteResultClass;
+ else if (methodReturnType.InheritsFrom())
+ callInfoType = Constants.PartialViewResultClass;
+ else if (methodReturnType.InheritsFrom())
+ callInfoType = Constants.ViewResultClass;
else if (methodReturnType.InheritsFrom())
callInfoType = Constants.ActionResultClass;
else if ((!isTaskResult || isGenericTaskResult) && !methodReturnType.InheritsFrom())
@@ -332,7 +339,7 @@ private void AddMethodOverrides(ClassBuilder classBuilder, ITypeSymbol mvcSymbol
classBuilder
/* [NonAction]
- * partial void {action}Override({ActionResultType} callInfo, [… params]);
+ * partial void {action}Override({ActionResultType} callInfo, [… params]);
*/
.WithMethod(method.Name + overrideMethodSuffix, null, m => m
.WithModifiers(SyntaxKind.PartialKeyword)
@@ -342,7 +349,7 @@ private void AddMethodOverrides(ClassBuilder classBuilder, ITypeSymbol mvcSymbol
.WithParameter(p.Name, p.Type.ToString()))
.WithNoBody())
/* [NonAction]
- * public overrive {ActionResultType} {action}([… params])
+ * public overrive {ActionResultType} {action}([… params])
* {
* var callInfo = new R4Mvc_Microsoft_AspNetCore_Mvc_ActionResult(Area, Name, ActionNames.{Action});
* ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "paramName", paramName);
@@ -385,61 +392,61 @@ public ClassBuilder WithViewsClass(ClassBuilder classBuilder, IEnumerable
/* public class ViewsClass
* {
* [...] */
- classBuilder.WithChildClass("ViewsClass", cb => cb
- .WithModifiers(SyntaxKind.PublicKeyword)
- .WithGeneratedNonUserCodeAttributes()
- // static readonly _ViewNamesClass s_ViewNames = new _ViewNamesClass();
- // public _ViewNamesClass ViewNames => s_ViewNames;
- .WithStaticFieldBackedProperty("ViewNames", ViewNamesClassName, SyntaxKind.PublicKeyword)
- /* public class _ViewNamesClass
- * {
- * public readonly string {view} = "{view}";
- * }
- */
- .WithChildClass(ViewNamesClassName, vnc => vnc
- .WithModifiers(SyntaxKind.PublicKeyword)
- .ForEach(viewFiles.Where(c => c.TemplateKind == null), (vc, v) => vc
- .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))
- .ForEach(viewFiles.Where(c => c.TemplateKind == null), (c, v) => c
- // public readonly string {view} = "~/Views/{controller}/{view}.cshtml";
- .WithStringField(v.Name.SanitiseFieldName(), v.RelativePath.ToString(), SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword))
- .ForEach(viewEditorTemplates.GroupBy(v => v.TemplateKind), (c, g) => c
- // static readonly _DisplayTemplatesClass s_DisplayTemplates = new _DisplayTemplatesClass();
- // public _DisplayTemplatesClass DisplayTemplates => s_DisplayTemplates;
- .WithStaticFieldBackedProperty(g.Key, $"_{g.Key}Class", SyntaxKind.PublicKeyword)
- /* public partial _DisplayTemplatesClass
- * {
- * public readonly string {view} = "{view}";
- * }
- */
- .WithChildClass($"_{g.Key}Class", tc => tc
- .WithModifiers(SyntaxKind.PublicKeyword, SyntaxKind.PartialKeyword)
- .ForEach(g, (tcc, v) => tcc
- .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword))))
- .ForEach(subpathViews.GroupBy(v => v.TemplateKind), (c, g) => c
- // static readonly _{viewFolder}Class s_{viewFolder} = new _{viewFolder}Class();
- // public _{viewFolder}Class {viewFolder} => s_{viewFolder};
- .WithStaticFieldBackedProperty(g.Key, $"_{g.Key}Class", SyntaxKind.PublicKeyword)
- /* public class _{viewFolder}Class
- * {
- * [...] */
- .WithChildClass($"_{g.Key}Class", tc => tc
- .WithModifiers(SyntaxKind.PublicKeyword, SyntaxKind.PartialKeyword)
- // static readonly _ViewNamesClass s_ViewNames = new _ViewNamesClass();
- // public _ViewNamesClass ViewNames => s_ViewNames;
- .WithStaticFieldBackedProperty("ViewNames", ViewNamesClassName, SyntaxKind.PublicKeyword)
- /* public class _ViewNamesClass
- * {
- * public readonly string {view} = "{view}";
- * }
- */
- .WithChildClass(ViewNamesClassName, vnc => vnc
- .WithModifiers(SyntaxKind.PublicKeyword)
- .ForEach(g, (vc, v) => vc
- .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))
- .ForEach(g, (vc, v) => vc
- // public string {view} = "~/Views/{controller}/{viewFolder}/{view}.cshtml";
- .WithStringField(v.Name.SanitiseFieldName(), v.RelativePath.ToString(), SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))));
+ classBuilder.WithChildClass("ViewsClass", cb => cb
+ .WithModifiers(SyntaxKind.PublicKeyword)
+ .WithGeneratedNonUserCodeAttributes()
+ // static readonly _ViewNamesClass s_ViewNames = new _ViewNamesClass();
+ // public _ViewNamesClass ViewNames => s_ViewNames;
+ .WithStaticFieldBackedProperty("ViewNames", ViewNamesClassName, SyntaxKind.PublicKeyword)
+ /* public class _ViewNamesClass
+ * {
+ * public readonly string {view} = "{view}";
+ * }
+ */
+ .WithChildClass(ViewNamesClassName, vnc => vnc
+ .WithModifiers(SyntaxKind.PublicKeyword)
+ .ForEach(viewFiles.Where(c => c.TemplateKind == null), (vc, v) => vc
+ .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))
+ .ForEach(viewFiles.Where(c => c.TemplateKind == null), (c, v) => c
+ // public readonly string {view} = "~/Views/{controller}/{view}.cshtml";
+ .WithStringField(v.Name.SanitiseFieldName(), v.RelativePath.ToString(), SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword))
+ .ForEach(viewEditorTemplates.GroupBy(v => v.TemplateKind), (c, g) => c
+ // static readonly _DisplayTemplatesClass s_DisplayTemplates = new _DisplayTemplatesClass();
+ // public _DisplayTemplatesClass DisplayTemplates => s_DisplayTemplates;
+ .WithStaticFieldBackedProperty(g.Key, $"_{g.Key}Class", SyntaxKind.PublicKeyword)
+ /* public partial _DisplayTemplatesClass
+ * {
+ * public readonly string {view} = "{view}";
+ * }
+ */
+ .WithChildClass($"_{g.Key}Class", tc => tc
+ .WithModifiers(SyntaxKind.PublicKeyword, SyntaxKind.PartialKeyword)
+ .ForEach(g, (tcc, v) => tcc
+ .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword))))
+ .ForEach(subpathViews.GroupBy(v => v.TemplateKind), (c, g) => c
+ // static readonly _{viewFolder}Class s_{viewFolder} = new _{viewFolder}Class();
+ // public _{viewFolder}Class {viewFolder} => s_{viewFolder};
+ .WithStaticFieldBackedProperty(g.Key, $"_{g.Key}Class", SyntaxKind.PublicKeyword)
+ /* public class _{viewFolder}Class
+ * {
+ * [...] */
+ .WithChildClass($"_{g.Key}Class", tc => tc
+ .WithModifiers(SyntaxKind.PublicKeyword, SyntaxKind.PartialKeyword)
+ // static readonly _ViewNamesClass s_ViewNames = new _ViewNamesClass();
+ // public _ViewNamesClass ViewNames => s_ViewNames;
+ .WithStaticFieldBackedProperty("ViewNames", ViewNamesClassName, SyntaxKind.PublicKeyword)
+ /* public class _ViewNamesClass
+ * {
+ * public readonly string {view} = "{view}";
+ * }
+ */
+ .WithChildClass(ViewNamesClassName, vnc => vnc
+ .WithModifiers(SyntaxKind.PublicKeyword)
+ .ForEach(g, (vc, v) => vc
+ .WithStringField(v.Name.SanitiseFieldName(), v.Name, SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))
+ .ForEach(g, (vc, v) => vc
+ // public string {view} = "~/Views/{controller}/{viewFolder}/{view}.cshtml";
+ .WithStringField(v.Name.SanitiseFieldName(), v.RelativePath.ToString(), SyntaxKind.PublicKeyword, SyntaxKind.ReadOnlyKeyword)))));
return classBuilder
.WithStaticFieldBackedProperty("Views", "ViewsClass", SyntaxKind.PublicKeyword);
diff --git a/src/R4Mvc.Tools/Services/ControllerRewriterService.cs b/src/R4Mvc.Tools/Services/ControllerRewriterService.cs
index 1ce4335..51fc018 100644
--- a/src/R4Mvc.Tools/Services/ControllerRewriterService.cs
+++ b/src/R4Mvc.Tools/Services/ControllerRewriterService.cs
@@ -1,9 +1,11 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
+
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using R4Mvc.Tools.Extensions;
namespace R4Mvc.Tools.Services
@@ -27,7 +29,9 @@ public IList RewriteControllers(CSharpCompilation compiler
foreach (var tree in compiler.SyntaxTrees.Where(x => !x.FilePath.EndsWith(".generated.cs")))
{
// if syntaxtree has errors, skip code generation
+#if !IGNORE_MSBUILD_DIAGNOSTICS
if (tree.GetDiagnostics().Any(x => x.Severity == DiagnosticSeverity.Error)) continue;
+#endif
// this first part, finds all the controller classes, modifies them and saves the changes
var controllerRewriter = new ControllerRewriter(compiler);
diff --git a/src/R4Mvc.Tools/Services/PageGeneratorService.cs b/src/R4Mvc.Tools/Services/PageGeneratorService.cs
index dcfacda..e328455 100644
--- a/src/R4Mvc.Tools/Services/PageGeneratorService.cs
+++ b/src/R4Mvc.Tools/Services/PageGeneratorService.cs
@@ -1,14 +1,17 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using R4Mvc.Tools.CodeGen;
using R4Mvc.Tools.Extensions;
+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static R4Mvc.Tools.Extensions.SyntaxNodeHelpers;
diff --git a/src/R4Mvc.Tools/Services/PageRewriterService.cs b/src/R4Mvc.Tools/Services/PageRewriterService.cs
index 35afe86..458d41c 100644
--- a/src/R4Mvc.Tools/Services/PageRewriterService.cs
+++ b/src/R4Mvc.Tools/Services/PageRewriterService.cs
@@ -1,9 +1,11 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
+
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using R4Mvc.Tools.Extensions;
namespace R4Mvc.Tools.Services
@@ -25,7 +27,9 @@ public IList RewritePages(CSharpCompilation compiler)
foreach (var tree in compiler.SyntaxTrees.Where(x => !x.FilePath.EndsWith(".generated.cs")))
{
// if syntaxtree has errors, skip code generation
+#if !IGNORE_MSBUILD_DIAGNOSTICS
if (tree.GetDiagnostics().Any(x => x.Severity == DiagnosticSeverity.Error)) continue;
+#endif
// this first part, finds all the controller classes, modifies them and saves the changes
var controllerRewriter = new PageRewriter(compiler);
diff --git a/src/R4Mvc.Tools/Services/R4MvcGeneratorService.cs b/src/R4Mvc.Tools/Services/R4MvcGeneratorService.cs
index 2e980af..c1927e9 100644
--- a/src/R4Mvc.Tools/Services/R4MvcGeneratorService.cs
+++ b/src/R4Mvc.Tools/Services/R4MvcGeneratorService.cs
@@ -1,11 +1,14 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using R4Mvc.Tools.CodeGen;
using R4Mvc.Tools.Extensions;
+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace R4Mvc.Tools.Services
@@ -119,14 +122,14 @@ public void Generate(string projectRoot, IList controllers
// R4MVC namespace used for the areas and Dummy class
var r4Namespace = NamespaceDeclaration(ParseName(_settings.R4MvcNamespace))
- // add the dummy class uses in the derived controller partial class
- /* [GeneratedCode, DebuggerNonUserCode]
- * public class Dummy
- * {
- * private Dummy() {}
- * public static Dummy Instance = new Dummy();
- * }
- */
+ // add the dummy class uses in the derived controller partial class
+ /* [GeneratedCode, DebuggerNonUserCode]
+ * public class Dummy
+ * {
+ * private Dummy() {}
+ * public static Dummy Instance = new Dummy();
+ * }
+ */
.AddMembers(new ClassBuilder(Constants.DummyClass)
.WithModifiers(SyntaxKind.PublicKeyword)
.WithGeneratedNonUserCodeAttributes()
@@ -183,6 +186,8 @@ public void Generate(string projectRoot, IList controllers
staticFileNode,
R4MvcHelpersClass(),
ActionResultClass(),
+ PartialViewResultClass(),
+ ViewResultClass(),
JsonResultClass(),
ContentResultClass(),
FileResultClass(),
@@ -364,6 +369,12 @@ public ClassDeclarationSyntax R4MvcHelpersClass()
public ClassDeclarationSyntax ActionResultClass()
=> IActionResultDerivedClass(Constants.ActionResultClass, "ActionResult");
+ public ClassDeclarationSyntax PartialViewResultClass()
+ => IActionResultDerivedClass(Constants.PartialViewResultClass, "PartialViewResult");
+
+ public ClassDeclarationSyntax ViewResultClass()
+ => IActionResultDerivedClass(Constants.ViewResultClass, "ViewResult");
+
public ClassDeclarationSyntax JsonResultClass()
=> IActionResultDerivedClass(Constants.JsonResultClass, "JsonResult",
c => c.WithBaseConstructorCall(SimpleLiteral.Null)); // ctor : base(null)
diff --git a/src/R4Mvc/R4Mvc.csproj b/src/R4Mvc/R4Mvc.csproj
index 30d262b..f006c4f 100644
--- a/src/R4Mvc/R4Mvc.csproj
+++ b/src/R4Mvc/R4Mvc.csproj
@@ -1,7 +1,7 @@

- netstandard1.6;netstandard2.0;netcoreapp3.0;net461
+ netstandard2.0;net5.0;net472
true
1701;1702;1591
@@ -21,7 +21,7 @@
Only the major version will ever be updated -->
1.0.0.0
-+ R4MvcExclude attribute now supports actions
+ + R4MvcExclude attribute now supports actions
@@ -40,12 +40,12 @@
-
-
-
+
+
+
-
+
diff --git a/test/AspNetSimple.Test/AspNetSimple.Test.csproj b/test/AspNetSimple.Test/AspNetSimple.Test.csproj
index c33b60c..87259a1 100644
--- a/test/AspNetSimple.Test/AspNetSimple.Test.csproj
+++ b/test/AspNetSimple.Test/AspNetSimple.Test.csproj
@@ -1,15 +1,15 @@

- net462
+ net472
false
-
-
+
+
-
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/test/R4Mvc.Test/R4Mvc.Test.csproj b/test/R4Mvc.Test/R4Mvc.Test.csproj
index 621a26d..cf4396e 100644
--- a/test/R4Mvc.Test/R4Mvc.Test.csproj
+++ b/test/R4Mvc.Test/R4Mvc.Test.csproj
@@ -1,16 +1,16 @@

- net462
+ net472
false
-
-
-
+
+
+
-
+
all
runtime; build; native; contentfiles; analyzers
@@ -24,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/test/R4Mvc.Test/Services/R4MvcGeneratorServiceTests.cs b/test/R4Mvc.Test/Services/R4MvcGeneratorServiceTests.cs
index 6524ea3..1bf8593 100644
--- a/test/R4Mvc.Test/Services/R4MvcGeneratorServiceTests.cs
+++ b/test/R4Mvc.Test/Services/R4MvcGeneratorServiceTests.cs
@@ -1,9 +1,13 @@
using System.Linq;
+
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+
using Moq;
+
using R4Mvc.Tools;
using R4Mvc.Tools.Services;
+
using Xunit;
namespace R4Mvc.Test.Services
@@ -146,6 +150,22 @@ public void ActionResultClass()
AssertIActionResultClass(actionClass, Constants.ActionResultClass, "ActionResult");
}
+ [Fact]
+ public void PartialViewResultClass()
+ {
+ var service = GetGeneratorService();
+ var actionClass = service.PartialViewResultClass();
+ AssertIActionResultClass(actionClass, Constants.PartialViewResultClass, "PartialViewResult");
+ }
+
+ [Fact]
+ public void ViewResultClass()
+ {
+ var service = GetGeneratorService();
+ var actionClass = service.ViewResultClass();
+ AssertIActionResultClass(actionClass, Constants.ViewResultClass, "ViewResult");
+ }
+
[Fact]
public void JsonResultClass()
{