当我调用自定义对象时,我收到以下错误
"Object of type 'customObject' cannot be converted to type 'customObject'."
以下是我收到此错误的情况:
当调用MethodInfo.Invoke()传递int时,string作为我方法的参数工作正常=>没有例外被抛出。
但是如果我尝试将自己的一个自定义类对象作为参数传递,那么我会得到一个ArgumentException
异常,它不是ArgumentOutOfRangeException
或ArgumentNullException
。< / 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
答案 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 []将成功运行。
但这是我在尝试将自定义对象作为参数传递时所做的。
在此完成了三件事。
我厌倦了通过创建动态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;
}
答案 2 :(得分:1)
当您在反映代码中引用的dll版本与编译代码中该dll的版本不同时,就会发生这种情况。
答案 3 :(得分:0)
这是一个老线程,但我遇到了类似的问题。我在这里看了一下,突然出现了这个,但我没有看到任何有用的解决方案。
OP的错误是这样的:'customObject'类型的对象无法转换为'customObject'类型。
我非常相似的错误是:'System.String'类型的对象无法转换为'System.Windows.Forms.AccessibleRole'类型。
以下是我解决问题的方法:
我执行了查找和替换(使用 CRTL + SHIFT + F 以显示对话框)在当前项目中搜索 AccessibleRole 一词。
在Form的Designer之一中,我使用AccessibleRole
为String
变量分配ToString()
值。
我修好了,我的问题就消失了。
我希望这可以为他人提供帮助。