“customObject”类型的对象无法转换为“customObject”类型

时间:2010-04-12 13:22:47

标签: c# asp.net web-services reflection web-applications

当我调用自定义对象时,我收到以下错误 "Object of type 'customObject' cannot be converted to type 'customObject'."

以下是我收到此错误的情况:

  • 我动态调用dll中的方法。
  • 加载程序集
  • 的CreateInstance ....

当调用MethodInfo.Invoke()传递int时,string作为我方法的参数工作正常=>没有例外被抛出。

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

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

我在网络应用程序中这样做。

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

我的代码中没有称为static assembly的东西。我试图动态调用web方法。此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 Kumar PV

4 个答案:

答案 0 :(得分: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);

我认为你会发现它与你正在做的事情完全相同。

答案 1 :(得分:2)

让我试着解释一下问题的最可能原因。

当我在webservice中调用一个名为“methodname”的程序集中的方法时,我试图将args []所需的参数传递给函数“CallWebService” 当我尝试传递普通参数(如包括字符串的原始类型)时,传递的args []将成功运行。

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

在此完成了三件事。

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

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

  4. 当我最终尝试使用创建的动态程序集的实例调用该方法时  我试图通过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;
    }
    

答案 2 :(得分:1)

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

答案 3 :(得分:0)

这是一个老线程,但我遇到了类似的问题。我在这里看了一下,突然出现了这个,但我没有看到任何有用的解决方案。

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

我非常相似的错误是:'System.String'类型的对象无法转换为'System.Windows.Forms.AccessibleRole'类型。

以下是我解决问题的方法:

我执行了查找和替换(使用 CRTL + SHIFT + F 以显示对话框)在当前项目中搜索 AccessibleRole 一词。

Find and Replace dialog

在Form的Designer之一中,我使用AccessibleRoleString变量分配ToString()值。

我修好了,我的问题就消失了。

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