【问题标题】:How to return error from ASP.NET MVC action如何从 ASP.NET MVC 操作返回错误
【发布时间】:2011-01-23 14:18:45
【问题描述】:

我正在使用 ASP.NET MVC 开发网站。我正在使用 jquery 来实现 AJAX 功能。在操作方法中,我想返回一些错误以表明输入不正确或无法执行操作。在这种错误情况下,我希望调用 jquery ajax 错误处理程序,并且我可以在那里采取适当的措施。我还没有找到如何做到这一点的方法。以下是我的操作方法。

在错误情况下,我应该从 Action 发送什么来触发 jquery 错误处理程序?

public ActionResult AddToFavourites(int entityId, string entityType)
    {

        if (!Request.IsAjaxRequest())
            throw new InvalidOperationException("This action can be called only in async style.");

        try
        {
            RBParams.EntityType typeOfFavourite = (RBParams.EntityType)Enum.Parse(typeof(RBParams.EntityType), entityType);
            string status = "";

            if (typeOfFavourite == RBParams.EntityType.BusinessEntity)
            {
                status = MarkFavouriteEntity(entityId);
            }
            else if (typeOfFavourite == RBParams.EntityType.Review)
            {
                status = MarkFavouriteReview(entityId);
            }
            else
            {
                throw new InvalidOperationException("The type of the entity is not proper");
            }

            return Content(status);

        }
        catch (Exception ex)
        {

            return Content("Error");
        }
    }

【问题讨论】:

    标签: jquery asp.net ajax asp.net-mvc


    【解决方案1】:

    你应该配置 jquery 来处理错误:

    $.ajaxSetup({
        error: function(xhr) {
            alert(xhr.statusText);
        }
    })
    

    【讨论】:

    • Ild615,我在 $.ajaxSetup(...) 中完成了此操作。我的问题是我应该从 Action 发送什么来触发这个错误处理程序。
    【解决方案2】:

    当操作没有返回预期的状态代码时,将调用您的 ajax 错误处理程序。例如,如果未找到该操作,或者如果您抛出您未处理的异常,它将触发。在您的情况下,如果您在操作中没有发现错误,它将被调用(因为操作将返回 500 状态代码)。

    但是,我不会这样做,因为这可能是预期的错误。我宁愿在你成功和出错时都返回 json。然后你可以指示它是否是一个成功的调用。像这样的:

    public ActionResult AddToFavourites(int entityId, string entityType)
    {
    
        if (!Request.IsAjaxRequest())
            throw new InvalidOperationException("This action can be called only in async style.");
    
        try
        {
            RBParams.EntityType typeOfFavourite = (RBParams.EntityType)Enum.Parse(typeof(RBParams.EntityType), entityType);
            string status = "";
    
            if (typeOfFavourite == RBParams.EntityType.BusinessEntity)
            {
                status = MarkFavouriteEntity(entityId);
            }
            else if (typeOfFavourite == RBParams.EntityType.Review)
            {
                status = MarkFavouriteReview(entityId);
            }
            else
            {
                throw new InvalidOperationException("The type of the entity is not proper");
            }
    
            return Json(new { Success = true, Status = status });
    
        }
        catch (Exception ex)
        {
    
            return Json(new { Success = false, Message = ex.Message });
        }
    }
    

    然后您以与成功调用相同的方式处理它。您只需检查 json 响应的 Success 属性。然后在错误回调中处理意外错误。

    【讨论】:

    • 您的示例中提供的Json 设置是否会设置为客户端的xhr 变量?
    • 我没有投反对票,但我不同意。 (对不起,@Mattias)。这将导致 JavaScript “成功”回调触发。当服务器出现错误时,我们总是希望触发错误回调。这违反了语义。从语义上讲,我们希望返回一个 500 系列错误。
    • 您可以使用 Response.StatusCode = (int) HttpStatusCode.InternalServerError; 返回错误就在 return Json(...); 之前
    • 你也可以抛出一个 HttpException。例如,抛出新的 HttpException(HttpStatusCode.InternalServerError, ex);这将触发 ajax 错误回调并提供问题的解释。
    • 我曾经做过类似答案的事情,虽然它有效......使用Web Api我使用了动作过滤器属性来捕获异常并返回具有不同细节级别的错误代码(不同预期错误与意外错误的错误代码)使客户端更加理智......这个错误都不是成功的疯狂! :) HttpException +1 听起来像是我这次来寻找的答案!
    【解决方案3】:

    Mattias Jakobsson 的回答是正确的。但我认为将错误返回给 jQuery 的最佳方法是创建一个 JSON 并将其发送为状态 500。但是,当我这样做并尝试使用 IIS 7 部署我的 MVC 网站时,我发现它正在返回我的自定义页面而不是消息。

    代码是...

    catch (Exception ex)
    {
        Response.StatusCode = 500;
        return Json(new { error = ex.Message });
    }
    

    但后来我看到了this thread,这让我想到了这个web site(来自 Rick Strahl)。

    总的来说,我明白你需要告诉 IIS 不注入自定义错误页面,所以你需要这个标志(在 global.asax 或 catch 中):

    Response.TrySkipIisCustomErrors = true;

    所以,在 jQuery 中代码保持不变:

    $.ajax({...})
    .done(function (result) {...})
    .fail(function (e) { 
       console.log(e.responseJSON.error);
    });
    

    【讨论】:

    • 这是一个出色而完整的答案。您将展示控制器的示例相应的 AJAX 调用。感谢您抽出宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多