«Система.ServiceModel.CommunicationException «при попытке передать растровое изображение через WCF

#c# #wcf #bitmap

#c# #wcf #растровое изображение

Вопрос:

Я пытаюсь передать растровое изображение через WCF, но оно выдает

Система.ServiceModel.Исключение CommunicationException не было обработано пользовательским кодом
Сообщение = Соединение с сокетом было прервано. Это может быть вызвано ошибкой при обработке вашего сообщения или превышением времени ожидания приема удаленным хостом, или основной проблемой с сетевыми ресурсами. Время ожидания локального сокета составило ’00:00:59.9650000′.

Есть идеи, что может быть причиной этого?

Спасибо!

Ответ №1:

Причина в том, что Bitmap тип является специфичным для .NET типом (с множеством особенностей Win32 внутри него тоже), который не сериализуется в XML. На самом деле вы не можете передать его обратно в качестве параметра метода — что вы могли бы сделать, так это передать его обратно с параметром типа Stream и использовать потоковую передачу в WCF.

Или другим способом (если ваши растровые изображения не слишком большие) было бы преобразовать Bitmap в строку, используя кодировку Base64, отправить ее обратно в виде строки, а затем перекодировать ее на стороне клиента.

Комментарии:

1. Спасибо! Кодировка Base64 выглядит многообещающе, я попробую ее завтра.

2. Auch … нет, это нормально работает только с очень маленькими изображениями. Для преобразования изображения размером 0,5 Мб потребовалось более минуты.

Ответ №2:

Предполагая, что вы размещаете свою службу WCF в IIS (вы не упомянули никаких подробностей).

Попробуйте увеличить некоторые числа как в файлах конфигурации клиента, так и сервера (помните, что настройки должны совпадать).

 <binding name="Binding_ISomeervice" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
    hostNameComparisonMode="StrongWildcard" listenBacklog="1000"
    maxBufferPoolSize="524288" maxBufferSize="2147483647" maxConnections="100"
    maxReceivedMessageSize="2147483647">
  <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647"
    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
  

Также включите отладку в файле веб-конфигурации сервера:

 <system.web>
  <compilation debug="true" />
</system.web>
  

Если вы можете, поместите try / catch (с протоколированием) вокруг вашей реализации вызова службы, это сообщит вам, ваша ли реализация выдает ошибку или среда размещения выдает ошибку.

Ответ №3:

Хех, это одно из наиболее раздражающих сообщений от WCF. Я предполагаю, что размер сообщения слишком большой. Самый надежный способ, который я нашел, чтобы разобраться в этом, — использовать трассировку WCF, как описано вhttp://msdn.microsoft.com/en-us/library/ms733025.aspx и SvcTraceViewer.exe .

Ответ №4:

Мой ответ состоит из двух частей: рекомендации для этой ситуации и рекомендации по улучшению отчетов об ошибках и трассировки на будущее.

Поскольку вы имеете дело с растровыми изображениями, рассматривали ли вы возможность использования необработанной модели программирования WCF? В этом сообщении в блоге подробно описывается, как использовать модель программирования на стороне сервиса, а в следующем сообщении в блоге подробно описывается, как использовать ее на стороне клиента. Я видел, что это довольно часто использовалось для сценариев загрузки файлов и передачи изображений, так что это может помочь и в вашей ситуации!

CommunicationException является обобщенным и не раскрывает базовое исключение. В будущем, при сообщении об ошибках, я бы рекомендовал включить IncludeExceptionDetailInFaults (либо из ServiceBehaviorAttribute, либо из configuration behavior) на сервере, чтобы отправить информацию об исключении обратно клиенту, а затем подробно сообщить о полученном вложенном исключении.

Например:

 <behaviors> 
            <serviceBehaviors> 
                <behavior 
                    <serviceMetadata httpGetEnabled="true" /> 
                    <serviceDebug includeExceptionDetailInFaults="true" /> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 
  

Что касается включения трассировки, ниже приведен мой совет, который я уже вставил в несколько других ответов.

Как правило, как только вы это сделаете, вы получите гораздо больше информации о том, что происходит на стороне сервиса, и сможете довольно быстро диагностировать проблему.