Вопрос

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

Моя проблема заключается в очень подробных настройках конфигурации, которые требуются для работы WCF.Для работы SSL требуются пользовательские настройки.Чтобы MTOM или что-то еще работало, требуется нечто большее.Вам нужно сжатие?Это снова мы...

WCF действительно мощный инструмент — вы можете использовать множество различных способов подключения, но все они, похоже, требуют большого количества подробной настройки.Если хост и клиент не совпадают идеально, вам будет сложно расшифровать ошибки.

Я хочу сделать настольное приложение намного проще в настройке - в идеале, с помощью какого-то автоматического обнаружения.Пользователи настольного приложения должны иметь возможность просто ввести URL-адрес, а все остальное сделает приложение.

Кто-нибудь знает хороший способ сделать это?

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

Я знаю, что инструменты VS можно использовать извне, но я ищу пользователей настольных приложений, которые не обязательно должны быть экспертами WCF.Я знаю, что MS намеренно усложнила задачу.

Есть ли какой-либо способ, механизм, сторонняя библиотека или что-то еще, чтобы сделать возможным автоматическое обнаружение настроек WCF?

Это было полезно?

Решение

Вся информация о конечной точке доступна в метаданных сервиса, вы можете написать клиент, который будет исследовать метаданные сервиса и настраивать клиент.В качестве примера кода вы можете изучить этот отличный Мексиканский исследователь от Жюваля Лоуи.

Другие советы

Спасибо, это был полезный код (+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.

  • Недостатком использования REST является потеря WSDL.
  • Плюсом является минимальная конфигурация, и ваши контрактные интерфейсы 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" %>

Заводская строка сообщает 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top