简体   繁体   English

如何以编程方式从WCF服务生成WSDL(集成测试)

[英]How to programmatically generate WSDL from WCF service (Integration Testing)

I am looking to write some integration tests to compare the WSDL generated by WCF services against previous (and published) versions. 我期待编写一些集成测试来比较WCF服务生成的WSDL与以前(和已发布)的版本。 This is to ensure the service contracts don't differ from time of release. 这是为了确保服务合同与发布时间不同。

I would like my tests to be self contained and not rely on any external resources such as hosting on IIS. 我希望我的测试是自包含的,而不是依赖任何外部资源,如在IIS上托管。

I am thinking that I could recreate my IIS hosting environment within the test with something like... 我想我可以在测试中重新创建我的IIS托管环境,例如...

using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), new Uri("http://localhost:8000/Omega")))
{
    host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary");
    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
    behavior.HttpGetEnabled = true;
    host.Description.Behaviors.Add(behavior);
    host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
    host.Open();
}

Does anyone else have any better ideas? 还有其他人有更好的想法吗?

EDIT: Obviously this code is simply creating a host for the service, I am still missing the client code to obtain the WSDL definition. 编辑:显然这段代码只是为服务创建一个主机,我仍然缺少客户端代码来获取WSDL定义。

Just use WebClient and ?wsdl sufix in URL 只需在URL中使用WebClient和?wsdl sufix

using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), 
new Uri("http://localhost:8000/Omega")))
{
    host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary");
    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
    behavior.HttpGetEnabled = true;
    host.Description.Behaviors.Add(behavior);
    host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
    host.Open();

    string wsdl = null;
    using (WebClient wc = new WebClient())
    {
        using (var stream = wc.OpenRead("localhost:8000/Omega?wsdl"))
        {
            using (var sr = new StreamReader(stream))
            {
                wsdl = sr.ReadToEnd();
            }
        }
    }
    Console.Write(wsdl);
}

Check out the WsdlExporter on MSDN. 查看MSDN上的WsdlExporter Its used to generate wsdl in WCF. 它用于在WCF中生成wsdl。 You could also have a look in svcutil with reflector to see how its generating the wsdl information, since the tool can generate wsdl from a dll-file. 您还可以查看带反射器的svcutil,了解它如何生成wsdl信息,因为该工具可以从dll文件生成wsdl。

Another way to do your comparison would be to use the svcutil tool to generate the wsdl and compare it to a saved/baselined version of the service. 另一种进行比较的方法是使用svcutil工具生成wsdl并将其与服务的已保存/基线版本进行比较。 Run the svcutil in your test and verify the output against the old files. 在测试中运行svcutil并根据旧文件验证输出。 Not really self-contained test since you'll need the svcutil... 不是真正独立的测试,因为你需要svcutil ...

How about something like this? 这样的事怎么样? Creating a WSDL using C# 使用C#创建WSDL

Same answer translated to VB 同样的答案翻译成VB

    Using host = New ServiceHost(GetType(MyHelloWorldWcfLib.HelloWorldServer), New Uri("http://localhost:8000/Omega"))

        host.AddServiceEndpoint(GetType(MyHelloWorldWcfLib.IHelloWorld), New BasicHttpBinding(), "Primary")
        Dim behavior = New ServiceMetadataBehavior()
        behavior.HttpGetEnabled = True
        host.Description.Behaviors.Add(behavior)
        host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex")
        host.Open()

        Dim wsdl As String = Nothing
        Using wc = New System.Net.WebClient()
            Using stream = wc.OpenRead("http://localhost:8000/Omega?wsdl")
                Using sr = New IO.StreamReader(stream)
                    wsdl = sr.ReadToEnd()
                End Using
            End Using
        End Using
        Console.Write(wsdl)
    End Using

One thing you need to be careful of is to compare the entire WSDL. 您需要注意的一件事是比较整个WSDL。 WCF breaks up WSDLs, unlike classic web services (asmx) WSDLs. 与传统的Web服务(asmx)WSDL不同,WCF分解了WSDL。 This means that the core of the info is on the ?WSDL page, however, there will also be multiple XSDs (.svc?XSD=XSD0, 1, 2 ...) and possibly multiple WSDL pages (?WSDL and ?WSDL=WSDL0 for example). 这意味着info的核心位于?WSDL页面上,但是,也会有多个XSD(.svc?XSD = XSD0,1,2 ......)和可能的多个WSDL页面(?WSDL和?WSDL =例如WSDL0)。

One way to accomplish this would be to generate a webrequest to get the data from the root wsdl. 实现此目的的一种方法是生成webrequest以从根wsdl获取数据。 Then you can search the WSDL for anything like (yourServicename).svc?WSDL=WSLD0 and (yourServicename)?XSD=XSD0 and so on, spawning additional webrequests for each WSDL and XSD. 然后,您可以在WSDL中搜索(yourServicename).svc?WSDL = WSLD0和(yourServicename)?XSD = XSD0等等,为每个WSDL和XSD生成其他Web请求。

You might be better off using SoapUI to test the WSDL rather than relying on NUnit directly. 您可能最好使用SoapUI来测试WSDL,而不是直接依赖NUnit。

If you want to call SoapUI from NUnit, it's possible, but a little clunky. 如果你想从NUnit调用SoapUI,它可能,但有点笨重。 See http://enthusiasm.soapui.org/forum/viewtopic.php?f=2&t=15 for more information. 有关详细信息,请参阅http://enthusiasm.soapui.org/forum/viewtopic.php?f=2&t=15

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM