简体   繁体   English

使用不同的界面使用Web服务

[英]Consuming a web service using a different interface

I have a wsdl file that is constructed in an extremely unhelpful way. 我有一个以极其无益的方式构建的wsdl文件。 It is huge,in some cases several megabytes in size, and when I use the various Visual Studio tools to generate a wrapper from it, the resulting codebase is so large that it tends to crash Visual Studio on weaker machines. 它是巨大的,在某些情况下是几兆字节,当我使用各种Visual Studio工具从中生成包装器时,生成的代码库非常大,以至于它会使较弱的机器上的Visual Studio崩溃。 The compilation time is ludicrous, and the resulting class uses properties where a more dynamic mode of access is absolutely necessary (ie some sort of indexer). 编译时间是荒谬的,结果类使用的属性是绝对必要的更动态的访问模式(即某种索引器)。 There is no option of any changes on the server side. 服务器端没有任何更改选项。

The wsdl files are far larger than could be processed by hand, and there is an arbitrary number of them. wsdl文件远远大于手工处理的文件,并且有任意数量的文件。 The solution I've employed so far, is to use reflection or late binding with the resulting, auto-generated class. 到目前为止我使用的解决方案是使用反射或后期绑定生成的自动生成的类。 However, since I'm dealing here with a wrapper that wraps what's basically a client for SOAP messages it would make sense if there is another way. 然而,因为我在这里处理的是封装了基本上是一个客户端的SOAP消息它将使意义,如果有另一种方式的包装

Essentially, I want to create a wrapper that exposes a more dynamic interface, especially where fields are concerned. 本质上,我想创建一个包装器,它暴露出一个更动态的界面,特别是在涉及字段的地方。 The task isn't entirely straightforward, so I'm looking for suggestions regarding what to do, and various classes, customizable code generators, WSDL explorers/parsers, etc, that will make the task less time-consuming. 这个任务并不完全是直截了当的,所以我正在寻找有关该做什么的建议,以及各种类,可定制的代码生成器,WSDL浏览器/解析器等,这些都将使这项任务不那么耗时。 Should I construct my own SOAP client? 我应该构建自己的SOAP客户端吗? What would I base it on? 我会以什么为基础? What .NET features can help me with this task? 什么.NET功能可以帮助我完成这项任务?

You could hand craft an interface that supports a subset of the methods available on the WebService and do away with the need to generate a service reference. 您可以手工制作支持WebService上可用方法子集的接口,并且不需要生成服务引用。

You would have to create the right soap signature for the methods including dto's and namespaces. 您必须为方法创建正确的soap签名,包括dto和名称空间。 The downside of this is that you would be forced to manage any changes to the service manually. 这样做的缺点是您将被迫手动管理对服务的任何更改。

Here is a simple example showing a proxy client created with the ISubsetInterface communication with a service exposing the IServiceInterface . 下面是一个简单的示例,显示了使用ISubsetInterface通信创建的代理客户端以及公开IServiceInterface的服务。 To achieve this the Name property has to match the name of the IServiceInterface contract which in this case defaults to "IServiceInterface" but your implementation might require manipulation of the Namespace and Actions. 要实现此目的,Name属性必须与IServiceInterface合约的名称匹配,在这种情况下,默认为“IServiceInterface”,但您的实现可能需要操作Namespace和Actions。 The simplest way to know what you need to manipulate is to look at the generated wsdl. 了解您需要操作的最简单方法是查看生成的wsdl。

[TestFixture]
public class When_using_a_subset_of_a_WCF_interface
{
    [Test]
    public void Should_call_interesting_method()
    {
        var serviceHost = new ServiceHost(typeof(Service));

        serviceHost.AddServiceEndpoint( typeof(IServiceInterface), new BasicHttpBinding(), "http://localhost:8081/Service" );
        serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;

        serviceHost.Open();

        using( var channelFactory = new ChannelFactory<ISubsetInterface>( new BasicHttpBinding(), "http://localhost:8081/Service") )
        {
            var client = channelFactory.CreateChannel();

            client.InterestingMethod().Should().Be( "foo" );
        }

        serviceHost.Close();
    }

    [ServiceContract]
    interface IServiceInterface
    {
        [OperationContract]
        string InterestingMethod();
        [OperationContract]
        string UninterestingMethod();
    }

    [ServiceContract(Name = "IServiceInterface")]
    interface ISubsetInterface
    {
        [OperationContract]
        string InterestingMethod();
    }

    class Service : IServiceInterface
    {
        public string InterestingMethod() { return "foo"; }

        public string UninterestingMethod() { throw new NotImplementedException(); }
    }
}

I suggest to use a shared assembly which contains the DataContracts . 我建议使用包含DataContracts的共享程序集。

Then use the ChannelFactory<T> class to create an instance of the server Interface. 然后使用ChannelFactory<T>类创建服务器接口的实例。 Then you can make calls to the Server without any WSDL. 然后,您可以在没有任何WSDL的情况下调用服务器。

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

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