ASP.Net中的AJAX WebService - 如何进行全局错误处理?

时间:2015-04-13 13:31:36

标签: .net ajax error-handling webmethod

我的* .aspx网站中有大约50多个AJAX WebMethods,由JQuery调用(有时是原始jquery,有时候是在lib')。

以下是一些例子:

 [WebMethod]
    public static string GetLog()
    {
        DAL.LogService log = new DAL.LogService();
        string items = log.GetLog();
        return items;
    }

    [WebMethod]
    public static void ClearBenchmarks()
    {
        DAL.LogService log = new DAL.LogService();
        log.ClearBenchmarks();
    }

    [WebMethod]
    public static void WriteLog(string message1, string message2, string user, string type)
    {
        DAL.LogService.WriteLog(message1, message2, user, type);
    }

事实上,在大多数时候,他们只会重定向到我的应用程序的dataLayer,但事实上,我有50多种单一方法......

现在我想在我的应用程序中包含错误处理 - 如何在不尝试捕获每个方法的情况下执行该操作?

2 个答案:

答案 0 :(得分:4)

经过长时间的搜索,我在其他网站上找到了这个解决方案 事实上,Application_Error永远不会被处理,因为请求处理程序会在它到达此点之前过滤JSON请求,因此您唯一的机会(afaik)是进入请求处理程序并检查其中是否存在jsonerror。

对我来说工作得很好,只需添加global.asax.cs并复制粘贴此代码:

  protected void Application_PostMapRequestHandler(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        if (context.Handler is Page && !string.IsNullOrEmpty(context.Request.PathInfo))
        {
            string contentType = context.Request.ContentType.Split(';')[0];
            if (contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase))
            {
                context.Response.Filter = new PageMethodExceptionLogger(context.Response);
            }
        }
    }

    public class PageMethodExceptionLogger : Stream
    {
        private readonly HttpResponse _response;
        private readonly Stream _baseStream;
        private readonly MemoryStream _capturedStream = new MemoryStream();

        public PageMethodExceptionLogger(HttpResponse response)
        {
            _response = response;
            _baseStream = response.Filter;
        }

        public override void Close()
        {
            if (_response.StatusCode == 500 && _response.Headers["jsonerror"] == "true")
            {
                _capturedStream.Position = 0;
                string responseJson = new StreamReader(_capturedStream).ReadToEnd();
                // TODO: Do the actual logging.
                JavaScriptSerializer j = new JavaScriptSerializer();
                var jsonObject = j.DeserializeObject(responseJson) as Dictionary<string, object>;
                DAL.LogService.WriteLog(jsonObject["Message"].ToString(), jsonObject["StackTrace"].ToString(), "ERROR", "ERROR");
            }

            _baseStream.Close();
            base.Close();
        }

        public override void Flush()
        {
            _baseStream.Flush();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _baseStream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _baseStream.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _baseStream.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _baseStream.Write(buffer, offset, count);
            _capturedStream.Write(buffer, offset, count);
        }

        public override bool CanRead { get { return _baseStream.CanRead; } }
        public override bool CanSeek { get { return _baseStream.CanSeek; } }
        public override bool CanWrite { get { return _baseStream.CanWrite; } }
        public override long Length { get { return _baseStream.Length; } }

        public override long Position
        {
            get { return _baseStream.Position; }
            set { _baseStream.Position = value; }
        }
    }

答案 1 :(得分:2)

这是.Net中的已知问题 - global.asax的Application_Error永远不会为Web服务触发。

所以你可以尝试一下这些想法。

  1. 您可以围绕每个Web服务方法设置一个try-catch

  2. 使用外观设计模式并在父级中包含try-catch 对象

  3. 编写自定义SOAP扩展或HTTPModule

  4. 希望这有帮助