没有配置文件的 WCF 配置

有没有人知道一个不使用配置文件而以编程方式公开 WCF 服务的好例子?我知道现在 WCF 的服务对象模型更加丰富了,所以我知道这是可能的。我只是没有看到如何做到这一点的例子。相反,我想看看没有配置文件的情况下是如何消费的。

在任何人询问之前,我有一个非常具体的需要,即不使用配置文件来完成这项工作。我通常不会建议这样的做法,但正如我所说,在这种情况下有一个非常具体的需要。

76176 次浏览

It is not easy on the server side..

For client side, you can use ChannelFactory

All WCF configuration can be done programatically. So it's possible to create both servers and clients without a config file.

I recommend the book "Programming WCF Services" by Juval Lowy, which contains many examples of programmatic configuration.

Consuming a web service without a config file is very simple, as I've discovered. You simply need to create a binding object and address object and pass them either to the constructor of the client proxy or to a generic ChannelFactory instance. You can look at the default app.config to see what settings to use, then create a static helper method somewhere that instantiates your 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" ) );
}

I found the blog post at the link below around this topic very interesting.

One idea I like is that of being able to just pass in a binding or behavior or address XML section from the configuration to the appropriate WCF object and let it handle the assigning of the properties - currently you cannot do this.

Like others on the web I am having issues around needing my WCF implementation to use a different configuration file than that of my hosting application (which is a .NET 2.0 Windows service).

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

It's very easy to do on both the client and the server side. Juval Lowy's book has excellent examples.

As to your comment about the configuration files, I would say that the configuration files are a poor man's second to doing it in code. Configuration files are great when you control every client that will connect to your server and make sure they're updated, and that users can't find them and change anything. I find the WCF configuration file model to be limiting, mildly difficult to design, and a maintenance nightmare. All in all, I think it was a very poor decision by MS to make the configuration files the default way of doing things.

EDIT: One of the things you can't do with the configuration file is to create services with non-default constructors. This leads to static/global variables and singletons and other types of non-sense in WCF.

If you are interested in eliminating the usage of the System.ServiceModel section in the web.config for IIS hosting, I have posted an example of how to do that here (http://bejabbers2.blogspot.com/2010/02/wcf-zero-config-in-net-35-part-ii.html). I show how to customize a ServiceHost to create both metadata and wshttpbinding endpoints. I do it in a general purpose way that doesn't require additional coding. For those who aren't immediately upgrading to .NET 4.0 this can be pretty convenient.

Here, this is complete and working code. I think it will help you a lot. I was searching and never finds a complete code that's why I tried to put complete and working code. Good luck.

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