Frage Objekt des Typs 'customObject' kann nicht in 'customObject' konvertiert werden


Ich erhalte den folgenden Fehler, wenn ich ein benutzerdefiniertes Objekt aufruft
"Object of type 'customObject' cannot be converted to type 'customObject'."

Folgendes ist das Szenario, wenn ich diesen Fehler erhalte:

  • Ich rufe dynamisch eine Methode in einer DLL auf.
  • Laden Sie eine Baugruppe
  • CreateInstance ....

Beim Aufrufen von MethodInfo.Invoke () passing int, string als Parameter für meine Methode funktioniert gut => Es werden keine Ausnahmen ausgelöst.

Aber wenn ich versuche, eines meiner eigenen benutzerdefinierten Klassenobjekte als Parameter zu übergeben, bekomme ich ein ArgumentException Ausnahme, und es ist auch nicht ein ArgumentOutOfRangeException oder ArgumentNullException.

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

Ich mache das in einer Webanwendung.

Die Klassendatei, die die Methode enthält, befindet sich in einem anderen Projekt. Außerdem ist das benutzerdefinierte Objekt eine separate Klasse in derselben Datei.

So etwas gibt es nicht static assembly in meinem Code. Ich versuche, eine Webmethode dynamisch aufzurufen. Diese Webmethode hat den Typ customObject als Eingabeparameter. Wenn ich also die Webmethode aufruft, erstelle ich die Proxy-Assembly und alle dynamisch. Von derselben Assembly versuche ich, eine Instanz des Cusotm-Objekts zu erstellen, die die Werte den Eigenschaften zuordnet und dann dieses Objekt als Parameter übergibt und die Methode aufruft. alles ist dynamisch und nichts ist statisch .. :(

Referenz hinzufügen wird nicht verwendet. Folgendes ist ein Beispielcode, den ich versucht habe, es zu erstellen

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

Ich kann nichts finden static in was ich mache.

Jede Hilfe wird sehr geschätzt.

Grüße, Phani Kumar PV


5
2018-04-12 13:22


Ursprung


Antworten:


Haben Sie sich angesehen, wie die Proxy-Klasse aussieht, die generiert wird? Du nicht brauchen der Proxy, um einen Web-Service anzurufen. Erstellen Sie einfach eine Klasse, von der er erbt SoapHttpClientProtocol und rufen Sie Invoke (methodName, params) auf.

Sie machen das SO viel komplizierter als Sie brauchen. Ehrlich.

BEARBEITEN Wenn Sie eine Klasse wie folgt erstellen:

public class SoapClient : SoapHttpClientProtocol
{

    public SoapClient()
    {

    }

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

}

und nenne es so:

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

Ich denke, Sie werden sehen, dass es die gleichen Ergebnisse wie das, was Sie tun, hat.


2
2018-04-14 17:58



Lassen Sie mich versuchen, den wahrscheinlichsten Grund für das Problem in meiner Annäherung zu erklären.

Als ich eine Methode in der Assembly namens "Methodenname" im Webservice aufgerufen habe, versuche ich, die dafür benötigten Parameter als args [] an die Funktion "CallWebService" zu übergeben Diese Argumente [], wenn sie übergeben werden, werden erfolgreich funktionieren, wenn ich versuche, normale Parameter wie primitive Typen einschließlich String zu übergeben.

Aber das habe ich gemacht, als ich versucht habe, ein benutzerdefiniertes Objekt als Parameter zu übergeben.

Drei Dinge, die dabei gemacht werden.

  1. Erstellen Sie ein Objekt dieses Typs außerhalb der CallWebService-Funktion (mit Reflektion). Wenn ich auf diese Weise vorgehe, passiert eine Instanz des benutzerdefinierten Objekts, das intern mit einem temporären DLL-Namen erstellt wird.
  2. Sobald ich die Eigenschaften des Objekts festgelegt habe, wird es an die CallWebService-Funktion als Objekt im Array args gesendet.
  3. Ich bin müde, um eine Instanz des Webservice zu erstellen, indem ich die dynamische DLL erstelle.

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

Als ich schließlich versuchte, die Methode mit der Instanz der erstellten dynamischen Assembly aufzurufen  Ich habe versucht, das customobject, das in Schritt 1,2 erstellt wird, über die Eigenschaft args zu übergeben.

Zum Zeitpunkt des Aufrufs versucht die CLR festzustellen, ob das benutzerdefinierte Objekt, das als Eingabe übergeben wurde, und die Methode, die aufgerufen wird, aus derselben DLL stammen.

was offensichtlich nicht von der Art ist, wie die Implementierung durchgeführt wird.

Folgend ist der Ansatz, der verwendet werden sollte, um das Problem zu überwinden Ich muss die benutzerdefinierte Objektgruppe mit derselben Assembly erstellen, mit der ich die Webservice-Instanz erstellt habe.

Ich habe diesen Ansatz vollständig umgesetzt und es hat gut funktioniert

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
2018-04-15 16:21



Dies kann auftreten, wenn sich die Version einer DLL, auf die Sie in Ihrem reflektierten Code verwiesen haben, von der Version dieser DLL in Ihrem kompilierten Code unterscheidet.


1
2018-01-05 05:23



Dies ist ein alter Thread, aber ich hatte gerade ein ähnliches Problem. Ich schaute hierhin, dieser erschien, aber ich sah keine brauchbaren Lösungen.

Der Fehler des OP war folgender: Objekt des Typs 'customObject' kann nicht in 'customObject' konvertiert werden.

Mein sehr ähnlicher Fehler war der: Objekt des Typs 'System.String' kann nicht in den Typ 'System.Windows.Forms.AccessibleRole' konvertiert werden.

Hier ist, wie ich mein Problem gelöst habe:

Ich machte eine Suchen und Ersetzen (benutzen CRTL+VERSCHIEBUNG+F um das Dialogfeld aufzurufen) suchen Sie in der Derzeitiges Projekt für den Begriff AccessibleRole.

Find and Replace dialog

In einem der Designer des Formulars war ein Platz, wo ich einen zugewiesen hatte AccessibleRole Wert zu a String Variable mit ToString().

Ich habe das behoben und mein Problem ist weg.

Ich hoffe, dass dies anderen hilft.


0
2018-04-03 14:28