Упрощение настройки WCF

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

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

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

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

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

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

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

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

"Я знаю, что MS сделал это намеренно слишком сложным" [необходима цитата]

Eric Schoonover 19.09.2008 10:36

Может это несправедливо. MS намеренно сделала так, чтобы каждый параметр, который вы когда-либо хотели изменить, мог быть, но вам потребовались бы книга WCF и опыт программирования, чтобы настроить основы.

Keith 19.09.2008 16:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
14
2
11 088
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вся информация о конечной точке доступна в метаданных службы, вы можете написать клиенту, который будет исследовать метаданные службы и настраивать клиента. В качестве примера кода вы можете посмотреть этот превосходный 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.

  • Обратной стороной использования 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" %>

Строка 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

Keith 02.12.2009 19:47

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