2016-05-23 10 views
12

मैं इसASP.NET कोर Middleware के लिए प्रतिक्रिया हेडर जोड़े

public class ProcessingTimeMiddleware 
{ 
    private readonly RequestDelegate _next; 

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

    public async Task Invoke(HttpContext context) 
    { 
     var watch = new Stopwatch(); 
     watch.Start(); 

     await _next(context); 

     context.Response.Headers.Add("X-Processing-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() }); 
    } 
} 

की तरह मेरे ASP.NET कोर WebAPI करने के लिए एक प्रसंस्करण समय मिडलवेयर जोड़ना चाहते हैं लेकिन ऐसा करने से एक अपवाद

System.InvalidOperationException: Headers are readonly, reponse has already started. 

कह फेंकता मैं प्रतिक्रिया में हेडर कैसे जोड़ सकता हूं?

उत्तर

17

कोई बात नहीं, कोड यहाँ

public async Task Invoke(HttpContext context) 
    { 
     var watch = new Stopwatch(); 
     watch.Start(); 

     //To add Headers AFTER everything you need to do this 
     context.Response.OnStarting(state => { 
      var httpContext = (HttpContext)state; 
      httpContext.Response.Headers.Add("X-Response-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() }); 
      return Task.FromResult(0); 
     }, context); 

     await _next(context); 
    } 
+0

पर विनिर्देश पा सकते हैं आप

Server-Timing: processingTime;dur=12ms 

उपयोग करने के लिए अनुमति चाहिए' पिछले बयान ('context.Response.Headers.Add के बाद होना चाहिए ')। अधिक अर्थात् सही है। –

+0

क्या कोई .NET 4 समतुल्य है या इसके लिए आसपास काम करता है? अभी भी सर्वर 2003 के कुछ ग्राहक हैं :( – apc

+0

क्या कोई कारण है कि आपने ऑनस्टार्टिंग पर राज्य अधिभार का उपयोग किया है? –

3

अपने उदाहरण हेडर में जब निष्पादन context.Response.Headers.Add (...) बयान तक पहुँच जाता है पहले ही भेज दिया है।

आप कोशिश कर सकते हैं:

public async Task Invoke(HttpContext context) 
{ 
    var watch = new Stopwatch(); 
    context.Response.OnSendingHeaders(x => 
    { 
     watch.Stop(); 
     context.Response.Headers.Add("X-Processing-Time-Milliseconds", new[] { watch.ElapsedMilliseconds.ToString() }); 
    }, null); 

    watch.Start(); 
    await _next(context); 
    watch.Stop(); 
} 
+0

किस पैकेज से ऑनेंडिंग हैडर? –

4

OnStarting विधि की एक अधिभार का उपयोग करना:

public async Task Invoke(HttpContext context) 
{ 
    var watch = new Stopwatch(); 

    context.Response.OnStarting(() => 
    { 
     watch.Stop(); 

     context 
       .Response 
       .Headers 
       .Add("X-Processing-Time-Milliseconds", 
         new[] { watch.ElapsedMilliseconds.ToString() }); 

     return Task.CompletedTask; 
    }); 

    watch.Start(); 

    await _next(context); 
} 
0

वैकल्पिक रूप से आप भी एक मिडलवेयर सीधे Startup.cs कॉन्फ़िगर विधि में जोड़ सकते हैं।

0

एक संबंधित नोट पर, इस तरह के रूप में अपने सवाल का जवाब देने के बिना, वहाँ अब एक Server-Timing विनिर्देश, अवधि प्रदान करने के लिए एक मानक हेडर, अन्य मैट्रिक्स के बीच है। यह आप मुझे यह भी है कि इंतजार है `_next (संदर्भ) जोड़ना होगा https://www.w3.org/TR/server-timing/