首页 文章

C的通用WebService(SOAP)客户端库

提问于
浏览
13

我正在寻找一个简单的C WebService客户端库,可以轻松链接到我的应用程序中 .

最好这个库:

  • 可用于访问任何SOAP WebService(因此我可以将URL,WebService名称,WebService方法和所有参数作为参数传递给函数调用)

  • 可以在C应用程序中静态链接(所以没有DLL)

  • 是免费软件或以低成本提供

  • 可以在我的申请中使用免版税

  • 可以在Web服务中查询其WSDL,并返回可用的方法名称,方法的参数及其数据类型

在你们任何人回答.NET之前:去过那里,尝试过 . 我对.NET的主要反对意见是:

  • 您可以生成代理,但之后不可能在生成的代理代码中更改WebService名称,因为.NET使用反射来检查WebService名称(有关该问题,请参阅Dynamically call SOAP service from own scripting language

  • 动态生成代理类似乎并不总能正常工作

我已经使用谷歌查找这些信息,但我找不到一个 .

谢谢

EDIT: 为了进一步澄清这一点,我真的想要一些可以编写这样的代码的东西(或者这种风格的东西):

SoapClient mySoapClient;
mySoapClient.setURL("http://someserver/somewebservice");
mySoapClient.setMethod("DoSomething");
mySoapClient.setParameter(1,"Hello");
mySoapClient.setParameter(2,12345);
mySoapClient.sendRequest();
string result;
mySoapClient.getResult(result);

没有动态代码生成 .

3 回答

  • 6

    Axis2C:http://axis.apache.org/axis2/c/core/index.html

    Axis2C勾选上述大部分内容,请检查静态链接..

    编辑:根据列表中的最后几条消息,静态链接不完整 . 以下仍然有:

    也许我不正确地理解这个问题 . 您调用的任何Web服务都需要指定 endpoints URL以及操作和参数 .

    您是指动态“发现”服务并提供调用它们的选项......?如果是这样,我怀疑这是可能的 .

    如果你指的是通用框架,那么SOAP消息就是客户端的责任......在一些工具包API下你应该没有问题 . WSDL代码生成不是强制性的 . 我已经从头开始编写了一些服务,即您可以根据自己的喜好设置 endpoints ,服务和工艺SOAP消息,参数, Headers 等 .

    干杯!

  • 4

    我找到了一个使用即时生成的程序集的解决方案(我以前无法工作) . 起点是http://refact.blogspot.com/2007_05_01_archive.html .

    例如 . 这是使用PeriodicTable Web服务的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Description;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Xml.Serialization;
    using System.IO;
    using System.Reflection;
    
    namespace GenericSoapClient
    {
    class Program
        {
        static void method1()
            {
            Uri uri = new Uri("http://www.webservicex.net/periodictable.asmx?WSDL");
            WebRequest webRequest = WebRequest.Create(uri);
            System.IO.Stream requestStream = webRequest.GetResponse().GetResponseStream();
    
            // Get a WSDL
            ServiceDescription sd = ServiceDescription.Read(requestStream);
            string sdName = sd.Services[0].Name;
    
            // Initialize a service description servImport
            ServiceDescriptionImporter servImport = new ServiceDescriptionImporter();
            servImport.AddServiceDescription(sd, String.Empty, String.Empty);
            servImport.ProtocolName = "Soap";
            servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
    
            CodeNamespace nameSpace = new CodeNamespace();
            CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
            codeCompileUnit.Namespaces.Add(nameSpace);
    
            // Set Warnings
    
            ServiceDescriptionImportWarnings warnings = servImport.Import(nameSpace, codeCompileUnit);
    
            if (warnings == 0)
                {
                StringWriter stringWriter =
                     new StringWriter(System.Globalization.CultureInfo.CurrentCulture);
    
                Microsoft.CSharp.CSharpCodeProvider prov =
                  new Microsoft.CSharp.CSharpCodeProvider();
    
                prov.GenerateCodeFromNamespace(nameSpace,
                   stringWriter,
                   new CodeGeneratorOptions());
    
                string[] assemblyReferences =
                   new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
    
                CompilerParameters param = new CompilerParameters(assemblyReferences);
    
                param.GenerateExecutable = false;
                param.GenerateInMemory = true;
                param.TreatWarningsAsErrors = false;
    
                param.WarningLevel = 4;
    
                CompilerResults results = new CompilerResults(new TempFileCollection());
                results = prov.CompileAssemblyFromDom(param, codeCompileUnit);
                Assembly assembly = results.CompiledAssembly;
                Type service = assembly.GetType(sdName);
    
                //MethodInfo[] methodInfo = service.GetMethods();
    
                List<string> methods = new List<string>();
    
                // only find methods of this object type (the one we generated)
                // we don't want inherited members (this type inherited from SoapHttpClientProtocol)
                foreach (MethodInfo minfo in service.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
                    {
                    methods.Add(minfo.Name);
                    Console.WriteLine (minfo.Name + " returns " + minfo.ReturnType.ToString());
                    ParameterInfo[] parameters = minfo.GetParameters();
                    foreach (ParameterInfo pinfo in parameters)
                        {
                            Console.WriteLine("   " + pinfo.Name + " " + pinfo.ParameterType.ToString());
                        }
                    }
    
                // Create instance of created web service client proxy
                object obj = assembly.CreateInstance(sdName);
    
                Type type = obj.GetType();
    
                object[] args0 = new object[] { };
                string result0 = (string)type.InvokeMember(methods[0], BindingFlags.InvokeMethod, null, obj, args0);
                Console.WriteLine(result0);
    
                object[] args1 = new object[] { "Oxygen" };
                string result1 = (string)type.InvokeMember(methods[1], BindingFlags.InvokeMethod, null, obj, args1);
                Console.WriteLine(result1);
                }
            }
        }
    }
    

    在这段代码中我明确使用了 methods[0]methods[1] ,但实际上你会检查方法名称 . 在这个例子中,我得到元素周期表中所有元素的名称,然后得到氧的原子量 .

    此示例尚未包含支持代理的逻辑 . 我仍然需要添加它,但目前,它解决了我最大的问题,即拥有一个通用的SOAP客户端 .

    EDIT:

    我知道这段代码是C#,我最初要求的是C解决方案,但是这段代码证明它可以在.NET环境中工作(我仍然可以在我的应用程序的有限部分使用),我可能会重写这段代码进入C / .NET,解决了我的问题 .

  • 1

    你看过gSOAP了吗?我认为它将适合您的需求 .

    http://gsoap2.sourceforge.net/

相关问题