C# 在C中动态添加web引用#

C# 在C中动态添加web引用#,c#,reference,C#,Reference,我的代码是: internal class WsProxy { [SecurityPermissionAttribute(SecurityAction.Demand, Unrestricted = true)] internal static object CallWebService(string webServiceAsmxUrl, string userName, string password, string serviceName, string methodName

我的代码是:

internal class WsProxy
{

    [SecurityPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
    internal static object CallWebService(string webServiceAsmxUrl, string userName, string password, string serviceName, string methodName, object[] args) 
    {

        System.Net.WebClient client = new System.Net.WebClient();
        if (userName.Length > 0)
        {
            client.Credentials = new NetworkCredential(userName, password);
        } 
        // Connect To the web service

        System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl");

        // Now read the WSDL file describing a service.

        ServiceDescription description = ServiceDescription.Read(stream);

        ///// LOAD THE DOM /////////

        // Initialize a service description importer.

        ServiceDescriptionImporter importer = new ServiceDescriptionImporter();

        importer.ProtocolName = "Soap"; // Use SOAP 1.2.

        importer.AddServiceDescription(description, null, null);

        // 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);

        if (warning == 0) // If zero then we are good to go
        {

            // Generate the proxy code

            CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");

            // Compile the assembly proxy with the appropriate references

            string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };

            CompilerParameters parms = new CompilerParameters(assemblyReferences);

            CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);

            // Check For Errors

            if (results.Errors.Count > 0)
            {

                foreach (CompilerError oops in results.Errors)
                {

                    System.Diagnostics.Debug.WriteLine("========Compiler error============");

                    System.Diagnostics.Debug.WriteLine(oops.ErrorText);

                }

                throw new System.Exception("Compile Error Occured calling webservice. Check Debug ouput window.");

            }

            // Finally, Invoke the web service method

            object wsvcClass = results.CompiledAssembly.CreateInstance("nmspace");//nmspace

            MethodInfo mi = wsvcClass.GetType().GetMethod(methodName);

            return mi.Invoke(wsvcClass, args);

        }

        else
        {

            return null;

        }

    }
我这样称呼它:

object[] arg = new object[5];
WsProxy.CallWebService(@"myurl/somename.asmx", "NameService", "TheMethod", arg); 
但每次wsvcClass都是空的

我试着换衣服

object wsvcClass = results.CompiledAssembly.CreateInstance("nmspace");

但它不起作用

每个人都说代码很有魅力,但我无法让它发挥作用。为什么?

更新: 以下是动态添加引用时的操作:

Namespace.MyService defect = new Namespace.MyService();
defect.Name = "someName";
下面是我如何通过代码来实现的:

object wsvcClass = results.CompiledAssembly.CreateInstance("Namespace." + "MyService");
MethodInfo mi = wsvcClass.GetType().GetMethod("Namespace." + "MyService");
return mi.Invoke(null, new object[] { "someName" });
mi为空,我知道最后一行也有问题。我只是觉得它很愚蠢。

你试过了吗

object wsvcClass = results.CompiledAssembly.CreateInstance(serviceName);
“nmspace”
是错误的,因为这是变量的名称,它包含一个没有名称的CodeNamespace。

您尝试过吗

object wsvcClass = results.CompiledAssembly.CreateInstance(serviceName);

“nmspace”
是错误的,因为这是变量的名称,其中包含一个没有名称的CodeNamespace。

当您说“无法使其工作”时,会发生什么您不希望/不会发生的事情?@CJBrew Well wsvcClass始终为空,并且不应该为空。之后,在创建MethodInfo对象时,出现了一个null异常。您是否尝试过单步执行
WsProxy.CallWebService
方法来查看它返回null的原因?你确定它甚至可以创建实例吗?据我所知,CreateInstance需要完整的命名空间和类型名。。。什么是“nmspace”?@CJBrew创建实例后,如何分配属性?wsvcClass没有名称作为属性,但服务有。当您说“无法使其工作”时,会发生什么您不期望/不应该发生的事情?@CJBrew-Well wsvcClass始终为空,并且不应该为空。之后,在创建MethodInfo对象时,出现了一个null异常。您是否尝试过单步执行
WsProxy.CallWebService
方法来查看它返回null的原因?你确定它甚至可以创建实例吗?据我所知,CreateInstance需要完整的命名空间和类型名。。。什么是“nmspace”?@CJBrew创建实例后,如何分配属性?wsvcClass没有名称作为属性,但服务有。创建实例后,如何分配属性?wsvcClass没有name作为属性,但服务有。您只需要确保serviceName是.asmx文件的名称,并且代码正常工作(
somename
)。您不需要设置任何属性,只需调用传递参数的方法即可;defect.Name=“someName”;没有传递参数的方法。您的问题是关于动态调用web服务,当您使用
mi.Invoke(wsvcClass,args)执行传递参数的方法时,代码就是这样做的。为什么需要设置Name属性?
Defect
是传递给服务方法的对象吗?您可以编辑问题(或添加新问题)并发布您想要使用的代码吗?创建实例后,如何分配属性?wsvcClass没有name作为属性,但服务有。您只需要确保serviceName是.asmx文件的名称,并且代码正常工作(
somename
)。您不需要设置任何属性,只需调用传递参数的方法即可;defect.Name=“someName”;没有传递参数的方法。您的问题是关于动态调用web服务,当您使用
mi.Invoke(wsvcClass,args)执行传递参数的方法时,代码就是这样做的。为什么需要设置Name属性?
Defect
是传递给服务方法的对象吗?您可以编辑问题(或添加新问题)并发布您想要使用的代码吗?