Как проверить ошибки при вызовах асинхронных веб-служб

Я разрабатываю веб-службы ASP.Net asmx. А на стороне клиента, если запрос к серверу возвращает код ошибки Http, например http 500, как я могу узнать со стороны клиента веб-служб (я использую автоматически сгенерированный клиентский прокси, добавляя веб-ссылки)?

заранее спасибо, Джордж

Ответов (6)

См. Предыдущий вопрос, easy-way-to-catch-all-unhandled-exceptions-in-c-net .

Для веб-служб, работающих под IIS, может показаться, что вам нужно перехватывать исключения во всех потоках, реализуя UnhandledExceptionModule.

Вы можете получить информацию из e.Response.GetResponseStream (). Как уже говорилось, вам может потребоваться посмотреть на стороне сервера, чтобы получить более полную информацию.

Это часто встречающаяся проблема, поскольку веб-службы обычно отправляют вам сообщение HTTP 500 (внутренняя ошибка сервера) только при обнаружении необработанного исключения. Я использую уловку, которую нашел давно. По сути, вам нужно детализировать WebException с помощью StreamReader, чтобы определить основную причину исключения.

Пример кода: (К сожалению, у меня не было под рукой кода 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 , который я настоятельно рекомендую.

Вы можете настроить трассировку для своих веб-сервисов, как это сделать ниже из MSDN:

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

Если у вас также есть доступ к серверу, вы можете настроить HealthMonitoring, например, который будет записывать любые ошибки, возникающие на стороне сервера, например, вы опубликовали внутреннюю ошибку сервера 500.

Мониторинг работоспособности - http://msdn.microsoft.com/en-us/library/ms998306.aspx

У вас также есть когда-либо полезный просмотрщик событий, если вы можете удаленно или войти на сервер.

Надеюсь это поможет:

Эндрю

Джордж, поскольку вы используете асинхронные вызовы 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 генерирует исключение, он обнаруживается только тогда, когда вы выполняете EndInvoke для AsynResult. Если вы используете механизм запуска и забывания асинхронного вызова WS, вы не будете вызывать EndInvoke, и, следовательно, исключение будет потеряно. Поэтому всегда используйте механизм обратного вызова, когда вам нужно перехватывать исключения. Надеюсь, это поможет :)

Сообщите мне, если у вас возникнут еще какие-либо сомнения.

Предполагая, что у вас есть Visual Studio для импорта веб-сервиса и вы используете библиотеку 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.