2012-01-20 37 views
1

我的代碼是這樣的:添加Web引用動態C#

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

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

,它不工作。

大家都說代碼就像魅力一樣工作,但我無法讓它工作。爲什麼?

UPDATE: 這裏是我做什麼,當我添加動態參考:

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爲空,我知道最後一行也有錯誤。對我來說,這看起來很愚蠢。

+0

當你說「無法工作」,你會發生什麼,不期望/不會發生這種情況? – CJBrew

+0

@CJBrew那麼wsvcClass總是空的,它不應該是。之後,創建MethodInfo對象時,會有一個空異常。 –

+0

您是否試過單步執行'WsProxy.CallWebService'方法來查看它爲什麼返回null?你確定它甚至可以創建實例嗎? –

回答

1

你試過

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

"nmspace"是錯誤的,因爲這是你的變量,它擁有與沒有名字的CodeNamespace的名稱。

+0

一旦我創建實例,我該如何分配屬性? wsvcClass沒有名稱作爲屬性,但該服務具有。 –

+0

你只需要確保serviceName是你的.asmx文件的名字和代碼的作品(在你的例子中是'somename')。您不需要設置任何屬性,只需調用傳遞參數的方法即可。 – Strillo

+0

以下是我如何使用手動添加的參考: DefectsService.Defect defect = new DefectsService.Defect(); defect.Name =「someName」; 沒有傳遞參數的方法。 –