使用UseExceptionHandler自定义错误页面时,错误页面显示为空白

问题描述 投票:0回答:1

我正在尝试在使用 .Net 6 构建的网站上实现自定义错误页面,并尝试使用以下代码实现:

程序.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();
app.UseExceptionHandler("/Shared/Error");
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    
    // 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.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

共享控制器.cs

public class SharedController : BaseController
{
    private readonly string _cookieKey = "session-info";
    private readonly ILogger<SharedController> _logger;

    public SharedController(ILogger<SharedController> logger, IConfiguration configuration) : base(configuration)
    {
        _logger = logger;
    }

    public IActionResult Error()
    {
        return View(new ErrorViewModel());
    }
}

BaseController.cs

public class BaseController : Controller
{
    private readonly string _cookieKey = "session-info";
    public IConfiguration _config;

    public BaseController(IConfiguration configuration)
    {
        _config = configuration;
    }

    public async Task CheckLogin(BaseModel? model)
    {
        if(model == null)
        {
            return;
        }

        model.UserName = "";
        model.UserId = -1;
        model.IsAdmin = false;
        model.LoggedIn = false;

        var baseAddress = new Uri(_config["Config:BaseAddress"]);
        var cookieContainer = new CookieContainer();
        using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
        {
            var siteCookies = HttpContext.Request.Cookies.Where(cookie => cookie.Key == _cookieKey); ;

            if (!siteCookies.Any())
            {
                return;
            }

            var siteCookie = siteCookies.First();
            cookieContainer.Add(baseAddress, new Cookie(siteCookie.Key, siteCookie.Value));
            var client = new HttpClient(handler);
            var response = await client.GetAsync(baseAddress.AbsoluteUri + "api/authenticate");

            if (response != null && response.IsSuccessStatusCode)
            {
                var userObj = await response.Content.ReadFromJsonAsync<UserLookup>();

                if (userObj.Key != null && userObj.Key != "")
                {
                    model.UserName = userObj.Key;
                    model.UserId = userObj.Id;
                    model.LoggedIn = true;
                }
            }

            response = await client.GetAsync(baseAddress.AbsoluteUri + "api/isAdmin");

            if (response != null && response.IsSuccessStatusCode)
            {
                model.IsAdmin = await response.Content.ReadFromJsonAsync<bool>();
            }
        }
    }

    private class Login
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }

    private class UserLookup
    {
        public string Key { get; set; }
        public int Id { get; set; }
    }
}

错误.cshtml

@model ErrorViewModel
@{
    ViewData["Title"] = "Error";
    Layout = "_Layout";
}

@if (true)
{
    <h1>Error.</h1>
    <h2>An error occurred while processing your request.</h2>
}

请注意,我将设置移到 IsDevelopment 块之外只是为了测试。 不过,无论是在开发配置还是发布配置上进行测试,我都会得到相同的结果。 当我遇到异常时,它会被中间件捕获,错误控制器方法运行,我什至可以通过断点看到视图正在运行。 但是,我只是在浏览器中看到一个完全空白的页面。另外,检查网络选项卡时,我仍然看到返回 500 错误。 我还应该注意,我只能通过抛出异常来触发此操作。如果我转到一个不存在的页面并收到 404,我只会得到一个空白页面,而不会命中任何处理程序。

由于流程通过 Error 方法和 cshtml 代码移动,我认为一切都连接正常,但我得到一个完全空白的页面。甚至布局都没有加载。在搜索中,我没有看到这个特定的问题弹出,所以除了将我的配置更改为发布之外,我没有尝试任何其他方法。

.net http-error
1个回答
0
投票

我在关闭“仅我的代码”进行调试时发现了这一点。 我的 ErrorViewModel 类继承了 PageModel。 在中间件的某个时刻,它期望它是 BaseModel 类型。由于类型不匹配,它正在考虑未处理的异常并调用 Rethrow,这会重新抛出错误,导致我看到 500 和空白页。 我不确定为什么这是预期的所有来龙去脉,但确实如此。

长话短说,我将 ErrorViewModel 更改为继承 BaseModel 而不是 PageModel,现在我按预期获得了自定义错误页面。

© www.soinside.com 2019 - 2024. All rights reserved.