Czy ktoś zna dobry przykład tego, jak udostępniać usługę WCF programowo bez użycia pliku konfiguracji? Wiem, że model obiektów usług jest teraz znacznie bogatszy dzięki WCF, więc wiem, że jest to możliwe. Po prostu nie widziałem przykładu, jak to zrobić. I odwrotnie, chciałbym zobaczyć, jak odbywa się również konsumpcja bez pliku konfiguracyjnego.
Zanim ktoś zapyta, mam bardzo konkretną potrzebę zrobienia tego bez plików konfiguracyjnych. Normalnie nie polecałbym takiej praktyki, ale jak powiedziałem, w tym przypadku istnieje bardzo konkretna potrzeba.
wcf
configuration
configuration-files
Kilhoffer
źródło
źródło
Odpowiedzi:
Jak odkryłem, korzystanie z usługi internetowej bez pliku konfiguracyjnego jest bardzo proste. Wystarczy utworzyć obiekt powiązania i obiekt adresowy i przekazać je albo do konstruktora serwera proxy klienta, albo do ogólnej instancji ChannelFactory. Możesz spojrzeć na domyślny plik app.config, aby zobaczyć, jakich ustawień użyć, a następnie utworzyć statyczną metodę pomocniczą w miejscu, w którym utworzy się Twój serwer proxy:
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" ) ); }
źródło
Security.Mode
domyślnieNone
.)Jeśli jesteś zainteresowany wyeliminowaniem użycia sekcji System.ServiceModel w web.config dla hostingu IIS, zamieściłem tutaj przykład, jak to zrobić ( http://bejabbers2.blogspot.com/2010/02/wcf -zero-config-in-net-35-part-ii.html ). Pokazuję, jak dostosować ServiceHost, aby utworzyć punkty końcowe zarówno metadanych, jak i wshttpbinding. Robię to w sposób ogólny, który nie wymaga dodatkowego kodowania. Dla tych, którzy nie dokonują natychmiastowej aktualizacji do .NET 4.0, może to być całkiem wygodne.
źródło
Tutaj jest to kompletny i działający kod. Myślę, że to ci bardzo pomoże. Szukałem i nigdy nie znalazłem pełnego kodu, dlatego próbowałem umieścić kompletny i działający kod. Powodzenia.
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; } }
źródło
Nie jest to łatwe po stronie serwera .
Po stronie klienta możesz użyć ChannelFactory
źródło
Wszystkie konfiguracje WCF można wykonać programowo. Możliwe jest więc tworzenie serwerów i klientów bez pliku konfiguracyjnego.
Polecam książkę „Programming WCF Services” autorstwa Juvala Lowy, która zawiera wiele przykładów konfiguracji programowej.
źródło
Jest to bardzo łatwe zarówno po stronie klienta, jak i serwera. Książka Juvala Lowy ma doskonałe przykłady.
Co do twojego komentarza na temat plików konfiguracyjnych, powiedziałbym, że pliki konfiguracyjne są sekundą dla biedaka, aby zrobić to w kodzie. Pliki konfiguracyjne są świetne, gdy kontrolujesz każdego klienta, który będzie łączył się z Twoim serwerem, i upewniasz się, że są aktualizowane, a użytkownicy nie mogą ich znaleźć i niczego zmienić. Uważam, że model pliku konfiguracji WCF jest ograniczający, średnio trudny do zaprojektowania i koszmar konserwacji. Podsumowując, myślę, że MS to bardzo zła decyzja, aby pliki konfiguracyjne stały się domyślnym sposobem wykonywania czynności.
EDYCJA: Jedną z rzeczy, których nie można zrobić z plikiem konfiguracyjnym, jest tworzenie usług z innymi niż domyślnymi konstruktorami. Prowadzi to do zmiennych statycznych / globalnych i pojedynczych oraz innych typów braku sensu w WCF.
źródło
Uważam, że wpis na blogu pod poniższym linkiem na ten temat jest bardzo interesujący.
Jednym z pomysłów, który mi się podoba, jest to, że można po prostu przekazać powiązanie, zachowanie lub adres sekcji XML z konfiguracji do odpowiedniego obiektu WCF i pozwolić mu obsłużyć przypisywanie właściwości - obecnie nie można tego zrobić.
Podobnie jak inni użytkownicy sieci Web, mam problemy z potrzebą implementacji programu WCF do korzystania z innego pliku konfiguracyjnego niż plik mojej aplikacji hostingowej (która jest usługą .NET 2.0 systemu Windows).
http://salvoz.com/blog/2007/12/09/programmatically-setting-wcf-configuration/
źródło