如何以相同的URL以编程方式创建WCF服务及其元数据

时间:2011-05-06 06:49:31

标签: .net wcf web-services

TL; DR
我想在同一个URL上运行所有这三件事(“你已经创建了一个Web服务”页面,WSDL页面和实际的Web服务),类似于在独立的WebService应用程序中创建的WCF服务项目。

我正在以编程方式创建WCF端点并将其中的大部分组合在一起。最后一件事是我无法将元数据URL与服务URL相同。我知道这应该是可行的,因为你可以从Visual Studio创建类似的服务。

我可以在浏览器中浏览WSDL,我可以将其添加为Web引用,但我无法从新创建的项目中调用它。如果我删除友好页面和wsdl页面,我可以调用该服务。

以下是我正在使用的代码。

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

    }
}

2 个答案:

答案 0 :(得分:9)

原来解决方案很简单。 documentation for HttpGetUrl略显迟钝,基本上是为了让所有三个工作都与您使用服务的完整网址创建ServiceHost所需的网址相同将ServiceMetaBaseBehaviour.HttpGetEnable设为true

相关代码如下。

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

答案 1 :(得分:0)

article in InfoWorld提供,请参阅第4行,了解另一种更清晰的方法,以指定避免上述任何URL问题的mex端点。当服务使用其他绑定(例如netTcp)公开端点时,这很有用:

localStorage.getItem("name");

(对那些对VB过敏的人道歉)