WCF, выбрасывающий CommunicationException, когда выдается FaultException - PullRequest
3 голосов
/ 01 июля 2011

Решение:

Небольшое отслеживание показало, что CommunicationException выбрасывалось, потому что была проблема с моим исключением T, не сериализовавшаяся правильно; потому что, в два слоя, у меня был анонимно напечатанный объект, который нельзя было разобрать. Удаление и всплывание изменений, казалось, исправили это. Было кое-что еще маленькое, что я делал до этого, но я не могу вспомнить, что это было, только то, что это не было сделано в конфигурации.

Я получал сообщения от моих следов, таких как:

Type 'RebuiltWCFService.Requests.HelloWorldRequest' with data contract name 'HelloWorldRequest:http://schemas.datacontract.org/2004/07/RebuiltWCFService.Requests' is not expected. 
Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Оригинальный пост

Сегодня я столкнулся с странной проблемой, на которую просто не могу найти ответ!

Проблема: мой сервис вызывает исключение CommunicationException, когда я генерирую исключение FaultException! Это не делает это, если я не выбрасываю исключение.

В моем сервисе я правильно определяю договоры о неисправности:

[OperationContract]
[FaultContract(typeof(Faults.HelloWorldFault))]
Responses.HelloWorldResponse HelloWorld(Requests.HelloWorldRequest parameter);

Тогда в условиях ошибки я выкидываю исключение правильного типа:

if (_errors.Count() > 0)
{
    Faults.HelloWorldFault fault = new Faults.HelloWorldFault(_errors);
    throw new FaultException<Faults.HelloWorldFault>(fault, new FaultReason("There are one or more errors in the request. Check the 'Errors' property for more detaisl"));
}

А потом я ловлю его на стороне клиента:

try
{
    response = client.HelloWorld(new BasicService.HelloWorldRequest() { Number = 49 });
    client.Close();
    Console.WriteLine(String.Format("Response message: {0}, Response number: {1}", response.Message, response.Number));
}
catch (FaultException<BasicService.HelloWorldFault> ex)
{
    ...
}

Мне кажется, что все в порядке, и вроде все должно работать. Однако, как только я иду, чтобы проверить мои предложения об ошибках (предоставляя неверные данные, такие как пропущенное поле), все это умирает от меня. Когда я выбрасываю свое FaultException, служба вместо этого выдает CommunicationException с сообщением

An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/RebuiltWCFService/Service1/. 
This could be due to the service endpoint binding not using the HTTP protocol. 
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). 
See server logs for more details.

Кто-нибудь может предложить какое-то понимание этого? Я использую привязку basicHttp, и я также попробовал это с wsHttp. Я опубликую свой конфигурационный файл по запросу.

Ответы [ 3 ]

6 голосов
/ 01 июля 2011

FaultException является дочерним элементом CommunicationException.Так что в том, что происходит в вашем коде, нет ничего плохого.

Если вы не уверены, что такое исключение во время обработки, оно обычно сообщается как CommunicationException.Если вы хотите обработать ваше конкретное исключение по-своему, используйте следующую структуру:

try
{ ... }
catch (FaultException<MyDemoException> me)
{ ... }
catch (FaultException fe)
{ ... }
catch (CommunicationException ce)
{ ... }
catch (Exception ex)
{ ... }

В приведенной выше структуре Exception является родителем CommunicationException.CommunicationException является родителем FaultException и т. Д.

System.Object 
  System.Exception
    System.SystemException
      System.ServiceModel.CommunicationException
        System.ServiceModel.FaultException
          System.ServiceModel.FaultException<TDetail>
            System.ServiceModel.Web.WebFaultException<T>
0 голосов
/ 05 декабря 2013

Я столкнулся с этой проблемой, потому что у меня была одна или несколько точек останова в неправильном месте. Я удалил все точки останова с помощью Debug..Delete all Breakpoints (Ctrl-Alt-F9), и все исключения CommunicationException исчезли и были заменены правильными сообщениями, возвращающимися.

Да, тайм-аут составляет 60 секунд, поэтому этого не должно было произойти, так что, возможно, это был какой-то странный артефакт Visual Studio 2012.

0 голосов
/ 02 декабря 2013

Спасибо, ребята, вы помогли мне лучше понять проблему. Мое наблюдение: я сохранил List MyData - для хранения любой универсальной / динамической коллекции, которая не могла быть сериализована, в результате чего закрылось соединение, поэтому коммуникационное исключение.

Когда я удалил Список из Fault Contract и выбрал Fault style, он явно давал исключение Fault Contract, а не исключение связи.

Надеюсь, это поможет, HydTechie.

...