public override async Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) { var json = _formatter.GetContext(_request, value); var writer = new StreamWriter(stream); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); content.Headers.TryAddWithoutValidation("x-template", _view); await writer.WriteAsync(json); await writer.FlushAsync(); return; }
public override async Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) { // await Console.Out.WriteLineAsync("HB Started: " + Request.RequestUri.PathAndQuery); var json = _formatter.GetContext(_request, value); string r = _template.Render(_view, json); StringBuilder html; var donuts = new List <string>(); if (_request.Properties.ContainsKey("donut") && (bool)_request.Properties["donut"] == true) { // detect any master or sections and fill them html = new StringBuilder(r); } else { html = FillSectionData(r, json); // detect the donuts int index = html.IndexOf("####donut:", 0, false); int length = 4; while (index != -1) { length = html.IndexOf("####", index + 10, false) - index - 10; donuts.Add(html.ToString(index + 10, length)); if (index + length > html.Length) { break; } index = html.IndexOf("####donut:", index + length, false); } } // execute any donuts var sync = new object(); var donutContent = new Dictionary <string, string>(); if (donuts.Count > 0) { foreach (var donut in donuts) { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://" + _request.RequestUri.DnsSafeHost + (_request.RequestUri.IsDefaultPort ? "" : ":" + _request.RequestUri.Port) + "/" + donut)) { request.Properties.Add("donut", true); // ensure any AB testing in donut actions uses the same grouping if (_request.Properties.ContainsKey("experiment")) { request.Properties.Add("experiment", _request.Properties["experiment"]); } // so we can use the same identify and context information in higher up // donut functions. if (_request.Properties.ContainsKey("MS_OwinContext")) { request.Properties.Add("MS_OwinContext", _request.Properties["MS_OwinContext"]); } // temp: try catch to debug "bad headers" foreach (var header in _request.Headers) { try { request.Headers.TryAddWithoutValidation(header.Key, header.Value); } catch (Exception e) { Console.Out.WriteLineAsync("Handlebars - Add Header: " + e.Message); } } // this was previously causing a deadlock, never use .Result!!!! it is the // root of all things evil. using (HttpResponseMessage response = await _client.SendAsync(request, CancellationToken.None)) { if (response.IsSuccessStatusCode) { try { var donutHtml = await response.Content.ReadAsStringAsync(); lock (sync) donutContent.Add(donut, donutHtml); } catch (Exception exp) { lock (sync) donutContent.Add(donut, exp.Message); } } } } } // wait for the donut requests // Console.Out.WriteLineAsync("HandlebarsMediaTypeFormatter: Donuts() " + sw.ElapsedMilliseconds + "ms"); } // StreamWriter writer = new StreamWriter(writeStream); foreach (var donut in donutContent) { html.Replace("####donut:" + donut.Key + "####", donut.Value); } // Console.Out.WriteLineAsync("HandlebarsMediaTypeFormatter: Replace() " + sw.ElapsedMilliseconds + "ms"); // await writer.WriteAsync(html.ToString()); var writer = new StreamWriter(stream); string output, contentType; if (_request.Properties.ContainsKey("hb-as-javascript")) { var lines = html.ToString() .Split(new[] { "\n\r", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); var sb = new StringBuilder(); foreach (var line in lines) { sb.Append("document.write('" + HandlebarsUtilities.ToJavaScriptString(line) + "');"); } output = sb.ToString(); contentType = "application/javascript"; } else { contentType = "text/html"; output = html.ToString(); } content.Headers.ContentType = new MediaTypeHeaderValue(contentType); await writer.WriteAsync(output); await writer.FlushAsync(); return; }