2015-07-08 7 views
12

सारांश: बेस क्लास को व्युत्पन्न कक्षा में कास्ट करने के बाद वापस लौटाया जाता है। हालांकि, कास्टिंग से पहले बेस क्लास ऑब्जेक्ट ठीक है।प्रोफाइलकॉम - रन-टाइम में कास्टिंग

विवरण: मैं पुराने एएसपीनेट वेबफॉर्म एप्लिकेशन को फिर से लिख रहा हूं ताकि एमवीसी दृष्टिकोण का उपयोग करके इसे विस्तारित किया जा सके। प्रोसेस के एक हिस्से के रूप में, मैं वेब साइट प्रोजेक्ट को वेब एप्लिकेशन प्रोजेक्ट में परिवर्तित कर रहा हूं। मामले में, ProfileCommon कक्षा स्वचालित रूप से जेनरेट नहीं होती है। इसलिए, मैंने पुराने प्रोजेक्ट से स्वत: जेनरेटेड क्लास परिभाषा की प्रतिलिपि बनाई है और इसे utils\ProfileCommon.cs के रूप में रखा है। फ़ाइल की सामग्री (एक भी संपत्ति है कि यह भी चेक समकक्ष से नाम दिया गया था करने के लिए सरल) है:

using System; 
using System.Web; 
using System.Web.Profile; 

namespace proj_app.utils 
{ 
    public class ProfileCommon : System.Web.Profile.ProfileBase 
    { 
     public virtual string Name { 
      get { return ((string)(this.GetPropertyValue("Name"))); } 
      set { this.SetPropertyValue("Name", value); } 
     } 

     public static ProfileCommon GetProfile(string username) 
     { 
      return ((ProfileCommon)(ProfileBase.Create(username))); 
     } 
    } 
} 

अंतर भी है कि मैं GetProfile() विधि से virtual हटा दिया है और यह static बना दिया है। (ProfileBase में GetProfile() विधि नहीं है, इसलिए, यह ठीक होना चाहिए, है ना?)

कोड ठीक संकलित करता है। हालांकि, मैं ब्राउज़र में निम्न अवलोकन कर सकते हैं (मोटे तौर पर अनुवादित, लाइन नंबर उदाहरण के साथ मेल नहीं खाते):

The object of the ProfileCommon type cannot be casted to proj_app.utils.ProfileCommon. 
Description: ... unhandled exception during the web request... 

Details about the exception: The object of the ProfileCommon type cannot be casted to proj_app.utils.ProfileCommon. 

Zdrojová chyba: 

Line 36:   public static ProfileCommon GetProfile(string username) 
Line 37:   { 
Line 38:    return ((ProfileCommon)(ProfileBase.Create(username))); 
Line 39:   } 
Line 40:  } 


Source file: d:\__RizeniProjektu\aplikace\proj_app\utils\ProfileCommon.cs Line: 38 

Stack trace: 
[InvalidCastException: Objekt typu ProfileCommon nelze přetypovat na typ proj_app.utils.ProfileCommon.] 
    proj_app.utils.ProfileCommon.GetProfile(String username) in d:\__RizeniProjektu\aplikace\proj_app\utils\ProfileCommon.cs:38 
    Users_seznam.Page_Load(Object sender, EventArgs e) in d:\__RizeniProjektu\aplikace\proj_app\Users\seznam.aspx.cs:29 
    System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51 
    System.Web.UI.Control.OnLoad(EventArgs e) +92 
    System.Web.UI.Control.LoadRecursive() +54 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772 

जब डीबगिंग, ProfileBase.Create(username) वस्तु है, जहां Name संपत्ति के लिए सही मान है रिटर्न अपेक्षित मूल्य (डीबगर जानता है कि मूल्य कैसे प्राप्त करें)। हालांकि, कास्ट के बाद, परिणामी ऑब्जेक्ट संदर्भ null है। (मुझे यह स्वीकार करना है कि मैं सी # में बहुत अच्छा नहीं हूं; मैं सी ++ से आया था।) मैंने ProfileBase p = ProfileBase.Create(username); (ऑब्जेक्ट शून्य नहीं है) प्राप्त करने के लिए कमांड को विभाजित करने का प्रयास किया, और केवल इसे प्रोफ़ाइल कॉमॉन q = p as ProfileCommon; (q) पर डालने के लिए शून्य है)।

अद्यतन: अजीब। मैंने अपनी कक्षा का नाम बदलकर ProfileComm कर दिया है, स्क्रैच से संकलित परियोजना को साफ़ किया है। निर्देशिका में ProfileCommon स्ट्रिंग नहीं है (न ही सूत्रों में, बाइनरी फ़ाइलों में नहीं, * .suo, * .dll, * .pdb, किसी अन्य फ़ाइल में नहीं)। यहां तक ​​कि फ़ाइल नाम का नाम बदलकर ProfileComm.cs कर दिया गया था, जो * .csproj में ProfileCommon नहीं है।

public class ProfileComm : System.Web.Profile.ProfileBase 
{ 
    ... 
    public static ProfileComm GetProfile(string username) 
    { 
     object p = ProfileBase.Create(username); 
     Type t = p.GetType(); 
     string s = t.Name; 

     return ((ProfileComm)(p)); 
    } 
} 

अब ब्राउज़र को पढ़ने में अपवाद का विवरण (किसी अन्य भाषा से अनुवाद): GetProfile() के स्रोत में बदल गया था System.InvalidCastException: Object of the type ProfileCommon cannot be casted to the type proj_app.utils.ProfileComm.

जब डीबगिंग, डिबगर पता चलता है कि p के प्रकार ProfileCommon है:

What the debugger shows about the type

मैं कहाँ प्रकार का नाम ProfileCommon में फिसल से पता नहीं है यह असली हो सकता है। टेड .NET ढांचे का एक संस्करण करते हैं? मुझे क्या जांचना चाहिए? ProfileCommon कक्षा अभी भी गतिशील रूप से उत्पन्न हो सकती है?

+2

'ProfileCommon प्रकार की वस्तु proj_app.utils.ProfileCommon' लिए casted नहीं किया जा सकता, आप अपने खुद वस्तु' ProfileCommon' नामित किए हैं? क्या आप वाकई सही पर कास्टिंग कर रहे हैं? – DLeh

+0

@DLeh: मैंने अपनी कक्षा का नाम बदलने के लिए इसका नाम बदल दिया है। कृपया, प्रश्न के अंत में अद्यतन देखें। – pepr

उत्तर

2

ASP.NET स्वचालित रूप से ProfileCommon वर्ग है कि आवेदन शुरू पर ProfileBase से विरासत पैदा करता है। यदि आप अपने प्रोफाइल कार्यान्वयन का उपयोग करना चाहते हैं तो आपको इसे web.config में स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है। कुछ की तरह:

<profile inherits="proj_app.utils.ProfileCommon"> 
.... 

इस तरह ProfileBase.Create आपके द्वारा निर्दिष्ट प्रकार के उदाहरण वापस आ जाएगी बजाय स्वचालित रूप से एक उत्पन्न।

MSDN for more details

+0

@pepr, आपकी कक्षा का नाम बदलने की कोई आवश्यकता नहीं है। बस अपने web.config के जवाब में दिखाए गए कॉन्फ़िगरेशन को लागू करें। अन्यथा एएसपी.नेट नहीं जानता कि किस प्रोफाइल क्लास को बनाने और डिफॉल्ट रूप से स्वचालित रूप से जेनरेट किया गया है। –

+0

धन्यवाद Vitalij! मैंने पर्याप्त ध्यान सलाह नहीं दी। Спасибо и всего хорошего! – pepr

+0

सुधार ... "पहले आपकी सलाह के लिए" – pepr

6

ऐसा प्रतीत होता है कि आपके पास दो प्रकार के ProfileCommon हैं, आपको इसकी पुष्टि करने के लिए अपना स्रोत देखना चाहिए। आप अधिक विशिष्ट हो सकते हैं और ProfileCommon की बजाय proj_app.utils.ProfileCommon पर वापस आ सकते हैं।

डिबगिंग शायद कोशिश करते हैं और देखते हैं कि क्या संकलक वस्तु सोचता है कि वास्तव में यह है के लिए इसके अलावा

, इस पोस्ट देखें: Could not resolve type: Issue while I am casting a custom class in c#


यह आप एक ASP.NET वर्ग के साथ परस्पर विरोधी रहे हैं लगता है, मैं या तो बना सकते हैं एक नई कक्षा पूरी तरह से या एएसपी.नेट प्रोफाइल कॉमन क्लास की एक सुपर क्लास बनाएं।

एएसपी.NET उपयोगकर्ता प्रोफ़ाइल के लिए उपयोग की जाने वाली कक्षा बनाने के लिए प्रोफाइलबेस क्लास का उपयोग करता है। जब उपयोगकर्ता प्रोफ़ाइल सक्षम करने वाला कोई एप्लिकेशन प्रारंभ होता है, तो ASP.NET प्रोफाइलकॉम प्रकार की एक नई श्रेणी बनाता है, जो प्रोफाइलबेस क्लास से प्राप्त होता है। प्रोफ़ाइल कॉन्फ़िगरेशन अनुभाग में परिभाषित प्रत्येक प्रॉपर्टी के लिए मजबूत टाइप किए गए एक्सेसर्स को प्रोफ़ाइल कॉमॉन क्लास में जोड़ा जाता है। प्रोफाइलकॉमन क्लास के दृढ़ता से टाइप किए गए एक्सेसर्स क्रमशः प्रोफाइल प्रॉपर्टी वैल्यू को पुनर्प्राप्त करने और सेट करने के लिए प्रोफाइलबेस बेस क्लास के GetPropertyValue और SetPropertyValue विधियों को कॉल करते हैं। प्रोफाइल कॉमन क्लास का एक उदाहरण ASP.NET अनुप्रयोग के लिए प्रोफ़ाइल प्रॉपर्टी के मान के रूप में सेट किया गया है।

https://msdn.microsoft.com/en-us/library/system.web.profile.profilebase(v=vs.110).aspx

+0

अच्छा बिंदु। यह पता लगाने के लिए, मैंने कक्षा का नाम बदल दिया है। 'ProfileCommon' स्रोतों में नहीं है, न ही बाइनरी में। फिर भी, यह किसी भी तरह से 'ProfileBase.Create() 'द्वारा वापस किया जाता है। कृपया, प्रश्न का अद्यतन भाग देखें। – pepr

+0

मूर्खतापूर्ण लगता है लेकिन एक पूर्ण साफ और पुनर्निर्माण करने का प्रयास करें, आपके पास कहीं अस्थायी फ़ाइल हो सकती है। अगर यह काम नहीं करता है तो मैं कुछ बेहतर सुझावों को आजमाकर सोचूंगा। इसके अलावा आप डीबग> मॉड्यूल का उपयोग कर सकते हैं यह देखने के लिए कि रन टाइम –

+1

पर कौन से प्रतीकों को लोड किया गया है, मैंने जितना संभव हो उतना साफ करने की कोशिश की। मैं असली उदाहरण प्रकाशित करने के लिए अब नंगे हड्डियों के लिए परियोजना को अलग कर रहा हूं। – pepr

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