服务器端捕捉asmx产生的未处理异常
项目中对于未处理异常的捕获是通过使用ApplicationErrorLog组件,但无论通过组件还是Global.asax或者自定义HttpModule都是通过在管道中截获异常信息,例如:
但是通过管道这种方式是不能截获asmx调用过程中产生的未处理异常的,所以只能使用别的小技巧来解决这个问题。因为项目统一使用ApplicationErrorLog来捕获未处理异常的,所以这里就不好添加另类的方式,影响统一性。现在处理的方式是把asmx产生的异常post到一个ashx页面来接收这个异常,然后在该页面抛出,这样就可能通过正常的httpmodule来截获了。
1、封装post操作
2、新建ashx页面(AsmxException.ashx)来接收post过来的异常
3、在asmx中调用方法
记得PostEx(ex)把发生的异常post到接收页面后还要再次抛出原来的异常,这样客户端才能正常收到原来的异常信息。
void Application_Error(object sender, EventArgs e)
{
Logger.log(ex.Message);
Logger.log(ex.StackTrace);
if (ex.InnerException != null)
{
Logger.log(ex.InnerException.Message);
Logger.log(ex.InnerException.StackTrace);
}
}
{
Logger.log(ex.Message);
Logger.log(ex.StackTrace);
if (ex.InnerException != null)
{
Logger.log(ex.InnerException.Message);
Logger.log(ex.InnerException.StackTrace);
}
}
但是通过管道这种方式是不能截获asmx调用过程中产生的未处理异常的,所以只能使用别的小技巧来解决这个问题。因为项目统一使用ApplicationErrorLog来捕获未处理异常的,所以这里就不好添加另类的方式,影响统一性。现在处理的方式是把asmx产生的异常post到一个ashx页面来接收这个异常,然后在该页面抛出,这样就可能通过正常的httpmodule来截获了。
1、封装post操作
protected void PostEx(Exception ex)
{
string message = ex.ToJSON();
string postData = string.Format("Error={0}&id={1}", message, Guid.NewGuid());
byte[] data = Encoding.UTF8.GetBytes(postData);
string url = string.Format("http://{0}/Admin/AsmxException.ashx", ConfigurationManager.AppSettings["ProxyHost"]);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
request.Timeout = 500;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
requestStream.Close();
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){}
}
catch (System.Net.WebException) { }
}
{
string message = ex.ToJSON();
string postData = string.Format("Error={0}&id={1}", message, Guid.NewGuid());
byte[] data = Encoding.UTF8.GetBytes(postData);
string url = string.Format("http://{0}/Admin/AsmxException.ashx", ConfigurationManager.AppSettings["ProxyHost"]);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
request.Timeout = 500;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
requestStream.Close();
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){}
}
catch (System.Net.WebException) { }
}
2、新建ashx页面(AsmxException.ashx)来接收post过来的异常
public class AsmxException : IHttpHandler {
public void ProcessRequest (HttpContext context) {
string message = context.Request.Form["Error"];
Exception ex = message.ParseJSON<Exception>();
throw ex;
}
public bool IsReusable { get { return false; } }
}
public void ProcessRequest (HttpContext context) {
string message = context.Request.Form["Error"];
Exception ex = message.ParseJSON<Exception>();
throw ex;
}
public bool IsReusable { get { return false; } }
}
3、在asmx中调用方法
[WebMethod(MessageName = "UpdatingContent", Description = "", EnableSession = false)]
[SoapHeader("Credentials")]
public void UpdatingContent(string identity)
{
try
{
InnerValidate();
this.NotifyUpdating(Credentials.SourceID, Credentials.HandleMode, Credentials.CallbackProtocol,
Credentials.UpdatingType, Credentials.INotifyHandlerImpl, identity);
}
catch (Exception ex)
{
PostEx(ex);
throw ex;
}
}
[SoapHeader("Credentials")]
public void UpdatingContent(string identity)
{
try
{
InnerValidate();
this.NotifyUpdating(Credentials.SourceID, Credentials.HandleMode, Credentials.CallbackProtocol,
Credentials.UpdatingType, Credentials.INotifyHandlerImpl, identity);
}
catch (Exception ex)
{
PostEx(ex);
throw ex;
}
}
记得PostEx(ex)把发生的异常post到接收页面后还要再次抛出原来的异常,这样客户端才能正常收到原来的异常信息。