2015-06-04 10 views
7

मुझे प्रतिक्रिया शरीर की लंबाई को पुनः प्राप्त करने की आवश्यकता है।वर्तमान प्रतिक्रिया शरीर की लंबाई कैसे प्राप्त करें?

जब मैं https://github.com/aspnet/HttpAbstractions/wiki/Rolling-Notes-Response-Stream-Contract को देखो यह कहा जाता है कि:

Stream.Position {मिल} और Stream.Length {मिल} लिखा

संचयी बाइट्स यह ठीक है कि मैं क्या जरूरत है लौटने के लिए, लेकिन httpContext.Response.Body.LengthNotSupportedException उठाता है और कहता है "धारा तलाशने योग्य नहीं है।"

क्या मुझे प्रत्येक लेखन पर बाइट्स गिनने के लिए एक प्रतिनिधि स्ट्रीम का उपयोग करना चाहिए?

+2

उत्सुक, परिदृश्य क्या है जहां आपको इसकी आवश्यकता है? संभवतः इस जानकारी को प्राप्त करने का एक तरीका वर्तमान प्रतिक्रिया पर 'ऑनसेंडिंगर्स' कॉलबैक के लिए पंजीकरण करना है। उदाहरण: 'httpContext.Response.OnSendingHeaders (कॉलबैक: (राज्य) => {var लंबाई: (HttpContext) राज्य। सामग्री लम्बाई;}, राज्य: httpContext)'। –

+1

मुझे लगता है कि मुझे आपकी पोस्ट की आखिरी पंक्ति याद आई है ... यकीन है कि यह भी काम करेगा ... आप एक मिडलवेयर लिख सकते हैं जो पाइपलाइन में बहुत जल्दी पंजीकृत है और एक प्रतिनिधि स्ट्रीम के साथ प्रतिक्रिया शरीर को लपेटता है ... –

+1

@ किरण चल्ला मुझे खपत बैंडविड्थ की गिनती के लिए सामग्री की लंबाई की आवश्यकता होती है। जब कोटा पार हो जाता है, तो भविष्य के अनुरोध अवरुद्ध/धीमा हो जाएंगे। 'ऑनसेंडिंग हैडर' कॉलबैक काम नहीं करता है: 'ContentLength' प्रॉपर्टी' null' पर सेट है। यह 'OnResponseCompleted' कॉलबैक के साथ समान है। – ycrumeyrolle

उत्तर

2

मुझे लगता है कि आप सामग्री लम्बाई को मिडलवेयर के भीतर से प्राप्त करने का प्रयास कर रहे हैं?

यहां मिडलवेयर का एक उदाहरण है। इसे किसी भी प्रतिक्रिया उत्पन्न करने से पहले पाइपलाइन (startup.cs) में जोड़ा जाना चाहिए जैसे कि एमवीसी या उपयोगस्टैटफाइल।

public class ContentLengthMiddleware 
{ 
    RequestDelegate _next; 

    public ContentLengthMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     using (var buffer = new MemoryStream()) 
     { 
      var request = context.Request; 
      var response = context.Response; 

      var bodyStream = response.Body; 
      response.Body = buffer; 

      await _next(context); 
      Debug.WriteLine($"{request.Path} ({response.ContentType}) Content-Length: {response.ContentLength ?? buffer.Length}"); 
      buffer.Position = 0; 
      await buffer.CopyToAsync(bodyStream); 
     } 
    } 
} 

कारण है कि जब स्थिर फ़ाइलें (png, जे एस, आदि) प्रतिक्रिया शरीर खाली हो जाएगा लेकिन ContentLength सेट किया गया है यही वजह है कि मैं response.ContentLength ?? buffer.Length इस्तेमाल किया लौटने मेरी समझ से परे हैं के लिए।

(मोड के लिए नोट: दो प्रश्नों के डुप्लिकेट उत्तर के बारे में खेद है। दूसरा उत्तर गलत तरीके से पोस्ट किया गया था, बहुत सारे टैब खुल गए। मैंने इसे हटा दिया और यहां जवाब दोबारा पोस्ट किया)।

+1

इस समाधान की कमी 'मेमोरीस्ट्रीम' का उपयोग है। यह बेकार स्मृति का उपभोग करता है। – ycrumeyrolle

+1

मैंने एक 'स्ट्रीम' ओवरराइड किया है और इस तरह प्रत्येक लिखने पर गिनती है: सार्वजनिक ओवरराइड शून्य लिखें (बाइट [] बफर, इंट ऑफ़सेट, int गिनती) { _tracker.ContentLength + = count - ऑफसेट; _inner.Write (बफर, ऑफसेट, गिनती); } – ycrumeyrolle

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