Ловить пользовательское исключение, брошенный на веб-метод веб-сервиса ASP.NET

у меня есть классический asp.net веб-служба (asmx) и веб-метод в ней. Мне нужно создать пользовательское исключение для некоторого случая в моем веб-методе, и мне нужно поймать это конкретное пользовательское исключение, где я вызываю метод веб-службы.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    public HelloWorldOutput HelloWorld(HelloWorldInput input)
    {
        try
        {
            // My Code
            return new HelloWorldOutput();
        }
        catch (Exception ex)
        {
            throw new HelloWorldException("Hello World Exception", ex);
        }
    }
}

классы ввода, вывода и исключения в качестве примера:

public class HelloWorldInput { }
public class HelloWorldOutput { }    

[Serializable]
public class HelloWorldException : Exception
{
    public HelloWorldException() { }
    public HelloWorldException(string message) : base(message) { }
    public HelloWorldException(string message, Exception inner) 
        : base(message, inner) { }
    protected HelloWorldException(
      System.Runtime.Serialization.SerializationInfo info,
      System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { }
}

на стороне клиента, мне нужно:

public static void Main()
{
    WebService service = new WebService();
    try
    {
        service.HelloWorld(new HelloWorldInput());
    }
    catch (HelloWorldException ex)
    {
        // Do sth with HelloWorldException
    }
    catch (Exception ex)
    {
        // Do sth with Exception
    }
}

однако я не могу этого сделать, потому что, когда я добавляю ссылку на веб-службу на клиенте, у меня есть служба класса, входные и выходные классы, но у меня нет пользовательского класса исключения.

также другая проблема заключается в том, что у меня также есть проблемы с сериализацией класса исключений (из-за исключения.Свойство Data реализует интерфейс IDictionary)

есть ли способ сделать это на моем пути, или я совершенно неправильно, или есть что-то, что я пропустил Об основах веб-сервисов?

спасибо.

2 ответов


ASP.NET веб-служба может создавать исключения любого типа: SoapException, HelloWorldException или soever. Однако исключение сериализуется в элемент ошибки SOAP, и независимо от типа исключения, создаваемого в службе, исключение преобразуется в исключение SoapException во время десериализации. Следовательно, невозможно поймать исключение HelloWorldException с моим блоком catch в моем вопросе, даже если я развертываю исключение HelloWorldException клиенту.

для ASP.NET клиент, единственный способ-поймать исключение как SoapException и обработать его своим Actor или SoapFaultSubCode собственность.

Я в основном решил свою проблему, как показано ниже:

Веб-Сервиса:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    public HelloWorldOutput HelloWorld(HelloWorldInput input)
    {
        try
        {
            // My Code
            return new HelloWorldOutput();
        }
        catch (Exception ex)
        {
            throw new SoapException("Hello World Exception",   
                 SoapException.ServerFaultCode, "HelloWorld", ex);
        }
    }
}

клиент:

public static void Main()
{
    WebService service = new WebService();
    try
    {
        service.HelloWorld(new HelloWorldInput());
    }
    catch (SoapException ex)
    {
        if(ex.Actor == "HelloWorld")
            // Do sth with HelloWorldException
    }
    catch (Exception ex)
    {
        // Do sth with Exception
    }
}

вместе с документом, который Брайс Фишер написал в своем ответе; эти документы msdn также имеют полезную информацию о метании и обработке исключений веб-службы.

как: выбросить исключения из a Веб-служба, созданная с помощью ASP.NET

как: обрабатывать исключения, создаваемые методом веб-службы


этой может помочь. Похоже, вы получите SoapException, но вы можете проверить детали, чтобы определить, является ли это вашим классом или нет.

Примечание, чтобы иметь доступ к" HelloWorldException", вы можете вытащить его в отдельную сборку и развернуть ее на клиенте...