2010-04-12 18 views
5

tôi nhận được lỗi sau khi tôi gọi một đối tượng tùy chỉnh
"Object of type 'customObject' cannot be converted to type 'customObject'."Object kiểu 'customObject' không thể được chuyển đổi sang loại 'customObject'

Sau đây là kịch bản khi tôi nhận được lỗi này:

  • Tôi gọi phương thức theo dll động.
  • nạp một assembly
  • CreateInstance ....

Khi gọi MethodInfo.Invoke() đi qua int, string như một tham số cho phương pháp của tôi hoạt động tốt => Không có trường hợp ngoại lệ được ném ra.

Nhưng nếu tôi thử và chuyển một trong các đối tượng lớp tùy chỉnh của riêng mình làm tham số, thì tôi nhận được một ngoại lệ ArgumentException và không phải là số ArgumentOutOfRangeException hoặc ArgumentNullException.

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

Tôi đang làm điều này trong ứng dụng web.

Tệp lớp chứa phương thức nằm trong một dự án khác. Ngoài ra đối tượng tùy chỉnh là một lớp riêng biệt trong cùng một tệp.

Không có thứ nào được gọi là static assembly trong mã của tôi. Tôi đang cố gắng để gọi một webmethod động. webmethod này có kiểu customObject như một tham số đầu vào. Vì vậy, khi tôi gọi các webmethod tôi đang tự động tạo ra lắp ráp proxy và tất cả. Từ cùng một assembly tôi đang cố gắng tạo ra một thể hiện của đối tượng cusotm để đưa các giá trị vào các thuộc tính của nó và sau đó truyền đối tượng này như một tham số và gọi phương thức này. tất cả mọi thứ là năng động và không có gì được tạo ra tĩnh .. :(

add tài liệu tham khảo không được sử dụng. Sau đây là một số mẫu mã tôi đã cố gắng để tạo ra nó

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

tôi không thể tìm thấy bất cứ điều gì static trong những gì tôi làm.

Any help is appreciated rất nhiều.

Kính trọng, Phani Kumar PV

+0

* Tại sao * bạn sẽ làm điều này? Tại sao không chỉ "thêm tham chiếu web" vào dự án? – Aaronaught

+0

i am developping một ứng dụng trong đó cho các địa chỉ WSDl tôi cần phải gọi một webmethod trong đó. như tôi có nghĩa vụ phải sử dụng webmethods khác nhau tôi không thể làm một tài liệu tham khảo web. –

Trả lời

2

Bạn đã xem những gì lớp proxy trông giống như được tạo ra? Bạn không cần cần proxy để gọi dịch vụ web. Chỉ cần tạo một lớp kế thừa từ SoapHttpClientProtocol và gọi Invoke (methodName, params).

Bạn đang thực hiện điều này SO phức tạp hơn nhiều so với nhu cầu của bạn. Thành thật.

EDIT Nếu bạn tạo một lớp như thế này:

public class SoapClient : SoapHttpClientProtocol 
{ 

    public SoapClient() 
    { 

    } 

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

} 

và gọi nó là như thế này:

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

Tôi nghĩ rằng bạn sẽ thấy rằng nó có kết quả chính xác giống như những gì bạn đang làm.

+0

Tôi đã đi qua mã được chia sẻ trong liên kết. Có vẻ như nó có thể được sử dụng khi thông tin abt không gian tên của webservice và các phương thức web có sẵn. Nhưng trong ứng dụng mà tôi hiện đang phát triển tôi sẽ nhận được các url wdsl động và nó được thay đổi frquently. trong kịch bản đó, cách tiếp cận được chỉ định trong url đã cho sẽ không giải quyết được sự cố của tôi. xin vui lòng cho tôi biết nếu tôi đã nhận nó theo hướng sai. –

+0

Cập nhật câu trả lời của tôi với một ví dụ về mã để giải thích những gì tôi đang nói đến. –

+0

Có, câu trả lời này là chính xác. Lý do duy nhất bạn cần để biên dịch mã dịch vụ web là nếu bạn cần kiểm tra kiểu thời gian biên dịch đối với một URL dịch vụ web đã biết. Bạn đã ở thời gian chạy khi bạn gọi điều này, vì vậy nó thực sự làm bạn không tốt. – ZeroBugBounce

2

Hãy để tôi cố gắng giải thích lý do có thể xảy ra nhất cho sự cố xảy ra trong cách tiếp cận của tôi.

Khi tôi gọi một phương thức trong assembly được gọi là "methodname" trong webservice Tôi đang cố chuyển các tham số cần thiết cho điều đó như args [] đến hàm "CallWebService" làm việc khi tôi cố gắng truyền một tham số bình thường như các kiểu nguyên thủy bao gồm chuỗi.

Nhưng đây là những gì tôi đã làm khi tôi cố gắng truyền một đối tượng tùy chỉnh làm tham số.

Ba điều được thực hiện trong điều này.

  1. tạo đối tượng thuộc loại đó bên ngoài chức năng CallWebService (sử dụng phản chiếu). khi tôi đã làm theo cách đó những gì xảy ra là một thể hiện của customobject tạo ra với một tên dll tạm thời trong nội bộ.
  2. khi tôi đặt tập hợp các thuộc tính của đối tượng và gửi nó cho hàm CallWebService làm đối tượng trong mảng args.
  3. Tôi mệt mỏi khi tạo một phiên bản của webservice bằng cách tạo dll động.

    đối tượng wsvcClass = results.CompiledAssembly.CreateInstance (foundType.ToString());

Khi tôi cuối cùng đã cố gắng để gọi phương pháp này với các ví dụ của việc lắp ráp động tạo tôi đã cố gắng để vượt qua customobject được tạo ở bước 1,2 qua bất động sản args.

tại thời điểm yêu cầu CLR cố gắng xem liệu customobject có được truyền dưới dạng đầu vào và phương thức đang được gọi đến từ cùng một DLL hay không.

rõ ràng không phải là cách thực hiện.

Vì vậy, đây là phương pháp mà nên được sử dụng để khắc phục những vấn đề tôi cần phải tạo ra các đối tượng lắp ráp tùy chỉnh với cùng một assembly mà tôi quen với tạo webservice dụ ..

tôi thực hiện phương pháp này hoàn toàn và nó hoạt động tốt đẹp

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

Đây là một chủ đề cũ, nhưng tôi chỉ có một vấn đề tương tự. Tôi nhìn vào đây, cái này xuất hiện, nhưng tôi thấy không có giải pháp hữu ích nào cả.

Lỗi OP là: Đối tượng thuộc loại 'customObject' không thể chuyển đổi thành loại 'customObject'.

Lỗi rất giống của tôi là: Đối tượng thuộc loại 'System.String' không thể chuyển đổi thành loại 'System.Windows.Forms.AccessibleRole'.

Dưới đây là cách tôi giải quyết vấn đề của tôi:

tôi thực hiện một Tìm và Thay thế (sử dụng CRTL + SHIFT + F để mang lại hộp thoại lên) tìm kiếm trong hiện tại Dự án cho thuật ngữ AccessibleRole.

Find and Replace dialog

Trong một trong những nhà thiết kế của Form là một nơi mà tôi đã gán một giá trị cho một biến AccessibleRoleString sử dụng ToString().

Tôi đã khắc phục sự cố này và sự cố của tôi đã biến mất.

Tôi hy vọng điều này sẽ giúp người khác.

1

điều này có thể xảy ra khi phiên bản dll bạn tham chiếu trong mã phản chiếu khác với phiên bản dll đó trong mã được biên dịch của bạn.

Các vấn đề liên quan