如何在DLL中添加Web服务引用

6
我正在创建一个带有对web服务的引用的DLL(我没有选择),但是我必须向使用该DLL的项目添加web服务引用才能使它正常工作。
例如,我有一个名为API.DLL的DLL,调用了一个名为WebService.svc的Web服务,我想在名为WinForm的项目中使用它。首先,我必须在API.DLL中添加对WebService.svc的“服务引用”。然后,我将API.DLL引用到WinForm中,但除非我还在WinForm中添加对WebService.svc的服务引用,否则它不起作用。
我应该怎么做才能避免最后这一步呢?

1
你不应该在WinForm中添加服务引用...你看到了什么错误? - John Weldon
系统无效操作异常。我的.NET是法语的(...叹气...),但它说类似于“找不到服务引用”。 - dsimard
5个回答

6
你的第一步是向自己证明这是可能的,然后调整你的项目。
你可以在这里下载可运行的解决方案。
我刚刚按照步骤列举了我的操作,以产生你所需要的结果。
创建一个名为'ReferencedWebService'的Web应用程序项目(因此也是解决方案) 添加一个Web服务,只需保留默认名称和实现 添加一个名为'ReferencedWebserviceAPI'的类库 添加服务引用 >高级选项 >添加Web引用>此解决方案中的Web服务 >WebService1 >添加引用,名称保留为“localhost” 添加一个名为'ReferencedWebserviceClient'的控制台应用程序项目 对于ReferencedWebserviceClient: 添加引用 >项目 >ReferencedWebserviceAPI 添加引用 >.Net >System.Web.Services
在Program.cs中替换Main:
static void Main(string[] args) { var svc = new ReferencedWebserviceAPI.localhost.WebService1(); var result = svc.HelloWorld(); Console.WriteLine(result); Console.ReadLine(); }
将ReferencedWebserviceClient设置为启动项目并运行。
好的,这是最简单的情况。您将需要处理的一个问题是,默认的服务URL在.dll中硬编码,并且它被设置为您的开发计算机上的端口地址。
您将想要向客户端项目添加配置参数。最简单、最便携的方法是使用appSetting。
对于ReferencedWebserviceClient: 添加项 >应用程序配置文件
将App.Config的内容替换为以下内容,当然要用适当的值替换该值。
添加引用 >.Net >System.Configuration
现在将Main替换为以下内容:
static void Main(string[] args) { var svc = new ReferencedWebserviceAPI.localhost.WebService1 { Url = ConfigurationManager.AppSettings["serviceUrl"] }; var result = svc.HelloWorld(); Console.WriteLine(result); Console.ReadLine(); } 这是将服务嵌入可再分发的.dll文件中的基准。请尝试将此模型应用于您当前的项目,看看它对您有何作用。如果仍然存在问题,则您肯定有参考问题,并应从该角度开始查找。希望这可以帮助您。

5
您可能正在使用Web服务公开的类型,或者您可能需要添加Web引用以便将适当的连接信息添加到配置文件中。Winform应用程序不会以任何方式继承或使用DLL的配置文件,除非您为其制作一些花哨的加载机制。换句话说,在DLL中添加Web引用时,它的配置文件会获取有关如何连接到Web服务的信息,但是当您在应用程序中使用该DLL时,您的应用程序需要该信息在自己的配置文件中,因此您必须添加Web引用以生成该信息。
关于使用Web引用公开的类型,我不确定这是否是您遇到的问题。我在DLL中遇到过这种情况。例如,SharpMap.dll声明了一个SharpMapData类,而WrapperOfSharpMap.dll有一个名为ProcessData(SharpMapData blah)的方法。
如果我编写一个WinForm应用程序并添加对WrapperOfSharpMap.dll的引用,则还必须添加对SharpMap.dll的引用,因为要调用ProcessData,我必须创建一个SharpMapData实例传递给该函数。换句话说,我正在使用SharpMap.dll中声明的类型,因此需要对它进行引用。
要解决此问题,WrapperOfSharpMap.dll的创建者必须创建一个WrapperSharpMapData类,如下所示:
class WrapperSharpMapData
{
  private SharpMapData hiddenSharpMapData;

  //create proprerties to access data elements using standard CLR types or other wrapper types
}

我认为问题实际上是因为我必须在WinForm中引用Web服务,但我不想这样做。我希望开发人员可以引用.DLL,并且Web服务会自动被引用。我该怎么做? - dsimard
@dan 如果不添加对Web服务的引用,WinForm如何获取连接到Web服务的配置信息?看看当您添加Web引用时,配置文件会发生什么。 DLL中的配置设置不会以任何方式影响EXE。 - AaronLS

1

这是因为您需要服务引用,以便WinForm应用程序可以引用您的服务返回的类型吗?

如果是这种情况,您可以将API dll转换为服务的包装器,并在API中封装服务上可用的所有方法,并对对象执行相同操作(假设它们是您创建的类)。显然,您必须将服务返回的所有对象转换为API中的对象。但是一旦完成,您就不需要在WinForm中引用服务。(有趣的是,我自己也正在做类似的事情!)


事实上,我的API.dll不会直接从webservice返回任何类型,以避免出现错误。就像DLL使用主机项目的服务引用而不是自身的引用一样。 - dsimard
那我就有点糊涂了!如果你创建一个新项目并引用你的API.dll,会发生什么?你会得到同样的错误吗? - Paul Manzotti
是的,如果我不添加对Web服务的引用,我就会遇到这个错误。我认为这是因为所有自动生成的类都没有遵循DLL。 - dsimard
@dan,生成的类被编译成程序集。请查看我的答案。 - Sky Sanders

1
你可以尝试使用svcutil.exe,它允许你通过命令行生成客户端代理代码。你应该能够将它生成的代码文件直接添加到你的DLL项目中,从而完全绕过Visual Studio。

0
在客户端项目中右键单击添加服务引用以添加方法和类。
然后,您可以像在dll中一样访问服务。
EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
Uri uri = new Uri("http://example.com/test.asmx");
var address = new EndpointAddress(uri, spn);
BasicHttpBinding basic = new BasicHttpBinding();
basic.Name = "bindingName";

var client = new MyService.MyWebServiceSoapClient(basic, address);
client.HelloWorld();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接