Конфигурация WCF без файла конфигурации

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

Прежде чем кто-нибудь спросит, у меня очень конкретная потребность сделать это без файлов конфигурации. Обычно я бы не рекомендовал такую ​​практику, но, как я уже сказал, в этом случае есть очень конкретная потребность.


person Kilhoffer    schedule 10.09.2008    source источник
comment
Почему бы вам не порекомендовать такую ​​практику (программное раскрытие службы без конфигурации)?   -  person BornToCode    schedule 24.11.2014


Ответы (7)


Как я обнаружил, использование веб-службы без файла конфигурации очень просто. Вам просто нужно создать объект привязки и объект адреса и передать их либо конструктору клиентского прокси, либо универсальному экземпляру ChannelFactory. Вы можете посмотреть файл app.config по умолчанию, чтобы узнать, какие настройки использовать, а затем создать где-нибудь статический вспомогательный метод, который создает экземпляр вашего прокси:

internal static MyServiceSoapClient CreateWebServiceInstance() {
    BasicHttpBinding binding = new BasicHttpBinding();
    // I think most (or all) of these are defaults--I just copied them from app.config:
    binding.SendTimeout = TimeSpan.FromMinutes( 1 );
    binding.OpenTimeout = TimeSpan.FromMinutes( 1 );
    binding.CloseTimeout = TimeSpan.FromMinutes( 1 );
    binding.ReceiveTimeout = TimeSpan.FromMinutes( 10 );
    binding.AllowCookies = false;
    binding.BypassProxyOnLocal = false;
    binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    binding.MessageEncoding = WSMessageEncoding.Text;
    binding.TextEncoding = System.Text.Encoding.UTF8;
    binding.TransferMode = TransferMode.Buffered;
    binding.UseDefaultWebProxy = true;
    return new MyServiceSoapClient( binding, new EndpointAddress( "http://www.mysite.com/MyService.asmx" ) );
}
person devios1    schedule 15.11.2008
comment
Мне лично нравится этот подход для примеров, когда вы собираетесь использовать файл в другом деле, например, если вы зашифровали свой app.config (или эквивалентный файл конфигурации) и вам не нужно использовать встроенный WCF возможности чтения в соединении - person Noah; 05.12.2008
comment
Для использования https добавьте привязку.Security.Mode = BasicHttpSecurityMode.Transport; - person ciscoheat; 25.08.2010
comment
У меня это сработало. Единственное отличие для меня в том, что я также установил ReaderQuotas и информацию о безопасности. Я воспользовался советом ciscoheat и установил Security.Transport.Mode на Transport при использовании https (для меня это не известно во время компиляции). - person Kirk Liemohn; 08.11.2010
comment
Я только что проверил, что все устанавливаемые свойства соответствуют значениям по умолчанию в WCF 4, fwiw. (Но обратите внимание, что Security.Mode по умолчанию None.) - person ladenedge; 12.12.2011

Если вас интересует отказ от использования раздела System.ServiceModel в web.config для хостинга IIS, я разместил здесь пример того, как это сделать (http://bejabbers2.blogspot.com/02/2010/wcf-zero-config-in-net-35-part-ii.html). Я показываю, как настроить ServiceHost для создания как метаданных, так и конечных точек привязки wshttp. Я делаю это универсальным способом, не требующим дополнительного программирования. Для тех, кто не обновляется сразу до .NET 4.0, это может быть очень удобно.

person John Wigger    schedule 26.02.2010
comment
Джон, я уверен, что это отличный пост в блоге, но, поскольку есть принятый ответ от 17 месяцев назад, действительно ли есть какой-то смысл в вашем ответе? - person John Saunders; 27.02.2010
comment
Поскольку это мой первый ответ на вопрос о переполнении стека, который может быть не таким, как обычно. Поскольку я знаком с книгами Лоуи и Бустаманте, которые являются отличными справочными материалами, я думаю, что мой ответ выходит далеко за рамки предлагаемых ими образцов. Я в основном использую Stack Overflow при поиске в Google, поэтому я часто читаю более старые сообщения. Наличие более свежих ответов помогает только с моей точки зрения. Я погуглил этот пост перед написанием кода, чтобы не изобретать колесо заново. - person John Wigger; 27.02.2010
comment
хорошо, но когда вы прочитаете FAQ (stackoverflow.com/faq, ссылка на него есть на каждой странице), вы обнаружите, что это сайт вопросов и ответов , а не дискуссионный форум. Для этого Q уже было много пятнадцати месяцев назад, так что ИМХО, это под вопросом. - person John Saunders; 27.02.2010
comment
вы можете узнать, meta.stackexchange.com/questions/40696/, где я использовал ваше сообщение в качестве примера. - person John Saunders; 27.02.2010
comment
Как частый пользователь SO, я считаю весьма желательным читать новые сообщения по старым темам. Это помогает мне лучше выполнять свою работу, что увеличивает ценность этого сайта (поскольку я и другие люди будут его чаще посещать). Вместо того, чтобы быть приверженцем правил, почему бы не позволить людям обсуждать, чтобы можно было найти лучшие ответы? Разве не в этом суть? - person ; 11.06.2011
comment
Кажется, Джон Сондерс был поставлен на его место с ответом на свой вопрос (ни один из которых он не принял в качестве ответа, я мог бы добавить). У меня лично нет проблем с поздними ответами на вопросы, и обычно я рад видеть новый ответ на заданный мною вопрос, спустя месяцы, если не годы. По иронии судьбы, я заработал свой собственный значок Некроманта с принятым ответом на этот самый вопрос. :) - person devios1; 19.01.2012
comment
У меня была такая же проблема, и принятый ответ мне не помог, но это помогло, ура за поздние ответы! Если бы не было запоздалых ответов, мне бы пришлось создать дублирующий вопрос об этом. - person Didier A.; 09.03.2012

Вот и полный рабочий код. Я думаю, это вам очень поможет. Я искал и не нашел полного кода, поэтому попытался поставить полный и рабочий код. Удачи.

public class ValidatorClass
{
    WSHttpBinding BindingConfig;
    EndpointIdentity DNSIdentity;
    Uri URI;
    ContractDescription ConfDescription;

    public ValidatorClass()
    {  
        // In constructor initializing configuration elements by code
        BindingConfig = ValidatorClass.ConfigBinding();
        DNSIdentity = ValidatorClass.ConfigEndPoint();
        URI = ValidatorClass.ConfigURI();
        ConfDescription = ValidatorClass.ConfigContractDescription();
    }


    public void MainOperation()
    {
         var Address = new EndpointAddress(URI, DNSIdentity);
         var Client = new EvalServiceClient(BindingConfig, Address);
         Client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;
         Client.Endpoint.Contract = ConfDescription;
         Client.ClientCredentials.UserName.UserName = "companyUserName";
         Client.ClientCredentials.UserName.Password = "companyPassword";
         Client.Open();

         string CatchData = Client.CallServiceMethod();

         Client.Close();
    }



    public static WSHttpBinding ConfigBinding()
    {
        // ----- Programmatic definition of the SomeService Binding -----
        var wsHttpBinding = new WSHttpBinding();

        wsHttpBinding.Name = "BindingName";
        wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
        wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.BypassProxyOnLocal = false;
        wsHttpBinding.TransactionFlow = false;
        wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
        wsHttpBinding.MaxBufferPoolSize = 524288;
        wsHttpBinding.MaxReceivedMessageSize = 65536;
        wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
        wsHttpBinding.TextEncoding = Encoding.UTF8;
        wsHttpBinding.UseDefaultWebProxy = true;
        wsHttpBinding.AllowCookies = false;

        wsHttpBinding.ReaderQuotas.MaxDepth = 32;
        wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
        wsHttpBinding.ReaderQuotas.MaxStringContentLength = 8192;
        wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
        wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;

        wsHttpBinding.ReliableSession.Ordered = true;
        wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
        wsHttpBinding.ReliableSession.Enabled = false;

        wsHttpBinding.Security.Mode = SecurityMode.Message;
        wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
        wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
        wsHttpBinding.Security.Transport.Realm = "";

        wsHttpBinding.Security.Message.NegotiateServiceCredential = true;
        wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
        wsHttpBinding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256;
        // ----------- End Programmatic definition of the SomeServiceServiceBinding --------------

        return wsHttpBinding;

    }

    public static Uri ConfigURI()
    {
        // ----- Programmatic definition of the Service URI configuration -----
        Uri URI = new Uri("http://localhost:8732/Design_Time_Addresses/TestWcfServiceLibrary/EvalService/");

        return URI;
    }

    public static EndpointIdentity ConfigEndPoint()
    {
        // ----- Programmatic definition of the Service EndPointIdentitiy configuration -----
        EndpointIdentity DNSIdentity = EndpointIdentity.CreateDnsIdentity("tempCert");

        return DNSIdentity;
    }


    public static ContractDescription ConfigContractDescription()
    {
        // ----- Programmatic definition of the Service ContractDescription Binding -----
        ContractDescription Contract = ContractDescription.GetContract(typeof(IEvalService), typeof(EvalServiceClient));

        return Contract;
    }
}
person S. M. Khaled Reza    schedule 19.01.2012
comment
Очень красивый пример! Вы демонстрируете почти все аспекты ручной настройки. Отлично сделано! - person Kilhoffer; 29.02.2012
comment
Я не понимаю, как EvalServiceClient вписывается в этот код. На него есть ссылка, но не определено. Почему сервер создает клиента? - person BlueMonkMN; 24.02.2015

На сервере это непросто сбоку ..

На стороне клиента вы можете использовать ChannelFactory.

person Gulzar Nazim    schedule 10.09.2008

Вся конфигурация WCF может быть выполнена программно. Таким образом, можно создавать и серверы, и клиенты без файла конфигурации.

Я рекомендую книгу Джувала Лоуи «Программирование служб WCF», которая содержит множество примеров программной конфигурации.

person Paul Lalonde    schedule 11.09.2008

Это очень просто сделать как на стороне клиента, так и на стороне сервера. В книге Жюваля Лоуи есть прекрасные примеры.

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

РЕДАКТИРОВАТЬ: Одна из вещей, которую вы не можете сделать с файлом конфигурации, - это создавать службы с конструкторами, отличными от конструкторов по умолчанию. Это приводит к статическим / глобальным переменным, одиночкам и другим типам бессмысленности в WCF.

person Steve    schedule 21.04.2009

Я нашел сообщение в блоге по этой теме по приведенной ниже ссылке очень интересным.

Одна идея, которая мне нравится, - это возможность просто передать привязку или поведение или адрес XML-раздела из конфигурации к соответствующему объекту WCF и позволить ему обрабатывать назначение свойств - в настоящее время вы не можете этого сделать.

Как и у других пользователей в Интернете, у меня возникают проблемы, связанные с необходимостью использования в моей реализации WCF файла конфигурации, отличного от файла конфигурации моего хостингового приложения (которое является службой Windows .NET 2.0).

http://salvoz.com/blog/2007/12/09/programmatically-setting-wcf-configuration/

person Tone    schedule 21.04.2009