有谁知道如何在不使用配置文件的情况下以编程方式公开 WCF 服务的好例子?我知道 WCF 的服务对象模型现在更加丰富,所以我知道这是可能的。我只是还没有看到如何执行此操作的示例。相反,我想看看如何在没有配置文件的情况下进行消费。

在有人问之前,我有一个非常具体的需要,即在没有配置文件的情况下执行此操作。我通常不会推荐这种做法,但正如我所说,在这种情况下有一个非常具体的需求。

有帮助吗?

解决方案

正如我发现的,在没有配置文件的情况下使用 Web 服务非常简单。您只需创建一个绑定对象和地址对象,并将它们传递给客户端代理的构造函数或通用 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" ) );
}

其他提示

如果您有兴趣消除在 IIS 托管的 web.config 中使用 System.ServiceModel 部分,我已在此处发布了如何执行此操作的示例(http://bejabbers2.blogspot.com/2010/02/wcf-zero-config-in-net-35-part-ii.html)。我展示了如何自定义 ServiceHost 以创建元数据和 wshttpbinding 端点。我以通用方式完成此操作,不需要额外的编码。对于那些不立即升级到 .NET 4.0 的人来说,这可能非常方便。

这是完整且有效的代码。我认为这会对你有很大帮助。我一直在搜索,但从未找到完整的代码,这就是为什么我尝试放置完整且有效的代码。祝你好运。

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

服务器上不容易 ..

对于客户端,您可以使用 通道工厂

所有 WCF 配置都可以通过编程方式完成。因此可以在没有配置文件的情况下创建服务器和客户端。

我推荐 Juval Lowy 的《Programming WCF Services》一书,其中包含许多编程配置的示例。

在客户端和服务器端都很容易做到。朱瓦尔·洛伊(Juval Lowy)的书中有很好的例子。

至于您对配置文件的评论,我想说配置文件是一个可怜的人在代码中完成它的第二个。当您控制将连接到服务器的每个客户端并确保它们已更新并且用户无法找到它们并更改任何内容时,配置文件非常有用。我发现 WCF 配置文件模型有局限性,设计起来有些困难,而且维护起来很困难。总而言之,我认为微软将配置文件作为默认的处理方式是一个非常糟糕的决定。

编辑:不能使用配置文件执行的操作之一是使用非默认构造函数创建服务。这导致了 WCF 中的静态/全局变量和单例以及其他类型的无意义。

我发现下面链接中围绕该主题的博客文章非常有趣。

我喜欢的一个想法是能够将绑定或行为或地址 XML 部分从配置传递到适当的 WCF 对象,并让它处理属性的分配 - 目前您不能这样做。

与网络上的其他人一样,我也遇到了需要 WCF 实现使用与托管应用程序(.NET 2.0 Windows 服务)不同的配置文件的问题。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top