动态Web服务客户端

时间:2015-01-29 09:35:32

标签: c# web-services soap reflection

我写了一个动态的Web服务客户端。这适用于SOAP 1.1但使用SOAP 1.2

失败

当我使用ServiceDescriptionImporter.Import时,我收到以下警告:

  

OptionalExtensionsIgnored

以下是准备网络服务的代码:

 using (var client = new WebClient())
        {
            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
            client.Credentials = new NetworkCredential(@"domain\user","password");
            using (var stream = client.OpenRead(url))
            {
                // Get a WSDL file describing the service.
                ServiceDescription description = ServiceDescription.Read(stream);

                // Initialize a service description importer.
                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
                importer.ProtocolName = webServiceProtocol.ToString();
                importer.Style = ServiceDescriptionImportStyle.Client;
                importer.AddServiceDescription(description, null, null);

                // Report on the service descriptions.
                Console.WriteLine("Importing {0} service descriptions with {1} associated schemas.",
                                  importer.ServiceDescriptions.Count, importer.Schemas.Count);

                // Add any imported files
                foreach (System.Xml.Schema.XmlSchema wsdlSchema in description.Types.Schemas)
                {
                    foreach (System.Xml.Schema.XmlSchemaObject externalSchema in wsdlSchema.Includes)
                    {
                        if (externalSchema is System.Xml.Schema.XmlSchemaImport)
                        {
                            Uri baseUri = new Uri(url);
                            Uri schemaUri = new Uri(baseUri, ((System.Xml.Schema.XmlSchemaExternal)externalSchema).SchemaLocation);
                            using (var schemaStream = client.OpenRead(schemaUri))
                            {
                                System.Xml.Schema.XmlSchema schema = System.Xml.Schema.XmlSchema.Read(schemaStream, null);
                                importer.Schemas.Add(schema);
                            }
                            Console.WriteLine(((System.Xml.Schema.XmlSchemaExternal)externalSchema).SchemaLocation);
                        }
                    }
                }

                // Generate a proxy client.
                importer.Style = ServiceDescriptionImportStyle.Client;

                // Generate properties to represent primitive values.
                importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;

                // Initialize a Code-DOM tree into which we will import the service.
                CodeNamespace nmspace = new CodeNamespace();
                CodeCompileUnit unit1 = new CodeCompileUnit();
                unit1.Namespaces.Add(nmspace);

                // Import the service into the Code-DOM tree. This creates proxy code
                // that uses the service.
                ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
                Console.WriteLine("Warning: " + warning);

                if (warning == 0 || warning == ServiceDescriptionImportWarnings.OptionalExtensionsIgnored)
                {
                    // Generate and print the proxy code in C#.
                    CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");

                    // Compile the assembly with the appropriate references
                    string[] assemblyReferences = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
                    CompilerParameters parms = new CompilerParameters(assemblyReferences);
                    CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
                    assembly = results.CompiledAssembly;

                    foreach (CompilerError oops in results.Errors)
                    {
                        Console.WriteLine("========Compiler error============");
                        Console.WriteLine(oops.ErrorText);
                    }

                }
                else
                {
                    // Print an error message.
                    Console.WriteLine("Warning: " + warning);
                }
            }
        }

如果我忽略警告并使用CodeDomProvider编译代码,则编译时没有错误。问题是当我从Web服务调用方法时,我得到以下错误:

  

调用目标抛出了异常。 SOAP标头   行动没有被理解。

调用该方法的代码如下:

 //Invoke the web service method
        object service = GetAssembly().CreateInstance("BizTalkServiceInstance");
        Type serviceType = service.GetType();
        PropertyInfo propInfo = serviceType.GetProperty("Credentials");
        propInfo.SetValue(service, new NetworkCredential("user", "pass", "domain"), null);

        object request = GetObjectFromString(requestName, requestValue);

        object response = serviceType.InvokeMember(methodName, System.Reflection.BindingFlags.InvokeMethod, null, service, new object[] { request });
        Console.WriteLine(GetValueFromObject(responseName,response));
        Console.ReadLine();
        return null;

我真的无法理解我所缺少的东西。

1 个答案:

答案 0 :(得分:0)

看起来我是以旧的方式做这件事。我已切换到ServiceContractGenerator。现在,这将创建一个Service Client对象,该对象提供了一个允许您设置绑定的构造函数。

它现在抛出了我的一个服务上的编译错误,但至少我有1.1和1.2服务都在工作。

您可以在此处使用新方法查看代码和我的问题: ServiceContractGenerator CodeDomProvider Compile Errors