Объект типа «customObject» не может быть преобразован в тип «customObject» - PullRequest
5 голосов
/ 12 апреля 2010

Я получаю следующую ошибку при вызове пользовательского объекта
"Object of type 'customObject' cannot be converted to type 'customObject'."

Ниже приведен сценарий, когда я получаю эту ошибку:

  • Я вызываю метод в dll динамически.
  • Загрузить сборку
  • CreateInstance ....

При вызове MethodInfo.Invoke (), передающем int, строка в качестве параметра для моего метода работает нормально => Никаких исключений не выдается.

Но если я попытаюсь передать один из моих собственных объектов класса в качестве параметра, тогда я получу исключение ArgumentException, и оно не будет ArgumentOutOfRangeException или ArgumentNullException.

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

Я делаю это в веб-приложении.

Файл класса, содержащий метод, находится в другом проекте. Также пользовательский объект - это отдельный класс в том же файле.

В моем коде нет такого понятия, как static assembly. Я пытаюсь вызвать веб-метод динамически. этот веб-метод имеет тип customObject в качестве входного параметра. Поэтому, когда я вызываю веб-метод, я динамически создаю сборку прокси и все. Из той же сборки я пытаюсь создать экземпляр объекта 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 ]

2 голосов
/ 15 апреля 2010

Позвольте мне попытаться объяснить наиболее вероятную причину возникновения проблемы в моем подходе.

Когда я вызывал метод в сборке, который называется «methodname» в веб-сервисе, я пытаюсь передать требуемые для этого параметры как args [] в функцию «CallWebService» Этот аргумент [] при прохождении будет успешно работать, когда я пытаюсь передать нормальные параметры, такие как примитивные типы, включая строку.

Но это то, что я сделал, когда попытался передать пользовательский объект в качестве параметра.

Три вещи, которые сделаны в этом.

  1. создать объект этого типа вне функции CallWebService (используя отражение). когда я сделал так, что происходит, это экземпляр пользовательского объекта, созданного с временным именем DLL внутри.
  2. однажды я установил набор свойств объекта и отправил его в функцию CallWebService как объект в массиве args.
  3. Я устал создавать экземпляр веб-сервиса, создавая динамическую DLL.

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

Когда я наконец попытался вызвать метод с экземпляром динамической сборки, созданной Я попытался передать пользовательский объект, созданный на шаге 1,2, через свойство args.

во время вызова CLR пытается определить, являются ли пользовательский объект, который передается в качестве входных данных, и вызываемый метод из одной и той же DLL.

что явно не от способа реализации.

Таким образом, следующий подход должен быть использован для преодоления проблемы Мне нужно создать пользовательскую сборку объекта с той же сборкой, которую я использовал для создания экземпляра веб-службы ..

Я полностью реализовал этот подход, и он отлично сработал

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 голосов
/ 14 апреля 2010

Вы смотрели, как выглядит прокси-класс, который генерируется? Вам не нужен прокси для вызова веб-службы. Просто создайте класс, который наследуется от SoapHttpClientProtocol и вызовите Invoke (methodName, params).

Вы делаете это НАСТОЛЬКО сложнее, чем нужно. Честно.

EDIT Если вы создаете такой класс:

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 голос
/ 05 января 2015

это может произойти, когда версия DLL, на которую вы ссылались в своем отраженном коде, отличается от версии этой DLL в скомпилированном коде.

0 голосов
/ 03 апреля 2012

Это старая ветка, но у меня просто была похожая проблема. Я посмотрел здесь, это выскочило, но я не увидел никаких полезных решений.

Ошибка ОП была следующей: Объект типа 'customObject' не может быть преобразован в тип 'customObject'.

Моя очень похожая ошибка была такой: Объект типа 'System.String' нельзя преобразовать в тип 'System.Windows.Forms.AccessibleRole'.

Вот как я решил свою проблему:

Я выполнил Найти и заменить (используйте CRTL + SHIFT + F , чтобы вызвать диалоговое окно), поиск в Текущий проект на срок AccessibleRole .

Find and Replace dialog

В одном из конструкторов форм было место, где я присваивал значение AccessibleRole переменной String, используя ToString().

Я исправил это, и моя проблема ушла.

Надеюсь, это поможет другим.

...