2010-04-12 169 views
5

我收到以下错误,当我调用自定义对象
"Object of type 'customObject' cannot be converted to type 'customObject'."对象不能转换为类型“customObject”

以下是当我得到这个错误的场景:

  • 我动态调用dll中的方法。
  • 负载的组件
  • 的CreateInstance ....

当调用MethodInfo.Invoke()通过INT,字符串作为我的方法的参数正常工作=>没有抛出异常。

但是,如果我尝试传递一个自己的自定义类对象作为参数,那么我会得到一个ArgumentException异常,它不是ArgumentOutOfRangeExceptionArgumentNullException

"Object of type 'customObject' cannot be converted to type 'customObject'."

我在一个Web应用程序这样做。

包含该方法的类文件位于不同的项目中。自定义对象也是同一个文件中的一个单独的类。

在我的代码中没有这样的东西叫做static assembly。我正在尝试动态调用webmethod。此webmethod将customObject类型作为输入参数。所以,当我调用webmethod我动态创建代理程序集和所有。从相同的程序集中,我试图创建一个cusotm对象的实例,将值赋予其属性,然后将此对象作为参数传递并调用该方法。一切都是动态的,并没有什么创建静态.. :(不使用

添加引用。 下面是一个示例代码,我试图创建它

public static object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args) 
    { 
     System.Net.WebClient client = new System.Net.WebClient(); 
     //-Connect To the web service 
     using (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 = "Soap12"; // 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) 
       { 
        StringBuilder sb = new StringBuilder(); 
        foreach (CompilerError oops in results.Errors) 
        { 
         sb.AppendLine("========Compiler error============"); 
         sb.AppendLine(oops.ErrorText); 
        } 
        throw new System.ApplicationException("Compile Error Occured calling webservice. " + sb.ToString()); 
       } 
       //--Finally, Invoke the web service method 
       Type foundType = null; 
       Type[] types = results.CompiledAssembly.GetTypes(); 
       foreach (Type type in types) 
       { 
        if (type.BaseType == typeof(System.Web.Services.Protocols.SoapHttpClientProtocol)) 
        { 
         Console.WriteLine(type.ToString()); 
         foundType = type; 
        } 
       } 

       object wsvcClass = results.CompiledAssembly.CreateInstance(foundType.ToString()); 
       MethodInfo mi = wsvcClass.GetType().GetMethod(methodName); 
       return mi.Invoke(wsvcClass, args); 
      } 
      else 
      { 
       return null; 
      } 
     } 
    } 

我不能有什么发现什么static我做的。

任何帮助是极大的赞赏。

问候, Phani库马尔PV

+0

*为什么*你会这样做?为什么不为项目添加“Web引用”? – Aaronaught 2010-04-12 14:18:07

+0

我正在开发一个应用程序,其中给定WSDl url,我需要调用它的webmethod。因为我应该使用不同的webmethods我不能做一个Web引用。 – 2010-04-12 14:25:43

回答

2

你有没有看过代理类看起来像什么生成?您不需要需要调用Web服务的代理。只需创建一个继承自SoapHttpClientProtocol的类并调用Invoke(methodName,params)。

你让这个比你需要的复杂得多。老实说。

编辑 如果你创建一个这样的类:

public class SoapClient : SoapHttpClientProtocol 
{ 

    public SoapClient() 
    { 

    } 

    public object[] Invoke(string method, object[] args) 
    { 
     return base.Invoke(method, args); 
    } 

} 

,并调用它像这样:

SoapClient soapClient = new SoapClient(); 
soapClient.Url = webServiceAsmxUrl; 
soapClient.Invoke(methodName, args); 

我想你会看到它有完全相同的结果是什么你在做。

+0

我浏览了链接中共享的代码。它似乎可以用于当web服务和web方法的名称空间可用时。 但在我目前正在开发的应用程序中,我将动态获取wdsl url,并且它会频繁更改。在这种情况下,在给定的url中指定的方法不会解决我的问题。请让我知道如果我把它弄错了方向。 – 2010-04-15 05:50:54

+0

用代码示例更新了我的答案,以解释我在说什么。 – 2010-04-15 13:52:52

+0

是的,这个答案是正确的。您需要编译Web服务代码的唯一原因是您需要对已知Web服务URL进行编译时类型检查。当你调用这个函数时,你已经处于运行时,所以它确实对你没有好处。 – ZeroBugBounce 2010-04-15 13:59:53

2

让我试着解释在我的方法中出现问题的最可能原因。

当我在webservice中调用一个名为“methodname”的程序集中的方法时,我试图将作为参数args []所需的参数传递给函数“CallWebService” 这个args []传递时会成功当我试图传递像包括字符串的基本类型的正常参数时工作。

但是这是我尝试传递一个自定义对象作为参数时所做的。

三件事情在这做。

  1. 在CallWebService函数之外(使用反射)创建该类型的对象。当我这样做时会发生的是一个内部使用临时dll名称创建的customobject实例。
  2. 一旦我设置了对象的属性并将其作为args数组中的对象发送到CallWebService函数。
  3. 我厌倦了通过创建动态DLL来创建webservice的一个实例。

    object wsvcClass = results.CompiledAssembly.CreateInstance(foundType.ToString());

当我最后试图与动态组件的实例调用方法创建 我试图通过其在经由ARGS属性步骤1,2中创建的customobject。

在调用时,CLR尝试查看作为输入传递的customobject和正在调用的方法是否来自同一个DLL。

这显然不符合实施的方式。

所以下面是应该用来解决这个问题 我需要创建与我以前的创建WebService实例相同的程序集的自定义对象组件的方法..

我完全实现了这个方法它工作得很好

MethodInfo m = type.GetMethod(methodName); 
ParameterInfo[] pm = m.GetParameters(); 
object ob; 
object[] y = new object[1]; 
foreach (ParameterInfo paraminfo in pm) 
{ 
    ob = this.webServiceAssembly.CreateInstance(paraminfo.ParameterType.Name); 

    //Some Junk Logic to get the set the values to the properties of the custom Object 
    foreach (PropertyInfo propera in ob.GetType().GetProperties()) 
    { 
     if (propera.Name == "AppGroupid") 
     { 
      propera.SetValue(ob, "SQL2005Tools", null); 
     } 
     if (propera.Name == "Appid") 
     { 
      propera.SetValue(ob, "%", null); 
     } 
    } 
    y[0] = ob; 
} 
0

这是一个古老的线程,但我只是有一个类似的问题。我看到这里,这个弹出来,但我没有看到有用的解决方案。

OP的错误是这样的:类型'customObject'的对象不能转换为类型'customObject'。

我非常类似的错误是这样的:类型'System.String'的对象不能转换为类型'System.Windows.Forms.AccessibleRole'。

这是我如何解决我的问题:

我进行查找和替换(使用CRTL + SHIFT + ˚F带来的对话框上)在当前搜索项目为期AccessibleRole

Find and Replace dialog

在窗体的设计人员之一,是我在那里用ToString()分配一个AccessibleRole值到String变量的地方。

我解决了这个问题,我的问题消失了。

我希望这可以为他人提供帮助。

1

当您在反射代码中引用的dll的版本与编译代码中该dll的版本不同时,可能会发生这种情况。

相关问题