简体   繁体   English

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

[英]How to add a web service reference in a DLL

I'm creating a DLL with a reference to web services (I don't have the choice to do so) but I have to add web service references to the project that uses the DLL for it to work.我正在创建一个引用 Web 服务的 DLL(我没有选择这样做),但我必须将 Web 服务引用添加到使用该 DLL 的项目才能使其工作。

Example, I have the DLL called API.DLL that calls a web service called WebService.svc that I want to use in a project called WinForm.例如,我有一个名为 API.DLL 的 DLL,它调用一个名为 WebService.svc 的 Web 服务,我想在名为 WinForm 的项目中使用该服务。 First, I have to add a "Service Reference" to WebService.svc in API.DLL.首先,我必须在 API.DLL 中向 WebService.svc 添加一个“服务引用”。 Then, I add a reference API.DLL to WinForm but it doesn't work unless I also add a service reference to WebService.svc in WinForm.然后,我向 WinForm 添加了一个引用 API.DLL,但它不起作用,除非我还在 WinForm 中添加了一个对 WebService.svc 的服务引用。

What can I do to avoid that last step?我该怎么做才能避免最后一步?

Your first step is to prove to yourself that this is possible and then adapt your project.您的第一步是向自己证明这是可能的,然后调整您的项目。

you can download the runnable solution here .您可以在此处下载可运行的解决方案。

I just went through the steps and enumerated my actions to produce the results you desire.我只是经历了这些步骤并列举了我的行为来产生你想要的结果。

Create a web app project (an thus a solution) named 'ReferencedWebService'
    Add a web service, just leave the default name and implementation
    Add a class library named 'ReferencedWebserviceAPI'
        Add Service Reference
            >Advanced
                >Add Web Reference>Web services in this solution
                    >WebService1
                        >Add reference leaving name as 'localhost'
    Add a console application project named 'ReferencedWebserviceClient'    
    To ReferencedWebserviceClient: 
        Add Reference
            >Projects
                >ReferencedWebserviceAPI
        Add Reference
            >.Net
                >System.Web.Services

    In Program.cs replace Main:

    static void Main(string[] args)
    {
        var svc = new ReferencedWebserviceAPI.localhost.WebService1();
        var result = svc.HelloWorld();
        Console.WriteLine(result);
        Console.ReadLine();
    }


    Set ReferencedWebserviceClient as startup project and run.

    Ok, this is simplest scenario. One issue you will have to deal with is that the default Service URL is hardcoded in the .dll,
    and it is set to a ported address on your dev machine.

    You will want to add a configuration parameter to your client project. The simplest and most portable way is to use an appSetting.

    To ReferencedWebserviceClient:
        Add Item
            >Application Configuration File

    Replace contents of App.Config with this, of course replace the value with the appropriate value on your machine.

    
    
      
        
      
    


        Add Reference
            >.Net
                >System.Configuration

    Now replace Main with this:

    static void Main(string[] args)
    {
        var svc = new ReferencedWebserviceAPI.localhost.WebService1
                      {
                          Url = ConfigurationManager.AppSettings["serviceUrl"]
                      };
        var result = svc.HelloWorld();
        Console.WriteLine(result);
        Console.ReadLine();
    }

This is the baseline for embedding services in a redistributable .dll.这是在可再发行的 .dll 中嵌入服务的基线。

Try to apply this model to your current project and see how that works for you.尝试将此模型应用于您当前的项目,看看它对您有何作用。

If you still have problems, you most definitely have a reference issue and should start looking at it from that perspective.如果你仍然有问题,你肯定有一个参考问题,应该从这个角度来看待它。

Hope this helps希望这可以帮助

You may be using types exposed by the web service, or it may be that you are having to add the web reference so that appropriate connection information is added to the config file.您可能正在使用 Web 服务公开的类型,或者您可能必须添加 Web 引用,以便将适当的连接信息添加到配置文件中。 A winform application will not inherit or use a DLL's config file in any way unless you were to cook up some fancy loading mechanism for it. Winform 应用程序不会以任何方式继承或使用 DLL 的配置文件,除非您为它设计了一些奇特的加载机制。 In other words, in the DLL when you add a web reference, it's config file gets information about how to connect to the web service, but when you then use the DLL in an application, your application needs that info in it's own config file, thus you must add a web reference so that the information is generated.换句话说,在 DLL 中,当您添加 Web 引用时,它的配置文件获取有关如何连接到 Web 服务的信息,但是当您在应用程序中使用 DLL 时,您的应用程序需要在它自己的配置文件中获取该信息,因此,您必须添加一个网络引用,以便生成信息。

In regards to using a type exposed by the web reference, I'm not sure if this could be an issue you are experiencing.关于使用网络参考公开的类型,我不确定这是否可能是您遇到的问题。 I have encountered this kind of thing in DLLs.我在 DLL 中遇到过这种事情。 For example, SharpMap.dll declares a SharpMapData class, and WrapperOfSharpMap.dll has a method called ProcessData(SharpMapData blah)例如,SharpMap.dll 声明了一个SharpMapData类,而 WrapperOfSharpMap.dll 有一个名为ProcessData(SharpMapData blah)

If I write a WinForm application and add a reference to WrapperOfSharpMap.dll, I also have to add a reference to SharpMap.dll because to call ProcessData I have to create a SharpMapData instance to pass to the function.如果我编写一个 WinForm 应用程序并添加对 WrapperOfSharpMap.dll 的引用,我还必须添加对 SharpMap.dll 的引用,因为要调用ProcessData我必须创建一个SharpMapData实例来传递给函数。 In other words, I am using a type declared in SharpMap.dll, therefore need a reference to it.换句话说,我使用的是在 SharpMap.dll 中声明的类型,因此需要对它的引用。

To resolve this problem, the creator of WrapperOfSharpMap.dll must create a WrapperSharpMapData class like so:为了解决这个问题,WrapperOfSharpMap.dll 的创建者必须像这样创建一个WrapperSharpMapData类:

class WrapperSharpMapData
{
  private SharpMapData hiddenSharpMapData;

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

Is that because you need the service reference so that the WinForm app can reference the types returned by your service?那是因为您需要服务引用,以便 WinForm 应用程序可以引用您的服务返回的类型吗?

If that's the case, you could turn your API dll into a wrapper for the service, and wrap up all the methods available on the service in API, and do the same for the objects (assuming that they are clases you have created).如果是这种情况,您可以将 API dll 转换为服务的包装器,并将服务上可用的所有方法包装在 API 中,并对对象执行相同操作(假设它们是您创建的类)。 Obviously, you'll have to convert all the objects that the service returns into the objects in the API.显然,您必须将服务返回的所有对象转换为 API 中的对象。 But once that's done, you shouldn't need to reference the service in WinForm.但是一旦完成,您就不需要在 WinForm 中引用该服务。 (funnily enough, I'm in the middle of doing something similar myself!). (有趣的是,我自己也在做类似的事情!)。

You could try looking into svcutil.exe , which allows you to generate the client side proxy code for your service via the command line.您可以尝试查看svcutil.exe ,它允许您通过命令行为您的服务生成客户端代理代码。 You should be able to take the code file that it produces and simply add it to your DLL project.您应该能够获取它生成的代码文件并将其添加到您的 DLL 项目中。 This lets you bypass Visual Studio completely.这使您可以完全绕过 Visual Studio。

right-click Add Service Reference in your client's project for add Methods and Classes右键单击客户项目中的“添加服务引用”以添加方法和类

Then To access the service you can then do something like in dll然后要访问该服务,您可以在 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();

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

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