如何检查异步Web服务调用中的错误

时间:2009-02-26 09:17:39

标签: c# web-services asynchronous error-handling

我正在开发ASP.Net asmx Web服务。在客户端,如果对服务器的请求返回Http错误代码,如http 500,我怎么能从Web服务客户端知道(我使用添加Web引用自动生成的客户端代理)?

提前谢谢, 乔治

6 个答案:

答案 0 :(得分:1)

George,因为您正在使用异步WS调用,所以必须在回调方法中实现异常处理。 例如: 以下是我开发的示例代码,用于演示异步委托。

public class TransformDelegateWithCallBack
{
    /// <summary>
    /// Delegate which points to AdapterTransform.ApplyFullMemoryTransformations()
    /// </summary>
    /// <param name="filename">Transformation file name</param>
    /// <param name="rawXml">Raw Xml data to be processed</param>
    /// <param name="count">Variable used to keep a track of no of async delegates</param>
    /// <returns>Transformed XML string</returns>
    public delegate string DelegateApplyTransformations(string filename, string rawXml, int count);

    public ArrayList resultArray;


    //// Declare async delegate and result
    DelegateApplyTransformations delegateApplyTransformation;
    IAsyncResult result;

    /// <summary>
    /// Constructor to initialize the async delegates, results and handles to the no of tabs in excel
    /// </summary>
    public TransformDelegateWithCallBack()
    {
        resultArray = ArrayList.Synchronized(new ArrayList());
    }


    /// <summary>
    /// Invoke the async delegates with callback model
    /// </summary>
    /// <param name="filename">Transformation file name</param>
    /// <param name="rawXml">Raw Xml data to be processed</param>
    /// <param name="count">Variable used to keep a track of no of async delegates</param>
    public void CallDelegates(string fileName, string rawXml, int count)
    {
        try
        {
            AdapterTransform adapterTrans = new AdapterTransform();
            // In the below stmt, adapterTrans.ApplyFullMemoryTransformations is the web method being called
            delegateApplyTransformation = new DelegateApplyTransformations(adapterTrans.ApplyFullMemoryTransformations);
            // The below stmt places an async call to the web method
            // Since it is an async operation control flows immediately to the next line eventually coming out of the current method. Hence exceptions in the web service if any will NOT be caught here.
            // CallBackMethod() is the method that will be called automatically after the async operation is done
            // result is an IAsyncResult which will be used in the CallBackMethod to refer to this delegate
            // result gets passed to the CallBackMethod 
            result = delegateApplyTransformation.BeginInvoke(fileName, rawXml, count, new AsyncCallback(CallBackMethod), null);
        }
        catch (CustomException ce)
        {
            throw ce;
        }
    }

    /// <summary>
    /// Callback method for async delegate
    /// </summary>
    /// <param name="o">By default o will always have the corresponding AsyncResult</param>
    public void CallBackMethod(object o)
    {

        try
        {
            AsyncResult asyncResult = (AsyncResult)o;
            // Now when you do an EndInvoke, if the web service has thrown any exceptions, they will be caught
            // resultString is the value the web method has returned. (Return parameter of the web method)
            string resultString = ((DelegateApplyTransformations)asyncResult.AsyncDelegate).EndInvoke((IAsyncResult)asyncResult);

            lock (this.resultArray.SyncRoot)
            {
                this.resultArray.Add(resultString);
            }
        }
        catch (Exception ex)
        {
            // Handle ex
        }
    }

}

如果您的WS调用正在抛出异常,那么只有在AsynResult上执行EndInvoke时才会捕获它。如果您正在使用火灾和忘记异步WS调用的机制,你不会调用EndInvoke,因此异常将丢失。因此,当您需要捕获异常时,请始终使用回调机制 希望这有帮助:)

如果您有任何疑问,请告诉我。

答案 1 :(得分:0)

您可以为您的网络服务设置跟踪,MSDN下面的方法如下:

http://msdn.microsoft.com/en-us/library/bb885203.aspx

如果您也可以访问服务器,则可以设置HealthMonitoring,例如,它将记录服务器端发生的任何错误,就像您发布500内部服务器错误一样。

健康监测 - http://msdn.microsoft.com/en-us/library/ms998306.aspx

如果您可以远程登录或登录服务器,也可以使用有用的事件查看器。

希望这会有所帮助:

安德鲁

答案 2 :(得分:0)

您可以从e.Response.GetResponseStream()获取信息。正如读者所说,您可能需要查看服务器端以获取更完整的信息。

答案 3 :(得分:0)

这是一个常见的问题,因为Web服务只会在遇到未处理的异常时向您发送HTTP 500(内部服务器错误)消息。我用了一个很久以前发现的技巧。基本上,您需要使用StreamReader钻取WebException以确定异常的根本原因。

示例代码:(抱歉,没有任何C#代码方便。请使用转换器)

Try
  'Hit the webservice.
Catch ex As WebException
  Dim r As HttpWebResponse = CType(ex.Response(), HttpWebResponse)
  Using sr As StreamReader = New StreamReader(r.GetResponseStream())
    Dim err As String = sr.ReadToEnd()
    'Log the error contained in the "err" variable.
  End Using
  Return Nothing
Finally
  'Clean up  
End Try

可以使用我强烈推荐的DeveloperFusion converter进行转换。

答案 4 :(得分:0)

请参阅上一个问题easy-way-to-catch-all-unhandled-exceptions-in-c-net

对于在IIS下运行的Web服务,您似乎需要通过实现UnhandledExceptionModule来捕获所有线程中的异常。

答案 5 :(得分:0)

假设您使用Visual Studio导入Web服务并使用Microsoft Web Services Enhancement 3.0库,它可能看起来像这样:

 private void DoWebService()
 {
      try
      {
           MyWebService.MyWebserviceWSE WSE = new MyWebService.MyWebserviceWSE.MyWebserviceWSE();

           WSE.DoSomethingCompleted += new MyWebService.DoSomethingCompletedEventHandler(WSE_DoSomethingCompleted);

           WSE.DoSomethingAsync(/* pass arguments to webservice */);            
      }
      catch (Exception ex)
      {
           // Handle errors
      }
 }

 private void WSE_DoSomethingCompleted(object o, MyWebService.DoSomethingCompletedEventArgs args)
 {
      if (args.Error != null)
      {
           // The following gets the error and shows it in a msg box
           StringBuilder sb = new StringBuilder();

           sb.AppendLine(args.Error.ToString());

           if (args.Error.InnerException != null)
           {
               sb.AppendLine(args.Error.ToString());
           }

           MessageBox.Show(sb.ToString());
      }
      else
      {
           // Do something with the results
      }
 }

任何错误都将在'MyWebService.DoSomethingCompletedEventArgs'对象中返回。