I followed article to include WCF service into my ASP.NET core application.
Looking at below line in reference.cs, it seems default endpoint configuration is hard-coded inside reference.cs.
return new System.ServiceModel.EndpointAddress("http://localhost:49945/SimpleService.svc");
This is how I can create my client in asp.net core controller-
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:49945/SimpleService.svc");
wcfClient = new SimpleServiceClient(basicHttpBinding, endpointAddress);
So my questions are-
Where should I maintain endpoint details so that it can be easily configurable during deployment?
How I can pass endpoint details (address and binding) dynamically from configuration file (appsetting.json)?
Generated Reference.cs file looks like follows-
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// //
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SimpleServiceReference
{
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="CompositeType", Namespace="http://schemas.datacontract.org/2004/07/SimpleService")]
public partial class CompositeType : object
{
private bool BoolValueField;
private string StringValueField;
[System.Runtime.Serialization.DataMemberAttribute()]
public bool BoolValue
{
get
{
return this.BoolValueField;
}
set
{
this.BoolValueField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string StringValue
{
get
{
return this.StringValueField;
}
set
{
this.StringValueField = value;
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="SimpleServiceReference.ISimpleService")]
public interface ISimpleService
{
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISimpleService/GetData", ReplyAction="http://tempuri.org/ISimpleService/GetDataResponse")]
System.Threading.Tasks.Task<string> GetDataAsync(int value);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISimpleService/GetDataUsingDataContract", ReplyAction="http://tempuri.org/ISimpleService/GetDataUsingDataContractResponse")]
System.Threading.Tasks.Task<SimpleServiceReference.CompositeType> GetDataUsingDataContractAsync(SimpleServiceReference.CompositeType composite);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
public interface ISimpleServiceChannel : SimpleServiceReference.ISimpleService, System.ServiceModel.IClientChannel
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
public partial class SimpleServiceClient : System.ServiceModel.ClientBase<SimpleServiceReference.ISimpleService>, SimpleServiceReference.ISimpleService
{
/// <summary>
/// Implement this partial method to configure the service endpoint.
/// </summary>
/// <param name="serviceEndpoint">The endpoint to configure</param>
/// <param name="clientCredentials">The client credentials</param>
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
public SimpleServiceClient() :
base(SimpleServiceClient.GetDefaultBinding(), SimpleServiceClient.GetDefaultEndpointAddress())
{
this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_ISimpleService.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}
public SimpleServiceClient(EndpointConfiguration endpointConfiguration) :
base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), SimpleServiceClient.GetEndpointAddress(endpointConfiguration))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}
public SimpleServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) :
base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}
public SimpleServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) :
base(SimpleServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}
public SimpleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public System.Threading.Tasks.Task<string> GetDataAsync(int value)
{
return base.Channel.GetDataAsync(value);
}
public System.Threading.Tasks.Task<SimpleServiceReference.CompositeType> GetDataUsingDataContractAsync(SimpleServiceReference.CompositeType composite)
{
return base.Channel.GetDataUsingDataContractAsync(composite);
}
public virtual System.Threading.Tasks.Task OpenAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
}
public virtual System.Threading.Tasks.Task CloseAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
}
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ISimpleService))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ISimpleService))
{
return new System.ServiceModel.EndpointAddress("http://localhost:49945/SimpleService.svc");
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
private static System.ServiceModel.Channels.Binding GetDefaultBinding()
{
return SimpleServiceClient.GetBindingForEndpoint(EndpointConfiguration.BasicHttpBinding_ISimpleService);
}
private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
{
return SimpleServiceClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_ISimpleService);
}
public enum EndpointConfiguration
{
BasicHttpBinding_ISimpleService,
}
}
}
I needed the same thing in the past, and ended up storing the connection details for a WCF service in the app's options. I stored the details in the appsettings.json file, created an Options class, and registered it with the services setup logic so I could request it when creating the WCF service.
Bare with my code, I just whipped this up quickly. I have not tested it for common errors like missing braces, semicolons, or misspellings :-P
Options class
public class MyServiceOptions
{
public string EndpointUrl {get;set;}
}
Excerpt from startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyServiceOptions>Configuration.GetSection("MyService"));
//Other calls as needed...
}
appsettings.json
{
"MyService": {
"EndpointUrl": "http://localhost:49945/SimpleService.svc"
}
}
Then you can access your options by requesting an instance of IOptions<MyServiceOptions>
from the dependency injection container in a variaty of ways.
public class MyController : Controller
{
//Option 1, in controller constructor
private IOptions<MyServiceOptions> myOptions;
public MyController(IOptions<MyServiceOptions> myOptions1)
{
myOptions = myOptions1
}
//Option 2, in action method signature
public IActionResult MyAction([FromServices]IOptions<MyServiceOptions> myOptions2)
{
//Option 3, directly
var myOptions3 = HttpContext.RequestServices.GetService<IControllerFactory>();
//NOTE: The GetService<>() method is an extension method from the Microsoft.Extensions.DependencyInjection namespace
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress(myOptions.Value.EndpointUrl);
wcfClient = new SimpleServiceClient(basicHttpBinding, endpointAddress);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With