2009-09-17 18 views
6

मेरे पास यह परिदृश्य है जहां सी # में एक webservice विधि मैं उपभोग कर रहा हूं, एक व्यावसायिक ऑब्जेक्ट देता है, जब निम्न कोड के साथ webservice विधि को कॉल करते हैं तो मुझे अपवाद मिलता है "ऑब्जेक्ट को कास्ट करने में असमर्थ प्रकार के "टाइप करने के लिए ContactInfo ContactInfo वेब संदर्भ के reference.cs कक्षा मेंMyObject टाइप करने के लिए MyObject टाइप करने में असमर्थ

कोड:

ContactInfo contactInfo = new ContactInfo(); 
Contact contact = new Contact(); 

contactInfo = contact.Load(this.ContactID.Value); 

किसी भी मदद की बहुत सराहना की जाएगी।

+0

क्या आपने हाल ही में अपना वेब संदर्भ अपडेट किया है? – womp

उत्तर

10

ऐसा इसलिए है क्योंकि ContactInfo ऑब्जेक्ट्स में से एक वेब सेवा प्रॉक्सी है, और यह एक अलग नामस्थान में है।

यह एएसएमएक्स-शैली वेब सेवाओं के साथ एक ज्ञात समस्या है। अतीत में मैंने स्वचालित उथले-प्रतिलिपि को इसके आसपास काम करने के लिए लागू किया है (here's how, हालांकि अगर मैं इसे फिर से कर रहा था तो शायद मैं AutoMapper पर देखता हूं)।

उदाहरण के लिए, यदि आप निम्नलिखित वर्ग के साथ एक विधानसभा है:

MyProject.ContactInfo 

और आप एक वेब विधि से यह का एक उदाहरण देते हैं:

public class DoSomethingService : System.Web.Services.WebService 
{ 
    public MyProject.ContactInfo GetContactInfo(int id) 
    { 
     // Code here... 
    } 
} 

फिर आप वेब संदर्भ जोड़ने जब अपने क्लाइंट प्रोजेक्ट में, आपको वास्तव में यह मिलता है:

MyClientProject.DoSomethingService.ContactInfo 

इसका मतलब है कि यदि आपके क्लाइंट एपी में तह, आप एक ContactInfo प्राप्त करने के लिए वेब सेवा को कॉल, तो आप इस स्थिति है:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // ERROR: You can't cast this: 
       MyProject.ContactInfo localContactInfo = contactInfo; 
      } 
     } 
    } 
} 

ऐसा नहीं है कि अंतिम पंक्ति है कि मैं अपने ShallowCopy क्लास का उपयोग पर है:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // We actually get a new object here, of the correct namespace 
       MyProject.ContactInfo localContactInfo = ShallowCopy.Copy<MyClientProject.DoSomethingService.ContactInfo, MyProject.ContactInfo>(contactInfo); 
      } 
     } 
    } 
} 

नोट
यह केवल काम करता है क्योंकि प्रॉक्सी क्लास और "असली" कक्षा में बिल्कुल वही गुण होते हैं (एक दृश्य स्टूडियो द्वारा दूसरे से उत्पन्न होता है)।

0

आप अपनी वेब सेवा प्रोजेक्ट के साथ-साथ उपभोक्ता परियोजना में कक्षा का संदर्भ कैसे दे रहे हैं? यदि आपने बस एक फ़ाइल लिंक का उपयोग किया है, तो यह त्रुटि के कारण की व्याख्या कर सकता है। जिस तरह से serialiasation .NET (वेब ​​सर्विसेज या अन्यथा मेरा मानना ​​है) के लिए काम करता है, किसी ऑब्जेक्ट के डेटा को लोड/डंप करने के लिए प्रतिबिंब का उपयोग करके होता है। अगर फाइलों को आसानी से जोड़ा जाता है, तो वे वास्तव में विभिन्न असेंबली में विभिन्न प्रकारों के लिए संकलित हो रहे हैं, जो समझाएंगे कि आपके पास एक ही नाम क्यों है लेकिन उनके बीच नहीं डाला जा सकता है। मैं एक 'कोर' लाइब्रेरी बनाने की अनुशंसा करता हूं जो वेब सेवा और उपभोक्ता परियोजना दोनों संदर्भों में है, और इसमें ContactInfo कक्षा है जिसका आप हर जगह उपयोग करते हैं।

0

यह कोई समस्या नहीं है - यह एक सुविधा है।

वे दो स्वतंत्र वर्ग हैं। दोनों की तुलना करें, और ध्यान दें कि प्रॉक्सी क्लास में मूल वर्ग से कोई भी रचनाकार, विधियां, अनुक्रमणिका या अन्य व्यवहार नहीं है। यह वही बात है जो तब होगा जब आपने जावा प्रोग्राम के साथ एएसएमएक्स सेवा का उपभोग किया था।

+1

@ डाउनवॉटर: क्या किसी को आपकी देखभाल करने की इच्छा है? तब आपको यह कहना होगा कि आप क्या सोचते हैं। "-2" ज्यादा नहीं कहता है। इसके बजाय, कहें कि तुम क्यों नीचे आ गए। –

+0

यह इस तरह से व्यवहार नहीं करना चाहिए। हमारे पास केवल एक उत्पन्न प्रॉक्सी का उपयोग करते समय यह समस्या है, CreateChannel विधि का उपयोग करते समय नहीं, लेकिन हमारी समस्या इस पोस्ट के समान है। मुझे नहीं लगता कि यह एक विशेषता होने के लिए है। – schmoopy

+0

@ स्चमोपी: वह एएसएमएक्स वेब सेवाओं का उपयोग कर रहा है, डब्ल्यूसीएफ नहीं। कोई 'CreateChannel' विधि नहीं है। –

1

जैसा कि कई अन्य उत्तरों ने सुझाव दिया है, ऐसा इसलिए है क्योंकि .NET उन्हें दो अलग-अलग वर्गों के रूप में देखता है।मैं व्यक्तिगत रूप से AutoMapper जैसे कुछ का उपयोग करने की सलाह दूंगा। मैं इसका उपयोग कर रहा हूं, और यह बहुत बढ़िया लगता है। आप कोड की 1-2 लाइनों में अपनी ऑब्जेक्ट्स कॉपी कर सकते हैं।

Mapper.CreateMap<SourceClass, DestinationClass>(); 
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance); 
0

ऐसा लगता है कि आपके दोनों सिरों पर दो अलग-अलग कक्षाएं हैं। आपके एप्लिकेशन में ContactInfo क्लास है और आपके webservice में ContactInfo क्लास भी है। दोनों दो पूरी तरह से अलग वर्ग हैं। एक तरफ आपकी तरफ से WebService कक्षा का उपयोग करना है। यदि आप अपनी वेब सेवा के अंदर ContactInfo का उपयोग कर रहे हैं तो इसे क्रमबद्ध किया जाएगा और उपयोग के लिए ग्राहक पक्ष पर उपलब्ध होगा।

1

वास्तव में यह एक बग नहीं है। यह आपकी खुद की परियोजना के संस्करण में बदलाव के साथ एक समस्या है! क्योंकि आपका अंतिम रन संकलन पर मूल आयातित संदर्भों का उपयोग नहीं करता है!

उदाहरण के लिए, मैं चैट सर्वर, क्लाइंट बना रहा था। मैंने क्लाइंट प्रोजेक्ट पर डेटा संचारित करने के लिए एक पैकेट संरचना का उपयोग किया। फिर सर्वर प्रोजेक्ट के लिए एक ही संदर्भ आयात किया।

Packet packet = (Packet)binaryFormatter.Deserialize(stream); कास्टिंग करते समय मुझे एक ही त्रुटि मिली। क्योंकि सर्वर प्रोजेक्ट पर वास्तविक चल रहा संदर्भ अब क्लाइंट प्रोजेक्ट पर संदर्भ नहीं है! क्योंकि मैंने कई बार क्लाइंट प्रोजेक्ट का पुनर्निर्माण किया है!

<new object>=(<new object>) <old object> कास्टिंग में हमेशा नई वस्तु को पुरानी वस्तु के रूप में एक नया या समान संस्करण होना चाहिए!

तो मैंने क्या किया था मैंने पैकेट वर्ग के लिए डीएलएल बनाने के लिए एक अलग परियोजना बनाई और दोनों परियोजनाओं में डीएलएल फ़ाइल आयात की।

यदि मैंने पैकेट कक्षा में कोई बदलाव किया है, तो मुझे क्लाइंट और सर्वर दोनों के संदर्भ को फिर से आयात करना होगा।

तब कास्टिंग उपरोक्त अपवाद नहीं देगा!

0

वेब संदर्भ जोड़े जाने पर आप विजुअल स्टूडियो द्वारा जेनरेट की गई अपनी References.cs फ़ाइल को भी संशोधित कर सकते हैं। यदि आप प्रॉक्सी जेनरेटेड क्लासेस को हटाते हैं और अपनी व्यक्तिगत कक्षाओं में एक संदर्भ (कथन का उपयोग करके) जोड़ते हैं, तो आप उथले प्रतिलिपि/प्रतिबिंब या भारी मैपिंग के बिना सीधे उनका उपयोग कर पाएंगे। (लेकिन यदि आप प्रॉक्सी परत को पुन: उत्पन्न करते हैं तो आपको अपना संशोधन दोबारा लागू करना होगा)।

मैंने प्रॉक्सी ऑब्जेक्ट को क्रमबद्ध करने और उन्हें अपने डीटीओ कक्षाओं में वापस करने की कोशिश की लेकिन यह काफी भारी संसाधन था इसलिए मैंने संदर्भ सीएस जेनरेटेड परत को संशोधित करना समाप्त कर दिया।

उम्मीद है कि यह अन्य लोगों को यहां आने में मदद करेगा :)

कृपया।

संबंधित मुद्दे