Pergunta

Eu tenho uma operação simples de serviço da web como esta:

    [WebMethod]
    public string HelloWorld()
    {
        throw new Exception("HelloWorldException");
        return "Hello World";
    }

E então eu tenho um aplicativo cliente que consome o serviço web e depois chama a operação.Obviamente, isso lançará uma exceção :-)

    try
    {
        hwservicens.Service1 service1 = new hwservicens.Service1();
        service1.HelloWorld();
    }
    catch(Exception e)
    {
        Console.WriteLine(e.ToString());
    }

No meu bloco catch, o que eu gostaria de fazer é extrair a mensagem da exceção real para usá-la no meu código.A exceção capturada é uma SoapException, o que é bom, mas é Message imóvel é assim...

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: HelloWorldException
   at WebService1.Service1.HelloWorld() in C:\svnroot\Vordur\WebService1\Service1.asmx.cs:line 27
   --- End of inner exception stack trace ---

...e a InnerException é null.

O que eu gostaria de fazer é extrair o Message propriedade do InnerException (o HelloWorldException texto na minha amostra), alguém pode ajudar com isso?Se você puder evitá-lo, não sugira analisar o Message propriedade do SoapException.

Foi útil?

Solução

Infelizmente não acho que isso seja possível.

A exceção que você está levantando no código do seu serviço da web está sendo codificada em uma falha de sabão, que é então passada como uma string de volta ao seu código do cliente.

O que você vê na mensagem SoapException é simplesmente o texto da falha do Soap, que não está sendo convertido novamente em uma exceção, mas apenas armazenado como texto.

Se você deseja retornar informações úteis em condições de erro, recomendo retornar uma classe personalizada do seu serviço da web que pode ter uma propriedade "Erro" que contém suas informações.

[WebMethod]
public ResponseClass HelloWorld()
{
  ResponseClass c = new ResponseClass();
  try 
  {
    throw new Exception("Exception Text");
    // The following would be returned on a success
    c.WasError = false;
    c.ReturnValue = "Hello World";
  }
  catch(Exception e)
  {
    c.WasError = true;
    c.ErrorMessage = e.Message;
    return c;
  }
}

Outras dicas

Isto É possível!

Exemplo de operação de serviço:

try
{
   // do something good for humanity
}
catch (Exception e)
{
   throw new SoapException(e.InnerException.Message,
                           SoapException.ServerFaultCode);
}

Cliente consumindo o serviço:

try
{
   // save humanity
}
catch (Exception e)
{
   Console.WriteLine(e.Message);    
}

Apenas uma coisa - você precisa definir customErrors mode='RemoteOnly' ou 'On' em seu web.config (do projeto de serviço).

créditos sobre a descoberta customErrors - http://forums.asp.net/t/236665.aspx/1

Encontrei algo semelhante há pouco e blogou sobre isso.Não tenho certeza se é precisamente aplicável, mas pode ser.O código é bastante simples quando você percebe que precisa passar por um objeto MessageFault.No meu caso, eu sabia que o detalhe continha um GUID que eu poderia usar para consultar novamente o serviço SOAP para obter detalhes.O código fica assim:

catch (FaultException soapEx)
{
    MessageFault mf = soapEx.CreateMessageFault();
    if (mf.HasDetail)
    {
        XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
        Guid g = reader.ReadContentAsGuid();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top