Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
535 views
in Technique[技术] by (71.8m points)

.net - How to programatically create a WCF service and its metadata on the same URL

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

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...