diff --git a/Mvc.NoFun.sln b/Mvc.NoFun.sln
index b80ac4f973..8f0b0be730 100644
--- a/Mvc.NoFun.sln
+++ b/Mvc.NoFun.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.24711.0
+VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@@ -99,6 +99,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LocalizationSample.Web", "s
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ActionConstraintSample.Web", "samples\ActionConstraintSample.Web\ActionConstraintSample.Web.xproj", "{EE0BD773-4D47-4AA8-8472-5A938A3953BA}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcSubAreaSample.Web", "samples\MvcSubAreaSample.Web\MvcSubAreaSample.Web.xproj", "{E1D45BAF-3967-4D81-9217-22AA54941BF5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -591,6 +593,18 @@ Global
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.ActiveCfg = Release|Any CPU
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.Build.0 = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|x86.Build.0 = Debug|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|x86.ActiveCfg = Release|Any CPU
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -638,5 +652,6 @@ Global
{DAB1252D-577C-4912-98BE-1A812BF83F86} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
{FCFE6024-2720-49B4-8257-9DBC6114F0F1} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
{EE0BD773-4D47-4AA8-8472-5A938A3953BA} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
+ {E1D45BAF-3967-4D81-9217-22AA54941BF5} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
EndGlobalSection
EndGlobal
diff --git a/Mvc.sln b/Mvc.sln
index 9f16b7fa6a..75e3487319 100644
--- a/Mvc.sln
+++ b/Mvc.sln
@@ -144,6 +144,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SimpleWebSite", "test\WebSi
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InlineConstraintSample.Web", "samples\InlineConstraintSample.Web\InlineConstraintSample.Web.xproj", "{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcSubAreaSample.Web", "samples\MvcSubAreaSample.Web\MvcSubAreaSample.Web.xproj", "{45F6B3B6-D114-4D77-84D6-561B3957F341}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -865,6 +867,18 @@ Global
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Release|x86.ActiveCfg = Release|Any CPU
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE}.Release|x86.Build.0 = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|x86.Build.0 = Debug|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|x86.ActiveCfg = Release|Any CPU
+ {45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -935,5 +949,6 @@ Global
{EE0BD773-4D47-4AA8-8472-5A938A3953BA} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
{396B40D7-AC70-49A7-B33C-ED42129FEBE3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{EA34877F-1AC1-42B7-B4E6-15A093F40CAE} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
+ {45F6B3B6-D114-4D77-84D6-561B3957F341} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
EndGlobalSection
EndGlobal
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Controllers/HomeController.cs b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Controllers/HomeController.cs
new file mode 100644
index 0000000000..4c336d3e86
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Controllers/HomeController.cs
@@ -0,0 +1,18 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc;
+
+namespace MvcSubAreaSample.Web.Restaurant.Hours
+{
+ [Area("Restaurant")]
+ [SubArea("Hours")]
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Views/Home/Index.cshtml b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..3412f2b92a
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Hours/Views/Home/Index.cshtml
@@ -0,0 +1,11 @@
+@{
+ Layout = "/Views/Shared/_Layout.cshtml";
+ ViewData["Title"] = "Home Page";
+}
+
+
\ No newline at end of file
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Controllers/HomeController.cs b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Controllers/HomeController.cs
new file mode 100644
index 0000000000..a737852c59
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Controllers/HomeController.cs
@@ -0,0 +1,18 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc;
+
+namespace MvcSubAreaSample.Web.Restaurant.Menu
+{
+ [Area("Restaurant")]
+ [SubArea("Menu")]
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Views/Home/Index.cshtml b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..86eecd2707
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Areas/Menu/Views/Home/Index.cshtml
@@ -0,0 +1,12 @@
+@{
+ ViewData["Title"] = "Home Page";
+ Layout = "/Views/Shared/_Layout.cshtml";
+}
+
+
\ No newline at end of file
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Controllers/HomeController.cs b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Controllers/HomeController.cs
new file mode 100644
index 0000000000..134b0b14f9
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Controllers/HomeController.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc;
+
+namespace MvcSubAreaSample.Web.Restaurant
+{
+ [Area("Restaurant")]
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/Areas/Restaurant/Views/Home/Index.cshtml b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..1ba98d3563
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Areas/Restaurant/Views/Home/Index.cshtml
@@ -0,0 +1,15 @@
+@addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers
+@{
+ Layout = "/Views/Shared/_Layout.cshtml";
+ ViewData["Title"] = "Home Page";
+}
+
+
diff --git a/samples/MvcSubAreaSample.Web/Controllers/HomeController.cs b/samples/MvcSubAreaSample.Web/Controllers/HomeController.cs
new file mode 100644
index 0000000000..4f3934a413
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Controllers/HomeController.cs
@@ -0,0 +1,34 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc;
+
+namespace MvcSubAreaSample.Web
+{
+ public class HomeController : Controller
+ {
+ public IActionResult Index()
+ {
+ return View();
+ }
+
+ public IActionResult About()
+ {
+ ViewData["Message"] = "Your application description page.";
+
+ return View();
+ }
+
+ public IActionResult Contact()
+ {
+ ViewData["Message"] = "Your contact page.";
+
+ return View();
+ }
+
+ public IActionResult Error()
+ {
+ return View("~/Views/Shared/Error.cshtml");
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/Startup.cs b/samples/MvcSubAreaSample.Web/Startup.cs
new file mode 100644
index 0000000000..53b4213be7
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Startup.cs
@@ -0,0 +1,49 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Hosting;
+using Microsoft.AspNet.Mvc.Razor;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace MvcSubAreaSample.Web
+{
+ public class Startup
+ {
+ public IServiceProvider ConfigureServices(IServiceCollection services)
+ {
+ services.Configure(options =>
+ {
+ options.ViewLocationExpanders.Add(new SubAreaViewLocationExpander());
+ });
+
+ services.AddMvc();
+
+ return services.BuildServiceProvider();
+ }
+
+ // Configure is called after ConfigureServices is called.
+ public void Configure(IApplicationBuilder app)
+ {
+ // Add MVC to the request pipeline.
+ app.UseFileServer();
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute("subarearoute", "{area:exists}/{subarea:exists}/{controller=Home}/{action=Index}");
+ routes.MapRoute("areaRoute", "{area:exists}/{controller=Home}/{action=Index}");
+ routes.MapRoute("controllerActionRoute", "{controller=Home}/{action=Index}");
+ });
+ }
+
+ public static void Main(string[] args)
+ {
+ var application = new WebApplicationBuilder()
+ .UseConfiguration(WebApplicationConfiguration.GetDefault(args))
+ .UseStartup()
+ .Build();
+
+ application.Run();
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/SubAreaAttribute.cs b/samples/MvcSubAreaSample.Web/SubAreaAttribute.cs
new file mode 100644
index 0000000000..bc17d7dd90
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/SubAreaAttribute.cs
@@ -0,0 +1,21 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNet.Mvc.Infrastructure;
+
+namespace MvcSubAreaSample.Web
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+ public class SubAreaAttribute : RouteConstraintAttribute
+ {
+ public SubAreaAttribute(string name)
+ : base("subarea", name, blockNonAttributedActions: true)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentException("SubArea name must not be null or empty.", nameof(name));
+ }
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/SubAreaViewLocationExpander.cs b/samples/MvcSubAreaSample.Web/SubAreaViewLocationExpander.cs
new file mode 100644
index 0000000000..c363722dcd
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/SubAreaViewLocationExpander.cs
@@ -0,0 +1,41 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNet.Mvc.Razor;
+
+namespace MvcSubAreaSample.Web
+{
+ public class SubAreaViewLocationExpander : IViewLocationExpander
+ {
+ private const string _subAreaKey = "subarea";
+
+ public IEnumerable ExpandViewLocations(
+ ViewLocationExpanderContext context,
+ IEnumerable viewLocations)
+ {
+ if (context.Values.ContainsKey(_subAreaKey))
+ {
+ var subArea = RazorViewEngine.GetNormalizedRouteValue(context.ActionContext, _subAreaKey);
+ var subareaViewLocations = new string[]
+ {
+ "/Areas/{2}/Areas/" + subArea + "/Views/{1}/{0}.cshtml"
+ };
+ viewLocations = subareaViewLocations.Concat(viewLocations);
+ }
+ return viewLocations;
+ }
+
+ public void PopulateValues(ViewLocationExpanderContext context)
+ {
+ var subArea = context.ActionContext.ActionDescriptor.RouteConstraints.FirstOrDefault(
+ s => s.RouteKey == "subarea" && !string.IsNullOrEmpty(s.RouteValue));
+
+ if (subArea != null)
+ {
+ context.Values[_subAreaKey] = subArea.RouteValue;
+ }
+ }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/Views/Home/Index.cshtml b/samples/MvcSubAreaSample.Web/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..5952b2f556
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Views/Home/Index.cshtml
@@ -0,0 +1,15 @@
+
+@addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers
+@{
+ ViewData["Title"] = "Home Page";
+ Layout = "/Views/Shared/_Layout.cshtml";
+}
+
+
diff --git a/samples/MvcSubAreaSample.Web/Views/Shared/_Layout.cshtml b/samples/MvcSubAreaSample.Web/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000000..9e62cb0568
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/Views/Shared/_Layout.cshtml
@@ -0,0 +1,46 @@
+
+@addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers
+
+
+
+
+ @ViewData["Title"] - MvcSubAreaSample.Web
+
+
+
+
+
+
+
+
+
+
+ @RenderSection("scripts", required: false)
+
+
diff --git a/samples/MvcSubAreaSample.Web/hosting.json b/samples/MvcSubAreaSample.Web/hosting.json
new file mode 100644
index 0000000000..95505372fa
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/hosting.json
@@ -0,0 +1,3 @@
+{
+ "server": "Microsoft.AspNet.Server.Kestrel"
+}
\ No newline at end of file
diff --git a/samples/MvcSubAreaSample.Web/project.json b/samples/MvcSubAreaSample.Web/project.json
new file mode 100644
index 0000000000..d0d1b955cf
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/project.json
@@ -0,0 +1,19 @@
+{
+ "compilationOptions": {
+ "emitEntryPoint": true
+ },
+ "commands": {
+ "web": "MvcSubAreaSample.Web"
+ },
+ "dependencies": {
+ "Microsoft.AspNet.Diagnostics": "1.0.0-*",
+ "Microsoft.AspNet.Mvc": "6.0.0-*",
+ "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-*",
+ "Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
+ "Microsoft.AspNet.StaticFiles": "1.0.0-*"
+ },
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": { }
+ }
+}
diff --git a/samples/MvcSubAreaSample.Web/wwwroot/web.config b/samples/MvcSubAreaSample.Web/wwwroot/web.config
new file mode 100644
index 0000000000..9a0d90abf8
--- /dev/null
+++ b/samples/MvcSubAreaSample.Web/wwwroot/web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/SubAreaTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/SubAreaTests.cs
new file mode 100644
index 0000000000..74597cabeb
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/SubAreaTests.cs
@@ -0,0 +1,56 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.FunctionalTests
+{
+ public class SubAreaTests : IClassFixture>
+ {
+ public SubAreaTests(MvcTestFixture fixture)
+ {
+ Client = fixture.Client;
+ }
+
+ public HttpClient Client { get; }
+
+ [Fact]
+ public async Task SubArea_Menu()
+ {
+ // Arrange & Act
+ var response = await Client.GetAsync("/Restaurant/Menu/Home/Index");
+ var content = await response.Content.ReadAsStringAsync();
+
+ // Assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Contains("Item 1", content);
+ }
+
+ [Fact]
+ public async Task SubArea_Hours()
+ {
+ // Arrange & Act
+ var response = await Client.GetAsync("/Restaurant/Hours/Home/Index");
+ var content = await response.Content.ReadAsStringAsync();
+
+ // Assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Contains("9-5 M-F", content);
+ }
+
+ [Fact]
+ public async Task SubArea_Home()
+ {
+ // Arrange & Act
+ var response = await Client.GetAsync("/");
+ var content = await response.Content.ReadAsStringAsync();
+
+ // Assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Contains("Areas", content);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
index b4a1b69719..daf19955aa 100644
--- a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
@@ -36,6 +36,7 @@
"Microsoft.Extensions.Configuration.Json": "1.0.0-*",
"Microsoft.Extensions.Logging.Testing": "1.0.0-*",
"MvcSandbox": "1.0.0",
+ "MvcSubAreaSample.Web": "1.0.0",
"PrecompilationWebSite": "1.0.0",
"RazorPageExecutionInstrumentationWebSite": "1.0.0",
"RazorWebSite": "1.0.0",