2010-03-04 18 views
14

लंबी कहानी संक्षेप में, मैं ASP.NET अनुप्रयोग मैं डिबग करने के लिए और कुछ बिंदु पर कोशिश कर रहा हूँ, बहुत विशेष परिस्थितियों में, आवेदन यह कहते हुए एक Response.Redirect() पर अपवाद फेंक देंगे:मैं कैसे बता सकता हूं कि HTTP हेडर को एएसपी.NET एप्लिकेशन में कब भेजा गया है?

"Cannot redirect after HTTP headers have been sent." 

कौन सा मैं और अधिक या कम मिलता है, सिवाय इसके कि मैं नहीं समझ सकता जहां शीर्षलेख भेजे गए थे।

क्या एएसपी.NET एप्लिकेशन में कुछ देखने के लिए कुछ है जो इंगित करेगा कि HTTP शीर्षलेख भेजे गए हैं?

बोनस डिफिक्टी: एएसपी.नेट ऐप अभी भी .NET 1.1 में है। अपग्रेड के पीछे देरी के बारे में परिस्थितियां वास्तव में एक गंभीर विषय हैं।

+0

रिस्पांस बफरिंग ('Response.Buffer' - आप पर यह चाहते हैं) और उत्तर फ्लशिंग (' Response.Flush() '- आप डॉन यह नहीं करना चाहते हैं) दो स्पष्ट उम्मीदवार हैं। – bzlm

उत्तर

15

HttpApplication में एक ईवेंट PreSendRequestHeaders है जिसे केवल हेडर writtne कहा जाता है। इसकी सदस्यता लें और इसे लॉग करें या ब्रेकपॉइंट जोड़ें।

इसके अलावा, HttpResponse एक आंतरिक संपत्ति HeadersWritten (.NET 1.1 में _headersWritten क्षेत्र) कहा जाता है। चूंकि यह आंतरिक है, आप इसे सीधे एक्सेस नहीं कर सकते हैं, लेकिन आप प्रतिबिंब के माध्यम से कर सकते हैं। यदि यह केवल आंतरिक डिबगिंग के लिए है (यानी, उत्पादन कोड नहीं), तो प्रतिबिंब का उपयोग करना ठीक है।

सभी पेज लाइफसील्स घटनाओं के पहले/बाद में इस विधि को जांचें। एक बार जब आप जानते हैं कि कौन सी घटना शीर्षलेख लिख रही है, तो HeadersWritten जांचें कि वे कहां लिखे जा रहे हैं, यह जांचने के लिए। इस संपत्ति के चेक की प्रगतिशील संकुचन के माध्यम से, आपको यह मिल जाएगा।

नई जानकारी

HeadersWritten संपत्ति शमूएल की जबाब बस मुझे (+1) के लिए इस समस्या का समाधान नेट 4.5.2

+0

यह वास्तव में अच्छा लगता है ... सिवाय इसके कि मैं ऐप का उल्लेख करना भूल गया हूं .NET 1.1 में है और यह एक .NET 2.0+ समाधान दिखता है। –

+0

@Schnapple, .NET 1.1 वास्तव में पुराना है। जब भी आप किसी पुराने संस्करण के बारे में बात कर रहे हों तो आपको हमेशा संस्करण निर्दिष्ट करना चाहिए। .NET 1.1 में केवल एक निजी क्षेत्र था, '_headersWritten', जिसे आप प्रतिबिंब के माध्यम से पढ़ सकते हैं। –

+2

'हेडरस्क्रिप्टेड' संपत्ति सार्वजनिक से शुरू हो रही है। नेट 4.5.2 –

5

से सार्वजनिक प्रारंभिक है। मैं एक टिप्पणी में एक कोड नमूना नहीं चिपका सकते हैं, लेकिन दूसरों की मदद करने के हित में, यहाँ है कि कैसे मैं घटना वह मेरा IHTTPHandler करने के लिए एक HeadersWritten संपत्ति जोड़ने के लिए सुझाव का प्रयोग किया:

protected bool HeadersWritten { get; private set; } 

void ApplicationInstance_BeginRequest(object sender, EventArgs e) 
{ 
    HeadersWritten = false; 
} 

void ApplicationInstance_PreSendRequestHeaders(object sender, EventArgs e) 
{ 
    HeadersWritten = true; 
} 

public void ProcessRequest(HttpContextBase context) 
{ 
    context.ApplicationInstance.PreSendRequestHeaders += new EventHandler(ApplicationInstance_PreSendRequestHeaders); 
    do_some_stuff(); 
} 

मेरी कोड में टूट जाएगा अगर बहुत देर हो चुकी हेडर के साथ मैं गड़बड़, मैं बस HeadersWritten संपत्ति पहले की जाँच करें:

if (!HeadersWritten) 
{ 
    Context.Response.StatusDescription = get_custom_description(Context.Response.StatusCode); 
} 
+4

ध्यान रखें कि 'HttpAplication' ऑब्जेक्ट का प्रत्येक उदाहरण एकाधिक (लेकिन हमेशा अनुक्रमिक) अनुरोधों को पूरा कर सकता है, इसलिए आपको * BeginRequest ईवेंट के दौरान ध्वज को रीसेट करना होगा। यह एक 'HTTPHandler' पर भी लागू होता है जिसमें 'ISReusable' प्रॉपर्टी सत्य होती है। [एचटीपीएप्लिकेशंस] देखें (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx) और [IsResuable] (http://msdn.microsoft.com/en-us/library/ system.web.ihttphandler.isreusable।एएसपीएक्स) विवरण के लिए एमएसडीएन में। –

+0

इसके लिए धन्यवाद, यूरो। स्पष्ट होने के लिए, मैं इस संपत्ति और संबंधित कोड और घटनाओं को अपनी कक्षा में जोड़ रहा हूं जो IHttpHandler से प्राप्त होता है। यह मेरी समझ थी कि इस वर्ग के लिए इस वर्ग के लिए एकल उपयोग होना चाहिए, और इस प्रकार अन्य अनुरोधों से हस्तक्षेप से पूरी तरह से सुरक्षित होना चाहिए। अगर यह समझ सही नहीं है, तो कृपया मुझे बताएं! –

+0

IHttpHandler इंटरफ़ेस के सदस्यों में से एक है 'IsReusable' नामक एक संपत्ति है (मैंने इसे अपनी मूल टिप्पणी में गलत लिखा है)। यदि आपका कार्यान्वयन अनिवार्य रूप से 'सार्वजनिक बूल IsReusable {प्राप्त {वापसी झूठी है; }} ', तो आप ठीक हैं: एएसपी.नेट प्रत्येक अनुरोध के लिए ऑब्जेक्ट को चालू करेगा और फिर इसे फेंक देगा। यदि आप 'सत्य' वापस करते हैं, तो ASP.NET आपके अनुरोधों को एकाधिक अनुरोधों के लिए पुन: उपयोग करेगा और आप थ्रेड-सुरक्षित नहीं हैं। –

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

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