Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有一种方法可以捕获AJAX web服务中的所有错误?_C#_Asp.net_.net_Ajax_Json - Fatal编程技术网

C# 有没有一种方法可以捕获AJAX web服务中的所有错误?

C# 有没有一种方法可以捕获AJAX web服务中的所有错误?,c#,asp.net,.net,ajax,json,C#,Asp.net,.net,Ajax,Json,我想捕获ASP.NET web服务中抛出的任何未经处理的异常,但到目前为止,我所做的任何尝试都无法奏效 首先,HttpApplication.Error事件不会在web服务上触发,所以这就结束了 下一种方法是实现soap扩展,并将其添加到web.config,方法如下: <soapExtensionTypes> <add type="Foo" priority="1" group="0" /> </soapExtensionTypes> 这使得整件事

我想捕获ASP.NET web服务中抛出的任何未经处理的异常,但到目前为止,我所做的任何尝试都无法奏效

首先,HttpApplication.Error事件不会在web服务上触发,所以这就结束了

下一种方法是实现soap扩展,并将其添加到web.config,方法如下:

<soapExtensionTypes>
   <add type="Foo" priority="1" group="0" />
</soapExtensionTypes>

这使得整件事变得越来越容易

2) 因为您不能子类或重写RestHandler类,所以必须将整个过程重新实现为自己的IHttpHandler,或者使用反射手动调用其方法。由于RestHandler的源代码是公共的,并且只有大约500行长,所以制作自己的版本可能不是一项巨大的工作,但是您将负责维护它。我也不知道该代码涉及到任何许可限制


3) 您可以将您的方法包装在try/catch块中,或者使用LAMBDA表达式使代码更简洁。仍然需要修改web服务中的每个方法。

这是个好问题。我在使用的web应用程序中遇到了这个问题。恐怕我的解决方案一点也不明智。我只是将每个web服务方法中的代码包装在一个try/catch中,并返回一个对象,该对象指示该方法是否已成功运行。幸运的是,我的应用程序没有大量的web服务调用,所以我可以避开这些。我很感激如果你在做大量的web服务调用,这不是一个好的解决方案

如中所述,确实没有好的解决方案

无法捕获HttpApplication.Error等的原因与微软的好人如何实现RestHandler有关。具体而言,RestHandler显式捕获(处理)异常,并将异常详细信息写入响应:

internal static void ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)
{
    try
    {
        NamedPermissionSet namedPermissionSet = HttpRuntime.NamedPermissionSet;
        if (namedPermissionSet != null)
        {
            namedPermissionSet.PermitOnly();
        }
        IDictionary<string, object> rawParams = GetRawParams(methodData, context);
        InvokeMethod(context, methodData, rawParams);
    }
    catch (Exception exception)
    {
        WriteExceptionJsonString(context, exception);
    }
}
你看了吗? 这是目前的测试版,但它已经在几个现场使用。 公开json/XMLRESTAPI非常容易。 在其中,您可以创建自己的HttpErrorHandler派生类来处理错误。这是一个非常干净的解决方案。也许值得你仔细看看。迁移任何现有服务也应该很简单。希望有帮助

编辑

是否尝试在web.config中关闭错误处理,然后添加错误模块

<location path="Webservices" >
    <system.web>
     <customErrors mode="Off" />
    </system.web>
</location>
执行失败的结果示例:

{
  success: true,
  data: [ .... ],
  error: null
}
{
  success: false,
  data: null,
  error: {
    message: 'error message',
    stackTrace: 'url encoded stack trace'
  }
}
将此添加到web.config:

<modules>
  <add name="UnhandledException" type="Modules.Log.UnhandledException"/>
</modules>

通过在模块中实现未记录的PreApplicationStartMethod函数,并创建和使用自定义的HttpApplication类来代替标准类,您可以轻松添加代码,使模块自注册。通过这样做,只需将任何模块添加到应用程序的bin文件夹,即可将其添加到应用程序中。这是我目前处理所有应用程序的方式,我必须说它工作得非常完美

下面的代码将捕获所有应用程序错误并返回带有错误消息的html响应(您需要用自己的json错误消息实现替换html内容):

使用System.Web;
名称空间模块.Log
{
使用制度;
使用系统文本;
公共类日志模块:IHttpModule
{
private bool initialized=false;
私有对象initLock=新对象();
私有静态字符串applicationName=string.Format(“服务器:{0};[LogModule\u AppName]安装名称未设置”,System.Environment.MachineName);
公共空间处置()
{
}
公共void Init(HttpApplication上下文)
{
//对每个AppDomain执行一次。
如果(!已初始化)
{
锁(initLock)
{
如果(!已初始化)
{
context.Error+=新的EventHandler(this.OnUnhandledApplicationException);
初始化=真;
}
}
}
}
私有void OnUnhandledApplicationException(对象发送方,事件参数e)
{
StringBuilder消息=新建StringBuilder(“”)+
正文,表格{字体大小:12px;字体系列:Arial,无衬线;}\r\n+
“表tr td{padding:4px;}\r\n”+
.header{font-weight:900;font-size:14px;颜色:#fff;背景色:#2b4e74;}\r\n+
.header2{字体大小:900;背景色:#C0C0;}\r\n+
“\r\n\r\n未处理LogModule.dll记录的异常:\r\n\r\nappId=”);
字符串appId=(字符串)AppDomain.CurrentDomain.GetData(“.appId”);
if(appId!=null)
{
message.Append(appId);
}
消息。追加(“”);
HttpServerUtility服务器=HttpContext.Current.server;
异常currentException=server.GetLastError();
如果(currentException!=null)
{
message.AppendFormat(
“类型{0}请求{3}消息{1}堆栈跟踪{2}”,
currentException.GetType().FullName,
currentException.Message,
currentException.StackTrace,
HttpContext.Current!=null?HttpContext.Current.Request.FilePath:“不适用”;
ClearError();
}
消息。追加(“”);
HttpContext.Current.Response.Write(message.ToString());
ClearError();
}
}
}

对于不能修改web方法的要求是否有任何灵活性?嗯,是的-只要我不必将所有方法都放在巨大的try/catch块中就可以了。。如果解决方案是干净的,那么我愿意接受它。我有一个解决方案,它需要一个Try块和一个单线捕捉。你也许可以改进它,完全取消试捕,我还没挖那么深。要寄出去吗
{
  success: false,
  data: null,
  error: {
    message: 'error message',
    stackTrace: 'url encoded stack trace'
  }
}
<modules>
  <add name="UnhandledException" type="Modules.Log.UnhandledException"/>
</modules>
using System.Web;

namespace Modules.Log
{
    using System;
    using System.Text;

    public class LogModule : IHttpModule
    {
        private bool initialized = false;
        private object initLock = new Object();
        private static string applicationName = string.Format("Server: {0}; [LogModule_AppName] installation name is not set", System.Environment.MachineName);

        public void Dispose()
        {
        }

        public void Init(HttpApplication context)
        {
            // Do this one time for each AppDomain.
            if (!initialized)
            {
                lock (initLock)
                {
                    if (!initialized)
                    {
                        context.Error += new EventHandler(this.OnUnhandledApplicationException);

                        initialized = true;
                    }
                }
            }
        }

        private void OnUnhandledApplicationException(object sender, EventArgs e)
        {
            StringBuilder message = new StringBuilder("<html><head><style>" +
                "body, table { font-size: 12px; font-family: Arial, sans-serif; }\r\n" +
                "table tr td { padding: 4px; }\r\n" +
                ".header { font-weight: 900; font-size: 14px; color: #fff; background-color: #2b4e74; }\r\n" +
                ".header2 { font-weight: 900; background-color: #c0c0c0; }\r\n" +
                "</style></head><body><table><tr><td class=\"header\">\r\n\r\nUnhandled Exception logged by LogModule.dll:\r\n\r\nappId=");

            string appId = (string)AppDomain.CurrentDomain.GetData(".appId");
            if (appId != null)
            {
                message.Append(appId);
            }

            message.Append("</td></tr>");

            HttpServerUtility server = HttpContext.Current.Server;
            Exception currentException = server.GetLastError();

            if (currentException != null)
            {
                message.AppendFormat(
                        "<tr><td class=\"header2\">TYPE</td></tr><tr><td>{0}</td></tr><tr><td class=\"header2\">REQUEST</td></tr><tr><td>{3}</td></tr><tr><td class=\"header2\">MESSAGE</td></tr><tr><td>{1}</td></tr><tr><td class=\"header2\">STACK TRACE</td></tr><tr><td>{2}</td></tr>",
                        currentException.GetType().FullName,
                        currentException.Message,
                        currentException.StackTrace,
                        HttpContext.Current != null ? HttpContext.Current.Request.FilePath : "n/a");
                server.ClearError();
            }

            message.Append("</table></body></html>");

            HttpContext.Current.Response.Write(message.ToString());
            server.ClearError();
        }
    }
}