Chúng tôi cho rằng ứng dụng có các tuyến và điểm cuối yêu cầu /Tenant1/Home/Error
và /Tenant2/Home/Error
. Bạn có thể giải quyết vấn đề bằng mã này:
app.UseExceptionHandler(
new ExceptionHandlerOptions
{
ExceptionHandler = async (ctx) =>
{
string tenant = ctx.Request.Host.Value.Split('/')[0];
ctx.Response.Redirect($"/{tenant}/Home/Error");
},
}
);
Một giải pháp tương đương khác là đặt đoạn mã sau vào startup.cs
:
app.UseExceptionHandler("$/{tenant}/Home/Error");
Chúng tôi cho rằng điều đó tenant
đến từ một nơi nào đó như cài đặt ứng dụng. Sau đó, bạn có thể dễ dàng nhận được các ngoại lệ trên điểm cuối mong muốn của mình bằng cách viết một lộ trình đơn giản cho hành động của bạn:
[Route("/{TenantId}/Home/Error")]
public IActionResult Error(string TenantId)
{
string Id = TenantId;
// Here you can write your logic and decide what to do based on TenantId
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
hoặc bạn có thể tạo hai hành động khác nhau:
[Route("/Tenant1/Home/Error")]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[Route("/Tenant2/Home/Error")]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
Cập nhật:
Nếu người thuê nhà của bạn được thêm động và không thể đưa vào appsettings.json
(những gì chúng tôi đã giả định trong các giải pháp trên), bạn có thể viết một kho trung gian để xử lý các Ngoại lệ, đây là cách:
Thêm kho trung gian Startup.cs
trong Configure
phương thức của bạn :
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
Ở dòng tiếp theo, thêm một tuyến cho các lỗi (chính xác là sau kho trung gian):
app.UseMvc(routes =>
{
routes.MapRoute(
name: "errors",
template: "{tenant}/{controller=Home}/{action=Index}/");
});
Tạo một lớp cho kho trung gian của bạn và đặt các mã này vào:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex,this.next);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex, RequestDelegate next)
{
string tenant = "tenant1";//write your logic something like this: context.Request.Path.Value.Split('/')[0];
context.Request.Path = new PathString($"/{tenant}/Home/Error");
context.Request.HttpContext.Features.Set<Exception>(ex);// add any object you want to the context
return next.Invoke(context);
}
}
Lưu ý rằng bạn có thể thêm bất cứ điều gì bạn muốn vào bối cảnh như thế này : context.Request.HttpContext.Features.Set<Exception>(ex);
.
Và cuối cùng bạn nên tạo một hành động với một định tuyến thích hợp để viết logic của bạn ở đó:
[Route("/{TenantId}/Home/Error")]
public IActionResult Error(string TenantId)
{
string Id = TenantId;
var exception= HttpContext.Features.Get<Exception>();// you can get the object which was set on the middle-ware
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
Lưu ý rằng đối tượng đã được đặt trên kho trung gian, bây giờ có thể được truy xuất.