2013-07-25 8 views
6

Mam projekt MVC. Ten projekt MVC zawiera jeden kontroler, który musi przesyłać treści strumieniowo do klienta. Po rozpoczęciu przesyłania strumieniowego nie ma możliwości określenia długości zawartości (obliczana jest on-the-fly). Więc otwieram HttpContext.Current.Response.OutputStream i rozpocząć pisanie i Flushing okresowo (ja już wyłączona buforowane wyjście i dołączone odpowiednie nagłówki HTTP):Kontroler MVC powracający Kodowanie treści kodowanych

while (some condition){ 

    HttpContext.Current.Response.OutputStream.Write(buffer, 0, buffer.Length); 
    HttpContext.Current.Response.Flush(); 
} 

Gdybym wtedy wymusić zamknięcie strumienia:

HttpContext.Current.Response.Close(); 

nie ma właściwie końca zawartości pakietowego (nie wstawiaj 0 długość kawałek na końcu, aby wskazać EOF do klienta).

Jeśli zamiast zamknięcia strumienia wyjściowego bardziej bezpiecznie:

HttpContext.Current.Response.End(); 

lub

HttpContext.Current.ApplicationInstance.CompleteRequest(); 

właściwy sposób zamyka się (fragment zerowej długości dołączony do końca) strumienia, ale pojawia się wyjątek generowane przez aplikacja, wskazując, że nie może wstawić nagłówków HTTP do strumienia wyjściowego, ponieważ strumień został już napisany!

W obu przypadkach kontroler powraca do wartości null (lub EmptyActionResult).

Zakładam, że wyjątek jest spowodowany, ponieważ stos MVC wymaga, aby wszystkie ActionResult ustawiały nagłówki HTTP po zakończeniu działania kontrolera. Jeśli tak jest, jak można wdrożyć strumień Chunked w MVC?

Z góry dziękuję!

EDIT: Dokładna wyjątkiem wyrzucane jest:

Uncaught Exception: System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent. 
    at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result) 
    at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Odpowiedz

2

mogę znaleźć rozwiązanie.

HTTP 1.1 Norma określa, które zostały podzielone na porcje kodowania muszą być zamknięte z 0 długości fragmentu, tylko gdy tryb Żądanie to keep-alive

W trybie podtrzymania, połączenie pomiędzy klient/serwer jest zachowywane dla wielokrotności Żądanie/odpowiedzi. Kodowanie chunkowane musi zostać zakończone porcją o zerowej długości w tym kontekście, ponieważ nie ma innego sposobu, aby klient wiedział, kiedy kończy się poprzednia odpowiedź.

Jeśli wybierzesz "Połączenie: zamknij" jako nagłówek, w przeciwieństwie do "Połączenie: keep-alive", to połączenie nie zostanie zachowane między żądaniami, klient może użyć zamknięcia połączenia jako wskazania zakończenia odpowiedzi, i nie wymaga porcji o długości 0 oznaczającej EOF.

właśnie postanowił zamknąć ręcznie przy użyciu HttpResponse:

HttpContext.Current.Response.Close(); 

ile uprzednio określone w kodzie powiedzieć klientowi, że połączenie będzie zamknąć na EOF. Rozwiązało to problem, w którym klient nie otrzymał fragmentu o długości 0, ponieważ teraz klient tego nie wymaga.

Powiązane problemy