How to hard-code a default WCF endpoint for a serv

2019-07-13 14:20发布

问题:

In a self-hosted service, I'd like to use the endpoint(s) specified in App.config, if present, or a default endpoint specified in code if App.config is empty. How can I do this?

Edit: to clarify, this is on the server (service) side using ServiceHost.

回答1:

One way is to try the first attempt to load from the config file, and hard-code the endpoint in the catch. EG:

MyServiceClient client = null;
try
{
    client = new MyServiceClient();
}
catch (InvalidOperationException)
{
    EndpointAddress defaultAddress = new EndpointAddress(...);
    Binding defaultBinding = new Binding(...);
    client = new MyServiceClient(defaultBinding, defaultAddress);
}


回答2:

You can get the configuration section as below:

var clientSection =  System.Configuration.ConfigurationManager.GetSection("system.serviceModel/client");

If value is null or if clientSection.Endpoints contains zero elements then it is not defined.



回答3:

I have faced to same kind of issue when I wanted to implement the standalone service client without app.config file. and Finally I could sort it out. Please follow the below code sample. It is working fine and I have tested it.

BasicHttpBinding binding = new BasicHttpBinding();
binding.Name = "BasicHttpBinding_ITaskService";
binding.CloseTimeout = TimeSpan.FromMinutes(1);
binding.OpenTimeout = TimeSpan.FromMinutes(1);
binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
binding.SendTimeout = TimeSpan.FromMinutes(1);
binding.AllowCookies = false;
binding.BypassProxyOnLocal = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MaxBufferSize = 65536;
binding.MaxBufferPoolSize = 524288;
binding.MaxReceivedMessageSize = 65536;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = System.Text.Encoding.UTF8;
binding.TransferMode = TransferMode.Buffered;
binding.UseDefaultWebProxy = true;
binding.Security.Mode = BasicHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Transport.Realm = "";
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;

Uri endPointAddress = new Uri("http://www.kapanbipan.com/TaskService.svc");
ChannelFactory<taskmgr.TaskService.ITaskServiceChannel> factory = new ChannelFactory<ITaskServiceChannel>(binding, endPointAddress.ToString());
taskmgr.TaskService.ITaskServiceChannel client = factory.CreateChannel();


回答4:

Try this...untested, but should work for you. It will check your configuration for any endpoints with a matching contract. You can change it to match by name, return different information, or whatever makes sense for your situation. If no matches is found, you can put logic in to create a default endpoint.

    public List<EndpointAddress> GetEndpointAddresses(Type t)
    {
        string contractName = t.FullName;
        List<EndpointAddress> endpointAddresses = new List<EndpointAddress>();
        ServicesSection servicesSection = ConfigurationManager.GetSection("system.serviceModel/services") as ServicesSection;

        foreach (ServiceElement service in servicesSection.Services)
        {
            foreach (ServiceEndpointElement endpoint in service.Endpoints)
            {
                if (string.Compare(endpoint.Contract, contractName) == 0)
                {
                    endpointAddresses.Add(new EndpointAddress(endpoint.Address));
                }
            }
        }

        if (endpointAddresses.Count == 0)
        {
            //TODO: Add logic to determine default
            endpointAddresses.Add(new EndpointAddress("Your default here"));
        }

        return endpointAddresses;
    }