구성 파일이없는 WCF 구성


90

구성 파일을 사용하지 않고 프로그래밍 방식으로 WCF 서비스를 노출하는 방법에 대한 좋은 예를 아는 사람이 있습니까? WCF를 사용하면 서비스 개체 모델이 훨씬 더 풍부하다는 것을 알고 있으므로 가능하다는 것을 알고 있습니다. 나는 그렇게하는 방법에 대한 예를 보지 못했습니다. 반대로 구성 파일 없이도 어떻게 소비하는지보고 싶습니다.

누군가 묻기 전에 구성 파일없이이 작업을 수행해야하는 매우 구체적인 필요가 있습니다. 나는 일반적으로 그러한 관행을 권장하지 않지만 내가 말했듯이이 경우에는 매우 특별한 요구가 있습니다.


1
왜 그러한 방법을 권장하지 않습니까 (구성없이 프로그래밍 방식으로 서비스 노출)?
BornToCode

답변:


115

내가 발견했듯이 구성 파일없이 웹 서비스를 사용하는 것은 매우 간단합니다. 바인딩 개체와 주소 개체를 만들고 클라이언트 프록시의 생성 자나 일반 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" ) );
}

예를 들어 app.config (또는 이에 상응하는 구성 파일)를 암호화하고 내장 된 WCF를 사용할 필요가없는 경우와 같이 다른 문제에서 파일을 사용하려는 경우이 접근 방식을 개인적으로 좋아합니다. 연결에서 읽는 그것의 능력
Noah

18
https 사용의 경우 binding.Security.Mode = BasicHttpSecurityMode.Transport를 추가하십시오.
ciscoheat

이것은 나를 위해 아주 잘 작동했습니다. 저에게 유일한 차이점은 ReaderQuotas 및 보안 정보도 설정한다는 것입니다. ciscoheat의 조언을 활용하고 https를 사용하는 경우 Security.Transport.Mode를 Transport로 설정했습니다 (나에게 이것은 컴파일 타임에 알려지지 않음).
Kirk Liemohn

2
방금 설정되는 모든 속성이 WCF 4, fwiw의 기본값과 동일한 지 확인했습니다. (그러나 Security.Mode기본값은 None.)
ladenedge

19

IIS 호스팅을 위해 web.config에서 System.ServiceModel 섹션의 사용을 제거하는 데 관심이 있다면 여기 ( http://bejabbers2.blogspot.com/2010/02/wcf -zero-config-in-net-35-part-ii.html ). 메타 데이터와 wshttpbinding 끝점을 모두 생성하도록 ServiceHost를 사용자 지정하는 방법을 보여줍니다. 추가 코딩이 필요없는 범용 방식으로 수행합니다. .NET 4.0으로 즉시 업그레이드하지 않는 사람들에게 이것은 매우 편리 할 수 ​​있습니다.


John, 나는 그것이 훌륭한 블로그 게시물이라고 확신합니다. 그러나 17 개월 전에 받아 들여진 답변이 있기 때문에 당신의 대답에 정말로 어떤 목적이 있습니까?
John Saunders

36
이것이 내 첫 번째 스택 오버플로 답변이기 때문에 일반적으로 수행되는 방식이 아닐 수 있습니다. 훌륭한 참고 자료 인 Lowy 및 Bustamante 책에 익숙해 졌기 때문에 내 대답은 그들이 제공하는 샘플을 훨씬 능가한다고 생각합니다. 인터넷 검색을 할 때 주로 Stack Overflow를 사용하므로 오래된 게시물을 자주 읽습니다. 더 많은 최신 답변이 있으면 내 관점에서만 도움이됩니다. 휠을 재발 명하지 않기 위해 코드를 작성하기 전에이 게시물을 검색했습니다.
John Wigger

48
빈번한 SO 사용자로서 나는 오래된 주제에 대한 새로운 게시물을 읽는 것이 매우 바람직하다는 것을 알게되었습니다. 내 업무를 더 잘 수행하는 데 도움이되며,이 사이트의 가치가 높아집니다 (나 자신과 다른 사람들이 더 많이 방문 할 것임). 규칙을 고수하는 대신 사람들이 토론하도록 허용하여 더 나은 답변을 찾을 수있는 이유는 무엇입니까? 그게 요점 아닌가요?

7
John Saunders는 자신의 질문에 대한 응답으로 그의 자리에 배치 된 것 같습니다 (그 중 어느 것도 내가 추가 할 수있는 대답으로 수락하지 않았습니다). 저는 개인적으로 질문에 대한 늦게 답변하는 데 문제가 없으며 일반적으로 몇 년은 아니더라도 몇 달 후에 제가 질문 한 질문에 대한 새로운 답변을 보게되어 기쁩니다. 아이러니하게도 저는이 질문에 대한 대답으로 제 자신의 네크로맨서 배지를 받았습니다. :)
devios1

3
나는 똑같은 문제가 있었고 받아 들여진 대답은 나를 돕지 않았지만 이것은 늦은 대답을 위해 만세! 늦은 답변이 아니었다면 중복 질문을 만들어야했을 것입니다.
Didier A.

15

여기, 이것은 완전하고 작동하는 코드입니다. 많은 도움이 될 것 같아요. 나는 검색 중이며 완전한 코드를 찾지 못하기 때문에 완전하고 작동하는 코드를 넣으려고했습니다. 행운을 빕니다.

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;
    }
}

아주 좋은 예! 수동 구성의 거의 모든 측면을 보여줍니다. 잘하셨습니다!
Kilhoffer

5
EvalServiceClient가이 코드에 어떻게 들어 맞는지 이해하지 못합니다. 참조되었지만 정의되지 않았습니다. 서버가 클라이언트를 만드는 이유는 무엇입니까?
BlueMonkMN


3

모든 WCF 구성은 프로그래밍 방식으로 수행 할 수 있습니다. 따라서 구성 파일없이 서버와 클라이언트를 모두 만들 수 있습니다.

프로그래밍 방식 구성의 많은 예가 포함 된 Juval Lowy의 "Programming WCF Services"책을 추천합니다.


2

클라이언트 측과 서버 측 모두에서 수행하는 것은 매우 쉽습니다. Juval Lowy의 책에는 훌륭한 예가 있습니다.

구성 파일에 대한 귀하의 의견에 관해서는 구성 파일이 코드에서 수행하는 것보다 두 번째로 가난한 사람이라고 말하고 싶습니다. 구성 파일은 서버에 연결할 모든 클라이언트를 제어하고 업데이트되었는지 확인하며 사용자가 파일을 찾아서 변경할 수없는 경우 유용합니다. WCF 구성 파일 모델이 제한적이며 디자인하기가 약간 어려우며 유지 관리에 악몽이 있습니다. 대체로, 구성 파일을 기본 작업 방식으로 만드는 것은 MS의 매우 잘못된 결정이라고 생각합니다.

편집 : 구성 파일로 할 수없는 작업 중 하나는 기본이 아닌 생성자로 서비스를 만드는 것입니다. 이로 인해 WCF에서 정적 / 전역 변수 및 싱글 톤 및 기타 유형의 넌센스가 발생합니다.


2

이 주제와 관련된 아래 링크의 블로그 게시물이 매우 흥미 롭다는 것을 알았습니다.

내가 좋아하는 한 가지 아이디어는 구성에서 적절한 WCF 개체로 바인딩 또는 동작을 전달하거나 XML 섹션을 주소 지정하고 속성 할당을 처리하도록 할 수 있다는 것입니다. 현재로서는 이렇게 할 수 없습니다.

웹의 다른 사람들과 마찬가지로 호스팅 응용 프로그램 (.NET 2.0 Windows 서비스)의 구성 파일과 다른 구성 파일을 사용하려면 WCF 구현이 필요하다는 문제가 있습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.