2010-04-12 20 views
5

recibo el siguiente error cuando invoco un objeto personalizado
"Object of type 'customObject' cannot be converted to type 'customObject'."objeto de tipo 'customObject' no se puede convertir al tipo 'customObject'

A continuación se presenta el escenario cuando estoy conseguir este error:

  • Invoco dinámicamente un método en un dll.
  • cargar un ensamblado
  • CreateInstance ....

Al llamar MethodInfo.Invoke() int paso, cadena como un parámetro para mi método funciona bien => No se lanzan excepciones.

Pero si trato de pasar uno de mis propios objetos de clase personalizados como parámetro, entonces obtengo una excepción ArgumentException, y no es ArgumentOutOfRangeException o ArgumentNullException.

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

que estoy haciendo esto en una aplicación web.

El archivo de clase que contiene el método está en un proyecto diferente. Además, el objeto personalizado es una clase separada en el mismo archivo.

No existe tal cosa como static assembly en mi código. Intento invocar un webmethod dinámicamente. este método web está teniendo el tipo de objeto personalizado como un parámetro de entrada. Entonces cuando invoco el método web estoy creando dinámicamente el ensamblado proxy y todo. Desde el mismo ensamble estoy tratando de crear una instancia del objeto cusotm asignando los valores a sus propiedades y luego pasando este objeto como un parámetro e invocando el método. todo es dinámico y nada se crea estática .. :(no se utiliza

Agregar referencia. siguiente es un ejemplo de código que traté de crearlo

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; 
      } 
     } 
    } 

no puedo encontrar nada en lo que static hacer.

Cualquier ayuda es muy apreciada.

Regards, Phani Kumar PV

+0

* ¿Por qué? ¿Harías esto? ¿Por qué no simplemente "agregar referencia web" al proyecto? – Aaronaught

+0

estoy desarrollando una aplicación en la que, dada la URL de WSDl, necesito invocar un método web en ella. como se supone que debo usar diferentes métodos web, no puedo hacer una referencia web. –

Respuesta

2

¿Has visto cómo se ve la clase proxy que se genera? Usted no necesita el proxy para llamar a un servicio web. Simplemente crea una clase que hereda de SoapHttpClientProtocol y llama a Invoke (methodName, params).

Usted está haciendo esto mucho más complicado de lo que necesita. Honestamente.

EDITAR Si crea una clase como esta:

public class SoapClient : SoapHttpClientProtocol 
{ 

    public SoapClient() 
    { 

    } 

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

} 

y lo llaman así:

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

Creo que va a ver que tiene los mismos resultados exactos que lo Tú lo estás haciendo.

+0

Revisé el código compartido en el enlace. Parece que se puede usar cuando la información sobre los espacios de nombres del servicio web y los métodos web están disponibles. Pero en la aplicación que estoy desarrollando actualmente obtendré la wdsl url dinámicamente y se cambia con frecuencia. en ese escenario, el enfoque especificado en la url dada no resolverá mi problema. por favor, avíseme si lo hice en la dirección incorrecta. –

+0

Actualicé mi respuesta con un ejemplo de código para explicar de qué estoy hablando. –

+0

Sí, esta respuesta es correcta. La única razón por la que necesita compilar el código del servicio web es si necesita verificar el tipo de tiempo de compilación contra una URL conocida del servicio web. Ya estás en tiempo de ejecución cuando invocas esto, así que realmente no te sirve. – ZeroBugBounce

2

Permítanme intentar explicar la razón más probable del problema en mi enfoque.

Cuando invoqué un método en el ensamblado llamado "methodname" en el servicio web estoy tratando de pasar los parámetros necesarios para eso como args [] a la función "CallWebService" Esto args [] cuando se pasa será exitoso trabajando cuando trato de pasar un parámetro normal como tipos primitivos incluyendo cadena.

Pero esto es lo que hice cuando traté de pasar un objeto personalizado como parámetro.

Tres cosas que se hacen en esto.

  1. crear un objeto de ese tipo fuera de la función CallWebService (utilizando la reflexión). cuando lo hice, lo que ocurre es una instancia del objeto personalizado creado internamente con un nombre dll temporal.
  2. una vez que establezco el conjunto las propiedades del objeto y lo envío a la función CallWebService como un objeto en la matriz args.
  3. Me cansé de crear una instancia del servicio web creando el dll dinámico.

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

Cuando finalmente intentado para invocar el método con el ejemplo del conjunto de dinámicas creadas Traté de pasar el customobject que se crea en el paso a través de 1,2 propiedad args.

en el momento de la invocación, el CLR intenta ver si el objeto personalizado que se pasa como entrada y el método que se invoca provienen de la misma DLL.

que obviamente no es por la forma en que se realiza la implementación.

Así que sigue es el enfoque que se debe utilizar para superar el problema que necesito para crear el ensamblado objeto personalizado con el mismo montaje que he utilizado para crear el servicio web ejemplo ..

he implementado este enfoque completamente y funcionó bien

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

Esto es un hilo viejo, pero acabo de tener un problema similar. Miré aquí, este apareció, pero no vi soluciones útiles.

El error del OP fue el siguiente: El objeto de tipo 'customObject' no se puede convertir a tipo 'customObject'.

Mi error muy similar fue esto: El objeto de tipo 'System.String' no se puede convertir a tipo 'System.Windows.Forms.AccessibleRole'.

Aquí es cómo resolví mi problema:

He realizado un Buscar y reemplazar (use CRTL + SHIFT + F para llevar el cuadro de diálogo hacia arriba) de búsqueda en el actual Proyecto para el término AccessibleRole.

Find and Replace dialog

Dentro de uno de Diseñador de la Forma de un lugar donde estaba la asignación de un valor a una variable AccessibleRoleString usando ToString().

Solucioné esto y mi problema desapareció.

Espero que esto ayude a otros.

1

esto puede ocurrir cuando la versión de un dll que ha hecho referencia en su código reflejado es diferente de la versión de ese dll en su código compilado.

Cuestiones relacionadas