我有一个以极其无益的方式构建的wsdl文件。它是巨大的,在某些情况下是几兆字节,当我使用各种Visual Studio工具从中生成包装器时,生成的代码库非常大,以至于它会使较弱的机器上的Visual Studio崩溃。编译时间是荒谬的,结果类使用的属性是绝对必要的更动态的访问模式(即某种索引器)。服务器端没有任何更改选项。
wsdl文件远远大于手工处理的文件,并且有任意数量的文件。到目前为止我使用的解决方案是使用反射或后期绑定生成的自动生成的类。但是,由于我在这里处理一个包装器,包装基本上是SOAP消息的客户端,如果有另一种方式,这将是有意义的。
本质上,我想创建一个包装器,它暴露出一个更动态的界面,特别是在涉及字段的地方。这个任务并不完全是直截了当的,所以我正在寻找有关该做什么的建议,以及各种类,可定制的代码生成器,WSDL浏览器/解析器等,这些都将使这项任务不那么耗时。我应该构建自己的SOAP客户端吗?我会以什么为基础?什么.NET功能可以帮助我完成这项任务?
答案 0 :(得分:9)
您可以手工制作支持WebService上可用方法子集的接口,并且不需要生成服务引用。
您必须为方法创建正确的soap签名,包括dto和名称空间。这样做的缺点是您将被迫手动管理对服务的任何更改。
这是一个简单的示例,显示了使用ISubsetInterface
通信创建的代理客户端,其中包含公开IServiceInterface
的服务。要实现此目的,Name属性必须与IServiceInterface合约的名称匹配,在这种情况下,默认为“IServiceInterface”,但您的实现可能需要操作Namespace和Actions。了解您需要操作的最简单方法是查看生成的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(); }
}
}
答案 1 :(得分:2)
我建议使用包含DataContracts
。
然后使用ChannelFactory<T>
类创建服务器接口的实例。然后,您可以在没有任何WSDL的情况下调用服务器。