У меня есть набор веб-служб WCF, динамически подключаемых к настольному приложению.
Моя проблема - это действительно подробные настройки конфигурации, которые требуются WCF для работы. Чтобы заставить SSL работать, требуются индивидуальные настройки. Чтобы заставить работать MTOM или что-нибудь еще, требуется больше. Вы хотите компрессию? Это снова мы...
WCF действительно мощный инструмент - вы можете использовать множество различных способов подключения, но все они требуют детальной настройки. Если хост и клиент не совпадают идеально, вам будет сложно расшифровать ошибки.
Я хочу упростить настройку настольного приложения - в идеале, с автоматическим обнаружением. Пользователи настольного приложения должны просто иметь возможность ввести URL-адрес, а он сделает все остальное.
Кто-нибудь знает хороший способ это сделать?
Я знаю, что Visual Studio может настроить конфигурацию для вас, но я хочу, чтобы настольное приложение могло делать это на основе большого количества различных настроек сервера.
Я знаю, что инструменты VS можно использовать извне, но я ищу пользователей настольных приложений, которые не должны быть экспертами по WCF. Я знаю, что М.С. сделал это намеренно слишком сложным.
Есть ли способ, механизм, сторонняя библиотека или что-то еще, чтобы сделать возможным автоматическое обнаружение настроек WCF?
Может это несправедливо. MS намеренно сделала так, чтобы каждый параметр, который вы когда-либо хотели изменить, мог быть, но вам потребовались бы книга WCF и опыт программирования, чтобы настроить основы.





Вся информация о конечной точке доступна в метаданных службы, вы можете написать клиенту, который будет исследовать метаданные службы и настраивать клиента. В качестве примера кода вы можете посмотреть этот превосходный Mex Explorer от Juval Lowy.
Спасибо, это был полезный код (+1).
Это более чем немного запутано, имеет некоторые ошибки (например, проверки с учетом регистра, которых не должно быть), имеет множество функций пользовательского интерфейса, которые мне не нужны, и повторяет много кода.
Я взял из него реальный механизм обнаружения, переписал его и почти заставил его работать (подключается, но требует некоторой доработки).
Сначала некоторые служебные функции, используемые основным методом:
/// <summary>If the url doesn't end with a WSDL query string append it</summary>
static string AddWsdlQueryStringIfMissing( string input )
{
return input.EndsWith( "?wsdl", StringComparison.OrdinalIgnoreCase ) ?
input : input + "?wsdl";
}
/// <summary>Imports the meta data from the specified location</summary>
static ServiceEndpointCollection GetEndpoints( BindingElement bindingElement, Uri address, MetadataExchangeClientMode mode )
{
CustomBinding binding = new CustomBinding( bindingElement );
MetadataSet metadata = new MetadataExchangeClient( binding ).GetMetadata( address, mode );
return new WsdlImporter( metadata ).ImportAllEndpoints();
}
Затем метод, который пробует другой способ подключения и возвращает конечные точки:
public static ServiceEndpointCollection Discover( string url )
{
Uri address = new Uri( url );
ServiceEndpointCollection endpoints = null;
if ( string.Equals( address.Scheme, "http", StringComparison.OrdinalIgnoreCase ) )
{
var httpBindingElement = new HttpTransportBindingElement();
//Try the HTTP MEX Endpoint
try { endpoints = GetEndpoints( httpBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
catch { }
//Try over HTTP-GET
if ( endpoints == null )
endpoints = GetEndpoints( httpBindingElement,
new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
}
else if ( string.Equals( address.Scheme, "https", StringComparison.OrdinalIgnoreCase ) )
{
var httpsBindingElement = new HttpsTransportBindingElement();
//Try the HTTPS MEX Endpoint
try { endpoints = GetEndpoints( httpsBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
catch { }
//Try over HTTP-GET
if ( endpoints == null )
endpoints = GetEndpoints( httpsBindingElement,
new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
}
else if ( string.Equals( address.Scheme, "net.tcp", StringComparison.OrdinalIgnoreCase ) )
endpoints = GetEndpoints( new TcpTransportBindingElement(),
address, MetadataExchangeClientMode.MetadataExchange );
else if ( string.Equals( address.Scheme, "net.pipe", StringComparison.OrdinalIgnoreCase ) )
endpoints = GetEndpoints( new NamedPipeTransportBindingElement(),
address, MetadataExchangeClientMode.MetadataExchange );
return endpoints;
}
Теперь есть другой способ сделать это, которого не было, когда я задавал исходный вопрос. Microsoft теперь поддерживает REST для служб WCF.
Вам понадобится новая ссылка на System.ServiceModel.Web
Отметьте свои операции знаком WebInvoke или WebGet
//get a user - note that this can be cached by IIS and proxies
[WebGet]
User GetUser(string id )
//post changes to a user
[WebInvoke]
void SaveUser(string id, User changes )
Добавить их на сайт очень просто - добавьте файл .svc:
<%@ServiceHost
Service = "MyNamespace.MyServiceImplementationClass"
Factory = "System.ServiceModel.Activation.WebServiceHostFactory" %>
Строка factory сообщает ASP.net, как активировать конечную точку - вам вообще не нужна конфигурация на стороне сервера!
Затем создание вашего ChannelFactory практически не изменилось, за исключением того, что вам больше не нужно указывать конечную точку (или автоматически обнаруживать ее, как я в других ответах)
var cf = new WebChannelFactory<IMyContractInterface>();
var binding = new WebHttpBinding();
cf.Endpoint.Binding = binding;
cf.Endpoint.Address = new EndpointAddress(new Uri("mywebsite.com/myservice.svc"));
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
IMyContractInterface wcfClient = cf.CreateChannel();
var usr = wcfClient.GetUser("demouser");
// and so on...
Обратите внимание, что я не указал и не обнаружил конфигурацию клиента - локальная конфигурация не требуется!
Еще одним большим преимуществом является то, что вы можете легко переключиться на сериализацию JSON, что позволяет использовать одни и те же службы WCF для Java, ActionScript, Javascript, Silverlight или чего-либо еще, что может легко обрабатывать JSON и REST.
Я также писал в блоге, почему это изменилось: bizvprog.blogspot.com/2009/11/giving-up-on-soap-for-good.htm l
"Я знаю, что MS сделал это намеренно слишком сложным" [необходима цитата]