简体   繁体   English

如何正确处理 ASP.NET Core MVC 中的 AJAX 错误?

[英]How to properly handle AJAX errors in ASP.NET Core MVC?

Background:背景:

I'm setting up error handling in an ASP.NET Core 2.2 MVC app.我正在 ASP.NET Core 2.2 MVC 应用程序中设置错误处理。 When in development environment, I use the app.UseDeveloperExceptionPage();在开发环境中,我使用app.UseDeveloperExceptionPage(); , and in production - app.UseExceptionHandler("/Error/Index"); ,并在生产中 - app.UseExceptionHandler("/Error/Index"); . . I am navigated to the correct error page during non-AJAX (regular form submission) requests based on the environment.在基于环境的非 AJAX(常规表单提交)请求期间,我被导航到正确的错误页面。

If an exception occurs in the server during an AJAX request, I want the app to display the correct error page depending on the environment.如果在 AJAX 请求期间服务器发生异常,我希望应用程序根据环境显示正确的错误页面。

I have already set up all of what I described above, as you can see in my code examples below.正如您在下面的代码示例中所见,我已经设置了上面描述的所有内容。

Problem/Concern:问题/担忧:

While this works (though still have to complete the TODO in InitializeGlobalAjaxEventHandlers function), I have some concerns.虽然这可行(尽管仍然必须在InitializeGlobalAjaxEventHandlers函数中完成 TODO),但我还是有些担心。

With non-AJAX calls in MVC, it feels like there is a "official/correct" way to do it with app.UseDeveloperExceptionPage();在 MVC 中使用非 AJAX 调用,感觉就像有一种“官方/正确”的方式来使用app.UseDeveloperExceptionPage(); and app.UseExceptionHandler("/Error/Index");app.UseExceptionHandler("/Error/Index"); , which automatically redirects the program to the error page. ,它会自动将程序重定向到错误页面。 With the AJAX end of error handling, however, I don't feel as confident because I pieced it together with parts from different solutions I've researched.然而,随着 AJAX 错误处理结束,我没有那么自信,因为我将它与我研究过的不同解决方案的部分拼凑在一起。 I'm worried I'm not aware of what could go wrong.我担心我不知道 go 会出现什么错误。

Question:问题:

Is this the proper way to handle errors during AJAX requests in MVC?这是在 MVC 中的 AJAX 请求期间处理错误的正确方法吗? Could something possibly go wrong with this set up?这个设置可能会出现 go 错误吗? Is this in any way improper or too far from common standards?这是否有任何不当或与共同标准相去甚远?

Code:代码:

Startup.cs > Configure method: Startup.cs > 配置方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //using build config to use the correct error page: https://stackoverflow.com/a/62177235/12300287
    //Reason why we don't use environmental variables is because we can't guarantee access to clients' 
    //machines to create them.
#if (DEVELOPMENT || STAGING)
    app.UseDeveloperExceptionPage();
#else
    app.UseExceptionHandler("/Error/Index");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
#endif

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    //app.UseCookiePolicy();

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=UserAccess}/{action=Index}/{id?}");
    });
}

ErrorController.cs:错误控制器.cs:

public class ErrorController : Controller
{
    [AllowAnonymous]
    public IActionResult Index()
    {
        IExceptionHandlerPathFeature exceptionDetails = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        Exception exception = exceptionDetails?.Error; // Here will be the exception details.

        Error model = new Error();
        model.ID = exception.HResult;
        model.Message = exception.Message;
        model.Path = exceptionDetails.Path;

        return View(model);
    }
}

Global AJAX error event handler (the if statement is to handle authentication):全局 AJAX 错误事件处理程序( if语句用于处理身份验证):

function InitializeGlobalAjaxEventHandlers() {
    $(document).ajaxError(function (event, xhr, ajaxSettings, thrownError) {
        //status is set in the [AuthorizeAjax] action filter if user isn't authenticated
        if (xhr.status == 403) {
            var response = $.parseJSON(xhr.responseText);
            window.location = response.redirectUrl;
        }

        //the document HTML is replaces by responseText value, which contains the HTML of error page
        document.write(xhr.responseText);

        //TODO: will need to display an error page if responseText is empty, which
        //can happen if an AJAX request doesn't reach the server (for example: if URL is incorrect).
    });
}

Is this the proper way to handle errors during AJAX requests in MVC?这是在 MVC 中的 AJAX 请求期间处理错误的正确方法吗? Could something possibly go wrong with this set up?这个设置可能会出现 go 错误吗? Is this in any way improper or too far from common standards?这是否有任何不当或与共同标准相去甚远?

As far as I know, there are no unified/official way of handling Ajax errors in ASP.NET Core MVC project.据我所知,在 ASP.NET Core MVC 项目中没有统一/官方的方法来处理 Ajax 错误。

Normally we show specific confirm message/content through Ajax error callback function if the Ajax request fails rather than directly displaying detailed exception information to client user, which would help achieve a better customer experience.通常,如果 Ajax 请求失败,我们会通过 Ajax 错误回调 function 显示特定的确认消息/内容,而不是直接向客户端用户显示详细的异常信息,这将有助于获得更好的客户体验。

If you have specific requirement that requires displaying the Developer Exception Page/custom error page while Ajax request fails, as you did, you can dynamically write the returned responseText to the HTML document using document.write(xhr.responseText);如果您有特定要求需要在 Ajax 请求失败时显示开发人员异常页面/自定义错误页面,就像您所做的那样,您可以使用document.write(xhr.responseText);将返回的responseText动态写入 HTML 文档; in global error handler.在全局错误处理程序中。

As you explain, there are two threads of code to consider.正如您所解释的,有两个代码线程需要考虑。 One is at the client and the other at the server.一个在客户端,另一个在服务器。

Whilst the server can return codes and messages for non-expected results, the client must still be robust and stand-alone.虽然服务器可以返回非预期结果的代码和消息,但客户端仍然必须是健壮的和独立的。 For example, if the server cannot be reached, a time-out error can occur at the client which it must handle.例如,如果无法访问服务器,则它必须处理的客户端可能会发生超时错误。 As mentioned above, you can catch errors at the local and global Ajax level.如上所述,您可以在本地和全局 Ajax 级别捕获错误。

The server may also generate an error response that never reaches the client.服务器还可能生成永远不会到达客户端的错误响应。

In some projects I have performed the following:- If a non-expected result is generated on the server, it is logged in a database and returns an JSON message as an error.在某些项目中,我执行了以下操作:- 如果在服务器上生成了非预期结果,则会将其记录在数据库中并返回 JSON 消息作为错误。

If a non-expected result is generated on the client, a server service is called to log the error on the database.如果在客户端上生成了非预期的结果,则会调用服务器服务将错误记录到数据库中。

In both cases, a message is displayed in the current page.在这两种情况下,都会在当前页面中显示一条消息。 A user can also navigate to an error page where recent errors (stored in the database) are displayed.用户还可以导航到显示最近错误(存储在数据库中)的错误页面。

Working on many project of varying sizes, I've come to the conclusion that there isn't really a solution that fits everything在处理许多不同规模的项目时,我得出的结论是,没有真正适合所有情况的解决方案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM