2015-11-24 13 views
6

Im Versuch, ein Web-API-Projekt (klassisches web.config-Projekt) zu migrieren, verwenden Sie PushStreamContent zur neuesten asp.net 5-Webanwendung (project.json).PushStreamContent in asp.net 5/mvc 6 funktioniert nicht

Mein Problem ist, dass ich PushStreamContent nicht funktionieren kann.

Wenn ich diese api Controller - ein Ergebnis wird in einem json-Format und nicht als Stream am Ende:

[Route("api/[controller]")] 
public class EventsController : Controller 
{ 
    private static readonly ConcurrentQueue<StreamWriter> s_streamWriter = new ConcurrentQueue<StreamWriter>(); 

    [HttpGet] 
    public HttpResponseMessage Get(HttpRequestMessage request) 
    { 
     HttpResponseMessage response = request.CreateResponse(); 
     response.Content = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(WriteToStream), "text/event-stream"); 
     return response; 
    } 

    private void WriteToStream(Stream outputStream, HttpContent headers, TransportContext context) 
    { 
     var streamWriter = new StreamWriter(outputStream) {AutoFlush = true}; 
     s_streamWriter.Enqueue(streamWriter); 
    } 
} 

Wenn ich die Controller-Aktion ändern, um eine Aufgabe zurückzukehren und wickeln PushStreamContent in einer Klasse MyPushStreamResult - So:

[HttpGet] 
public async Task<IActionResult> Get(HttpRequestMessage request) 
{ 
    var stream = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(WriteToStream), "text/event-stream"); 
    return new MyPushStreamResult(stream, "text/event-stream"); 
} 

public class MyPushStreamResult : ActionResult 
{ 
    public string ContentType { get; private set; } 
    public PushStreamContent Stream { get; private set; } 
    public MyPushStreamResult(PushStreamContent stream, string contentType) 
    { 
     Stream = stream; 
     ContentType = contentType; 
    } 
    public override async Task ExecuteResultAsync(ActionContext context) 
    { 
     var response = context.HttpContext.Response; 
     response.ContentType = ContentType; 
     await Stream.CopyToAsync(response.Body); 
    } 
} 

eine Anfrage an meine Controller-Aktion nun einen Strom zurückkehrt, aber der Strom Spülung nicht, bevor es auf server schließen oder eine Menge von Daten enthält. Wenn ich Daten in den PushStreamContent-Ausgabestream pushe, spüe ich nach jedem Text-Schreibvorgang, aber ich denke, der Flush ist nicht auf dem response.Body-Stream.

Was vermisse ich? Kann keine Beispiele mit asp.net 5 Struktur finden.

+1

die 'IHttpBufferingFeature' Funktion kann helfen, denke ich, haben Sie versucht, die Pufferung zu deaktivieren? –

+0

es sieht aus wie die 'IHttpBufferingFeature' in Kestrel [docs] (http://docs.asp.net/de/latest/fundamentals/servers.html#supported-features-by-server) –

+0

In dem ersten Beispiel nicht unterstützt wird Du schreibst niemals in den Stream. – usr

Antwort

4

HttpResponseMessage wird nicht speziell in ASP.NET 5 behandelt, es sei denn, Sie verwenden Microsoft.AspNet.Mvc.WebApiCompatShim Paket. Dieses Paket ist nicht empfohlen, wenn Sie die ASP.NET 5-Features verwenden können, um ähnliche Sachen zu tun und wurde erstellt, um Abwärtskompatibilität zu unterstützen.

Also da HttpResponseMessage nicht besondere betrachtet wird, seine als json durch die JsonOutuptFormatter gemacht zu werden wie jedes andere .NET-Objekt

Statt PushStreamContent, Sie derzeit Zugriff auf Antwortstream haben direkt über HttpContext.Response.Body Eigenschaft, so dass Sie kann einfach direkt in den Stream schreiben.

Aktualisiert:
PushStreamContent in Web-API Sie in die Antwortstream direkt schreiben erlaubt. Dieser Typ wurde erstellt (vom Web-API-Team und ist nicht Teil der Bibliothek System.Net.Http, in der alle anderen Inhaltstypen enthalten sind), sodass man direkt in den Stream schreiben könnte, beispielsweise von einem Controller oder Filter usw. Die Alternative zu PushStreamContent war StreamContent, die Ihnen nur erlaubt, ein Stream-Objekt zur Verfügung zu stellen, und dann die Host-Schichten die Daten aus dem Quelldatenstrom kopieren (wie Daten ziehen). Auch PushStreamContent ist nichts besonderes. Man könnte seinen eigenen Typ schreiben, der sich von HttpContent ableitet.

Zusammenfassend, PushStreamContent erlaubt Schreiben in den Antwort-Stream direkt, wo wie in ASP.NET 5 haben wir direkten Zugriff auf den Stream und so können Sie darauf schreiben.

Aktualisiert:
Ganz am Grundform (rechts, könnten Sie konvertieren für Testbarkeit Action) sollte die folgende arbeiten.

[HttpGet] 
public Task Get() 
{ 
    HttpContext.Response.ContentType = "text/event-stream"; 
    var sourceStream = // get the source stream 
    return sourceStream.CopyToAsync(HttpContext.Response.Body); 
} 
+0

'PushStreamContent' wird verwendet, um mehrmals in den Stream zu schreiben - wie ein Chat, bei dem der Server neue Daten an den Client senden kann. Ich kann nicht sehen, wie ich mehrfach in den 'HttpContext.Response.Body' schreiben kann. Kannst du ein Beispiel geben? –

+0

Meine Post mit mehr Details aktualisiert. –

+0

Ich habe dein Update gelesen und verschiedene Dinge ausprobiert. Aber ich kann es nicht zum Laufen bringen, und finde kein Codebeispiel, das in asp.net geschrieben wird, 5 gibt dort einen Strom an den Klienten zurück, den der Server einzelne Stücke von Daten schreiben kann. Können Sie ein Beispielprojekt/Code-Snippet erstellen? –

Verwandte Themen