TL;DR
I would to run all three things("You have created a web service" page, WSDL page and actual web service) on the same URL, similarly to a WCF service project created in a standalone WebService application.
I am working on creating WCF endpoints programatically and got most of it together. The last thing is that I can't get the metadata URL to be the same as the service URL. I know this should be possible as you can create services like that from Visual Studio.
What happens is I can browse WSDL in the browser, I can add it as a web reference but I can't invoke it from the newly created project. If I remove both friendly page and wsdl pages, i can invoke the service.
Below is the code that I am using.
class Program
{
private static ManualResetEvent _ResetEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.TreatControlCAsInput = true;
var serviceUrl = "Fibonacci.svc";
new Thread(() =>
{
var baseUri = new Uri("http://ws.test.com");
var serviceUri = new Uri(baseUri, serviceUrl);
BasicHttpBinding binding = new BasicHttpBinding();
using (var host = new ServiceHost(typeof(Fibonacci), new[] { baseUri }))
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = new Uri(baseUri, serviceUrl) });
host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
host.Description.Behaviors.Find<ServiceDebugBehavior>().HttpHelpPageUrl = serviceUri;
host.AddServiceEndpoint(typeof(IFibonacci), binding, serviceUri);
Console.WriteLine("Started service on cotnract {0}, ready for anything", typeof(IFibonacci).FullName);
host.Open();
_ResetEvent.WaitOne();
}
}).Start();
while (true)
{
var cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.C && (cki.Modifiers & ConsoleModifiers.Control) != 0)
{
_ResetEvent.Set();
break;
}
}
}
}
WCF services use metadata to describe how to interact with the service's endpoints so that tools, such as Svcutil.exe, can automatically generate client code for accessing the service. Most of the types that make up the WCF metadata infrastructure reside in the System. ServiceModel. Description namespace.
There are three types of hosting environments for WCF services: IIS, WAS, and self-hosting. The term “self-hosting” refers to any application that provides its own code to initialize the hosting environment. This includes console, Windows Forms, WPF, and managed Windows services.
Turns out the solution is simple. The documentation for HttpGetUrl is slightly obtuse, basically in order to get all three to work off the same URL you need to create the ServiceHost
with the full URL of the service and then only set ServiceMetaBaseBehaviour.HttpGetEnable
to true
.
Relevant code is below.
var baseUri = new Uri("http://ws.test.com");
var serviceUri = new Uri(baseUri, serviceUrl);
BasicHttpBinding binding = new BasicHttpBinding();
using (var host = new ServiceHost(typeof(Fibonacci), serviceUri /*Specify full URL here*/))
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true /*Do not specify URL at all*/});
host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
host.Description.Behaviors.Find<ServiceDebugBehavior>().HttpHelpPageUrl = serviceUri;
host.AddServiceEndpoint(typeof(IFibonacci), binding, string.Empty /*Url here can either be empty or the same one as serviceUri*/);
Console.WriteLine("Started service on cotnract {0}, ready for anything", typeof(IFibonacci).FullName);
host.Open();
_ResetEvent.WaitOne();
}
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