【问题标题】:500 error mystery happens on server only500 错误之谜仅发生在服务器上
【发布时间】:2016-02-19 13:57:56
【问题描述】:

我在本地从 .net MVC 应用程序取回请求的数据的问题为零,但在服务器上,ajax jquery 调用报告了 500 错误。通常,我可以在本地单步执行代码并找出“可能”导致服务器上出现 500 错误的原因。

这一次我意识到我真的需要一个更好的编码策略来捕获错误并将它们记录下来或报告给我

public ActionResult PhotoList(int tblGateCode_ID)
{
    try
    {
        context = new DBGate();
        var images = context.tblGateCodeImages.Where(x => x.tblGateCode_ID == tblGateCode_ID);
        foreach (var img in images)
        {
            img.GatePhoto = null;
        }
        ViewModel viewModel = new ViewModel
        {
            GateCodeImageList = images.ToList()
        };
        return Json(viewModel, "application/json", JsonRequestBehavior.AllowGet);

        }
        catch (Exception e)
        {

        //??
        }
   }
}

更新:

我确实尝试将代码添加到我的 catch 中

catch (Exception e)
{
    return Json(e.Message, "application/json", JsonRequestBehavior.AllowGet); 
}

要么我不被允许这样做......要么我仍然得到 500 的其他原因?

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

【问题讨论】:

  • 您可以使用浏览器工具(网络选项卡)检查响应并查看错误的更多详细信息
  • 响应不够好,我想做的只是将异常传回。所以我想e.Message
  • 您对服务器有多少访问权限?如果您可以查看事件日志,则可以将 exception.message 写入事件日志以帮助调试。 support.microsoft.com/en-us/kb/307024
  • 我碰巧可以访问此服务器 - 将异常消息传递回调用者会非常好 - 让我与 console.log 一起使用
  • 真正奇怪的是,即使我将 json 返回更改为只传回一个空的视图模型,我仍然会收到 500 错误。就像 try /catch 甚至没有真正起作用 IMO

标签: jquery asp.net-mvc asp.net-web-api error-handling


【解决方案1】:

这有多种原因,从缺少依赖项到不正确的服务器设置。因此,我建议设置一些适当的错误日志,您很快就会从这些日志中看到错误是什么。

在 ASP.net 中更简单的方法是安装 Elmah。通过 nuget 执行此操作。

这里要注意的一点是,默认情况下,在 web api 中,您不会将所有错误都选为described here。为了确保捕获所有异常,添加以下代码并在启动时通过添加 config.Filters.Add(new RestfulModelStateFilterAttribute()); 在方法注册中的 WebAppConfig 类中注册它;

下面的替代方法是添加 nuget 包 Elmah.Contrib.WebApi

using System;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Elmah;
using Newtonsoft.Json;

/// <summary>
/// see http://sergeyakopov.com/2015/03/restful-validation-with-aspnet-web-api-and-fluentvalidation
/// and https://github.com/rdingwall/elmah-contrib-webapi/blob/master/src/Elmah.Contrib.WebApi/ElmahHandleErrorApiAttribute.cs
/// this is a combination of both, but with logging enabled for anything above 400, not 500 like the link above.
/// </summary>
public class RestfulModelStateFilterAttribute : ActionFilterAttribute
{

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);

        var e = actionExecutedContext.Exception;
        if (e != null)
        {
            RaiseOrLog(e, actionExecutedContext);
        }
        else if ((int)actionExecutedContext.Response.StatusCode >= 400)
        {
            RaiseOrLog(
                new HttpException(
                    (int)actionExecutedContext.Response.StatusCode,
                    ResolveMessage(actionExecutedContext)),
                actionExecutedContext);
        }
    }

    private string ResolveMessage(HttpActionExecutedContext actionExecutedContext)
    {
        const string messageKey = "Message";

        var defaultMessage = actionExecutedContext.Response.ReasonPhrase;
        var objectContent = actionExecutedContext.Response.Content as ObjectContent<HttpError>;
        if (objectContent == null) return defaultMessage;

        var value = objectContent.Value as HttpError;
        if (value == null) return defaultMessage;

        if (!value.ContainsKey(messageKey)) return defaultMessage;

        var message = value[messageKey] as string;
        return string.IsNullOrWhiteSpace(message) ? defaultMessage : message;
    }

    private void RaiseOrLog(Exception exception, HttpActionExecutedContext actionExecutedContext)
    {
        if (RaiseErrorSignal(exception) // prefer signaling, if possible
            || IsFiltered(actionExecutedContext)) // filtered?
            return;

        LogException(exception);
    }

    private static bool RaiseErrorSignal(Exception e)
    {
        var context = HttpContext.Current;
        if (context == null)
            return false;
        var application = HttpContext.Current.ApplicationInstance;
        if (application == null)
            return false;
        var signal = ErrorSignal.Get(application);
        if (signal == null)
            return false;
        signal.Raise(e, context);
        return true;
    }

    private static bool IsFiltered(HttpActionExecutedContext context)
    {
        var config = HttpContext.Current.GetSection("elmah/errorFilter")
                     as ErrorFilterConfiguration;

        if (config == null)
            return false;

        var testContext = new ErrorFilterModule.AssertionHelperContext(
                                  context.Exception, HttpContext.Current);

        return config.Assertion.Test(testContext);
    }

    private static void LogException(Exception e)
    {
        var context = HttpContext.Current;
        Elmah.ErrorLog.GetDefault(context).Log(new Error(e, context));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 2018-04-15
    相关资源
    最近更新 更多