寻找一种方法让 类 自动将自己注册为端点
Looking for a way to have classes auto register themselves as an Endpoint
我正在将围绕通用处理程序构建的 .NET Framework 4.8 Web 应用程序转换为 .NET Core 3.1 Web 应用程序。
我正在为我的每个自定义页面 class 寻找一种方法,以便能够在启动阶段将自己自动注册为端点。现在它是一个我想简化的手动过程。
这就是我目前正在使用的内容。
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.FileProviders;
namespace App
{
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseStaticFiles(StaticFolder("/Resources"));
app.UseStaticFiles(StaticFolder("/Clients"));
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", Page<Default>);
endpoints.MapGet("/Login.ashx", Page<Login>);
endpoints.MapPost("/LoginPostBack.ashx", Page<LoginPostBack>);
endpoints.MapGet("/Logout.ashx", Page<Logout>);
endpoints.MapPost("/LogoutPostBack.ashx", Page<LogoutPostBack>);
endpoints.MapGet("/Clients/", Page<Clients.Default>);
endpoints.MapPost("/Clients/", Page<Clients.DefaultPostBack>);
endpoints.MapGet("/Clients/Add.ashx", Page<Clients.Add>);
endpoints.MapPost("/Clients/AddPostBack.ashx", Page<Clients.AddPostBack>);
endpoints.MapGet("/Clients/Modify.ashx", Page<Clients.Modify>);
endpoints.MapPost("/Clients/ModifyPostBack.ashx", Page<Clients.ModifyPostBack>);
endpoints.MapGet("/Clients/Delete.ashx", Page<Clients.Delete>);
endpoints.MapPost("/Clients/DeletePostBack.ashx", Page<Clients.DeletePostBack>);
});
}
private async Task Page<T>(HttpContext context) where T : new()
{
T page = new T();
await ((IPage)page).ProcessRequest(context);
}
private StaticFileOptions StaticFolder(string path)
{
return new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), path.Substring(1))),
RequestPath = path
};
}
}
}
下面是自定义页面的示例 class:
using System.Web;
namespace App
{
public class Default : FormPage
{
protected override void PreProcess()
{
Page.Icon = "far fa-home";
Page.Title = "Home";
}
protected override void Process()
{
Write(@"<div class=""row mb-4"">");
Write(@"<div class=""col-12"">");
Write(@"<h5>Home</h5>");
Write(@"</div>");
Write(@"</div>");
}
}
}
这里的问题是您试图维护以 ashx
结尾的 URL,即使这在 ASP.NET Core 中没有任何意义。 Razor Pages 有关于 URL 结构的默认约定,除了 ashx
.
之外,这与这里的 URL 几乎一致
如果您只是想维护现有的 URL 结构(没有 404),正确的做法是创建永久重定向,例如Login.ashx
到 Login
。然后,默认的基于约定的路由就可以正常工作,如果有人确实去了旧的 URL,他们只会被重定向到新的。
我用反射解决了它:
app.UseEndpoints(endpoints =>
{
foreach (Type pageType in Assembly.GetExecutingAssembly().DefinedTypes)
if (typeof(IPage).IsAssignableFrom(pageType))
{
IPage pageInstance = (IPage)Activator.CreateInstance(pageType);
MethodInfo pageMethod = typeof(Startup).GetMethod("Page");
MethodInfo delegateMethod = pageMethod.MakeGenericMethod(pageType);
RequestDelegate requestDelegate = (RequestDelegate)RequestDelegate.CreateDelegate(typeof(RequestDelegate), this, delegateMethod);
endpoints.MapGet(pageInstance.Endpoint, requestDelegate);
}
});
我正在将围绕通用处理程序构建的 .NET Framework 4.8 Web 应用程序转换为 .NET Core 3.1 Web 应用程序。
我正在为我的每个自定义页面 class 寻找一种方法,以便能够在启动阶段将自己自动注册为端点。现在它是一个我想简化的手动过程。
这就是我目前正在使用的内容。
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.FileProviders;
namespace App
{
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseStaticFiles(StaticFolder("/Resources"));
app.UseStaticFiles(StaticFolder("/Clients"));
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", Page<Default>);
endpoints.MapGet("/Login.ashx", Page<Login>);
endpoints.MapPost("/LoginPostBack.ashx", Page<LoginPostBack>);
endpoints.MapGet("/Logout.ashx", Page<Logout>);
endpoints.MapPost("/LogoutPostBack.ashx", Page<LogoutPostBack>);
endpoints.MapGet("/Clients/", Page<Clients.Default>);
endpoints.MapPost("/Clients/", Page<Clients.DefaultPostBack>);
endpoints.MapGet("/Clients/Add.ashx", Page<Clients.Add>);
endpoints.MapPost("/Clients/AddPostBack.ashx", Page<Clients.AddPostBack>);
endpoints.MapGet("/Clients/Modify.ashx", Page<Clients.Modify>);
endpoints.MapPost("/Clients/ModifyPostBack.ashx", Page<Clients.ModifyPostBack>);
endpoints.MapGet("/Clients/Delete.ashx", Page<Clients.Delete>);
endpoints.MapPost("/Clients/DeletePostBack.ashx", Page<Clients.DeletePostBack>);
});
}
private async Task Page<T>(HttpContext context) where T : new()
{
T page = new T();
await ((IPage)page).ProcessRequest(context);
}
private StaticFileOptions StaticFolder(string path)
{
return new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), path.Substring(1))),
RequestPath = path
};
}
}
}
下面是自定义页面的示例 class:
using System.Web;
namespace App
{
public class Default : FormPage
{
protected override void PreProcess()
{
Page.Icon = "far fa-home";
Page.Title = "Home";
}
protected override void Process()
{
Write(@"<div class=""row mb-4"">");
Write(@"<div class=""col-12"">");
Write(@"<h5>Home</h5>");
Write(@"</div>");
Write(@"</div>");
}
}
}
这里的问题是您试图维护以 ashx
结尾的 URL,即使这在 ASP.NET Core 中没有任何意义。 Razor Pages 有关于 URL 结构的默认约定,除了 ashx
.
如果您只是想维护现有的 URL 结构(没有 404),正确的做法是创建永久重定向,例如Login.ashx
到 Login
。然后,默认的基于约定的路由就可以正常工作,如果有人确实去了旧的 URL,他们只会被重定向到新的。
我用反射解决了它:
app.UseEndpoints(endpoints =>
{
foreach (Type pageType in Assembly.GetExecutingAssembly().DefinedTypes)
if (typeof(IPage).IsAssignableFrom(pageType))
{
IPage pageInstance = (IPage)Activator.CreateInstance(pageType);
MethodInfo pageMethod = typeof(Startup).GetMethod("Page");
MethodInfo delegateMethod = pageMethod.MakeGenericMethod(pageType);
RequestDelegate requestDelegate = (RequestDelegate)RequestDelegate.CreateDelegate(typeof(RequestDelegate), this, delegateMethod);
endpoints.MapGet(pageInstance.Endpoint, requestDelegate);
}
});