Поддержка Mtom и Text как MessageEncoding в WCF
У меня есть служба WCF, которая имеет метод со следующей подписью:
object GetCommand(Guid apiKey, SocialService service, string name, object argument);
Причина, по которой он работает с объектами как с типом возвращаемого значения, так и с последним аргументом, заключается в том, что должна быть возможность передавать любой тип в качестве аргумента и возвращать любой тип.
В любом случае, я передаю объект, который содержит следующее свойство:
public byte[] Photo { get; set; }
Чтобы включить большие сообщения, я бы хотел начать использовать Mtom, в то время как ранее я использовал обычный текст в качестве типа MessageEncoding.
Проблема в том, что я хочу, чтобы он был обратно совместим, поэтому текущие клиенты с уже настроенными настройками должны продолжать использовать кодировку в виде простого текста, в то время как новые клиенты должны иметь возможность использовать Mtom через web.config.
Мой вопрос: возможно ли по-прежнему использовать обычный текст в качестве MessageEncoding (по умолчанию для существующих клиентов) и предлагать кодирование Mtom одновременно?
Я пробовал кое-что с конфигурацией, например, определение нескольких конечных точек с разными конфигурациями связывания, но я не могу заставить его работать:
сервер
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpTextBinding_SocialProxy" />
<binding name="BasicHttpMtomBinding_SocialProxy" maxReceivedMessageSize="5242880" messageEncoding="Mtom">
<readerQuotas maxStringContentLength="655360" maxArrayLength="1310720" maxNameTableCharCount="1310720" maxBytesPerRead="327680" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="SocialProxyService">
<endpoint name="BasicEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpTextBinding_SocialProxy" />
<endpoint name="MtomEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpMtomBinding_SocialProxy" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
клиент
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_SocialProxy" messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://socialproxy.local/socialproxy.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SocialProxy"
contract="Webservice.SocialProxy" name="BasicHttpBinding_SocialProxy" />
</client>
</system.serviceModel>
Проблема в следующем:
Если я не установлю Mtom messageEncoding @ клиент, все работает через обычный текст. Но когда я настрою его на использование Mtom, я получу исключение:
The remote server returned an error: (415) Cannot process the message because the content type 'multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:65a6b418-8eb3-4c76-b4c0-ea3486a56892+id=2";start-info="text/xml"' was not the expected type 'text/xml; charset=utf-8'..
Кто-нибудь может мне помочь?:-)
1 ответ
Если вы хотите добавить новую конечную точку (для новых клиентов), эта конечная точка должна находиться по другому адресу. Так как вы не получили никакой ошибки, я полагаю, у вас неверное имя в name
атрибут <service>
элемент. Помните, что атрибут name должен содержать полное имя класса обслуживания. Если ваш класс обслуживания находится в пространстве имен InfoCaster.SocialProxy
, ваша конфигурация сервиса должна быть определена как ниже:
<services>
<service name="InfoCaster.SocialProxy.SocialProxyService">
<endpoint name="BasicEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpTextBinding_SocialProxy" />
<endpoint name="MtomEndpoint_SocialProxy" address="newClients" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpMtomBinding_SocialProxy" />
</service>
</services>
И клиенты будут иметь что-то вроде
<client>
<endpoint address="http://socialproxy.local/socialproxy.svc/newClients"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SocialProxy"
contract="Webservice.SocialProxy" name="BasicHttpBinding_SocialProxy" />
</client>
Теперь, если вам нужна одна конечная точка, которая может поддерживать как текст, так и MTOM таким образом, чтобы клиенты, отправляющие текст, получали текстовый ответ, а клиенты, отправляющие MTOM, получали ответ MTOM обратно, вы все равно можете это сделать. Вам понадобится пользовательский кодировщик, и я написал его в посте по адресу http://blogs.msdn.com/b/carlosfigueira/archive/2011/02/16/using-mtom-in-a-wcf-custom-encoder.aspx.