The default folder-by-type structure is to messy for me to handle. So I'm trying to adopt it to folder-by-feature structure. While doing so, I'm no able o rename Areas folder to a custom folder name.
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
string CombinePath(string path1, string path2)
{
if (path1.EndsWith("/", StringComparison.Ordinal) || path2.StartsWith("/", StringComparison.Ordinal))
{
return path1 + path2;
}
else if (path1.EndsWith("/", StringComparison.Ordinal) && path2.StartsWith("/", StringComparison.Ordinal))
{
return string.Concat(path1, path2.AsSpan(1));
}
return path1 + "/" + path2;
}
// Add services to the container.
builder.Services.AddMvc();
// .AddRazorPagesOptions(option => { })
// builder.Services.AddMvc().AddRazorPagesOptions(options =>
// {
// options.RootDirectory = $"/Areas/{{2}}/{{1}}/Pages/{{0}}.cshtml";
// });
builder.Services.Configure<RazorViewEngineOptions>(options =>
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
options.AreaPageViewLocationFormats.Clear();
options.AreaViewLocationFormats.Clear();
options.PageViewLocationFormats.Clear();
options.ViewLocationExpanders.Clear();
options.ViewLocationFormats.Clear();
var rootDirectory = "Pages";
var defaultPageSearchPath = CombinePath(rootDirectory, "{1}/{0}" + RazorViewEngine.ViewExtension);
options.PageViewLocationFormats.Add(defaultPageSearchPath);
// /Pages/Shared/{0}.cshtml
var pagesSharedDirectory = CombinePath(rootDirectory, "Shared/{0}" + RazorViewEngine.ViewExtension);
options.PageViewLocationFormats.Add(pagesSharedDirectory);
options.PageViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
var areaDirectory = CombinePath("/RandomFolder/", "{2}");
// Areas/{2}/Pages/
var areaPagesDirectory = CombinePath(areaDirectory, "/Pages/");
// Areas/{2}/Pages/{1}/{0}.cshtml
// Areas/{2}/Pages/Shared/{0}.cshtml
// Areas/{2}/Views/Shared/{0}.cshtml
// Pages/Shared/{0}.cshtml
// Views/Shared/{0}.cshtml
var areaSearchPath = CombinePath(areaPagesDirectory, "{1}/{0}" + RazorViewEngine.ViewExtension);
options.AreaPageViewLocationFormats.Add(areaSearchPath);
var areaPagesSharedSearchPath = CombinePath(areaPagesDirectory, "Shared/{0}" + RazorViewEngine.ViewExtension);
options.AreaPageViewLocationFormats.Add(areaPagesSharedSearchPath);
var areaViewsSharedSearchPath = CombinePath(areaDirectory, "Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.AreaPageViewLocationFormats.Add(areaViewsSharedSearchPath);
options.AreaPageViewLocationFormats.Add(pagesSharedDirectory);
options.AreaPageViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.ViewLocationFormats.Add(pagesSharedDirectory);
options.AreaViewLocationFormats.Add(pagesSharedDirectory);
options.ViewLocationExpanders.Add(new PageViewLocationExpander());
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.MapGet("/debug/routes", (IEnumerable<EndpointDataSource> endpointSources) =>
string.Join("\n", endpointSources.SelectMany(source => source.Endpoints)));
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
I tried to simply add new folder path to AreaPageViewLocationFormats, but it didn't work for Razor Pages (This works for Controller-Views, through AreaViewLocationFormats). So I tried it with the code of Configure method of RazorViewEngineOptions from the framework.
If I rename the folder to something else, and leave the folder name as it is in Program.cs, it will through an error saying program searched for the page in following locations. But as soon as rename the folder to the same name as it is in Program.cs, it will give 404. it only works if the folder name is "Areas". It doesn't even work for "Area".
Am I missing something?