// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.DiagnosticsViewPage.Views { /// /// Infrastructure /// [Obsolete("This type is for internal use only and will be removed in a future version.")] public abstract class BaseView { /// /// The request context /// protected HttpContext Context { get; private set; } /// /// The request /// protected HttpRequest Request { get; private set; } /// /// The response /// protected HttpResponse Response { get; private set; } /// /// The output stream /// protected StreamWriter Output { get; private set; } /// /// Html encoder used to encode content. /// protected HtmlEncoder HtmlEncoder { get; set; } = HtmlEncoder.Default; /// /// Url encoder used to encode content. /// protected UrlEncoder UrlEncoder { get; set; } = UrlEncoder.Default; /// /// JavaScript encoder used to encode content. /// protected JavaScriptEncoder JavaScriptEncoder { get; set; } = JavaScriptEncoder.Default; /// /// Execute an individual request /// /// public async Task ExecuteAsync(HttpContext context) { Context = context; Request = Context.Request; Response = Context.Response; Output = new StreamWriter(Response.Body, Encoding.UTF8, 4096, leaveOpen: true); await ExecuteAsync(); Output.Dispose(); } /// /// Execute an individual request /// public abstract Task ExecuteAsync(); /// /// Write the given value directly to the output /// /// protected void WriteLiteral(string value) { WriteLiteralTo(Output, value); } /// /// Write the given value directly to the output /// /// protected void WriteLiteral(object value) { WriteLiteralTo(Output, value); } private List AttributeValues { get; set; } protected void WriteAttributeValue(string thingy, int startPostion, object value, int endValue, int dealyo, bool yesno) { if (AttributeValues == null) { AttributeValues = new List(); } AttributeValues.Add(value.ToString()); } private string AttributeEnding { get; set; } protected void BeginWriteAttribute(string name, string begining, int startPosition, string ending, int endPosition, int thingy) { Debug.Assert(string.IsNullOrEmpty(AttributeEnding)); Output.Write(begining); AttributeEnding = ending; } protected void EndWriteAttribute() { Debug.Assert(!string.IsNullOrEmpty(AttributeEnding)); var attributes = string.Join(" ", AttributeValues); Output.Write(attributes); AttributeValues = null; Output.Write(AttributeEnding); AttributeEnding = null; } /// /// Writes the given attribute to the given writer /// /// The instance to write to. /// The name of the attribute to write /// The value of the prefix /// The value of the suffix /// The s to write. protected void WriteAttributeTo( TextWriter writer, string name, string leader, string trailer, params AttributeValue[] values) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (name == null) { throw new ArgumentNullException(nameof(name)); } if (leader == null) { throw new ArgumentNullException(nameof(leader)); } if (trailer == null) { throw new ArgumentNullException(nameof(trailer)); } WriteLiteralTo(writer, leader); foreach (var value in values) { WriteLiteralTo(writer, value.Prefix); // The special cases here are that the value we're writing might already be a string, or that the // value might be a bool. If the value is the bool 'true' we want to write the attribute name // instead of the string 'true'. If the value is the bool 'false' we don't want to write anything. // Otherwise the value is another object (perhaps an HtmlString) and we'll ask it to format itself. string stringValue; if (value.Value is bool) { if ((bool)value.Value) { stringValue = name; } else { continue; } } else { stringValue = value.Value as string; } // Call the WriteTo(string) overload when possible if (value.Literal && stringValue != null) { WriteLiteralTo(writer, stringValue); } else if (value.Literal) { WriteLiteralTo(writer, value.Value); } else if (stringValue != null) { WriteTo(writer, stringValue); } else { WriteTo(writer, value.Value); } } WriteLiteralTo(writer, trailer); } /// /// Convert to string and html encode /// /// protected void Write(object value) { WriteTo(Output, value); } /// /// Html encode and write /// /// protected void Write(string value) { WriteTo(Output, value); } /// /// is invoked /// /// The to invoke protected void Write(HelperResult result) { WriteTo(Output, result); } /// /// Writes the specified to . /// /// The instance to write to. /// The to write. /// /// is invoked for types. /// For all other types, the encoded result of is written to the /// . /// protected void WriteTo(TextWriter writer, object value) { if (value != null) { var helperResult = value as HelperResult; if (helperResult != null) { helperResult.WriteTo(writer); } else { WriteTo(writer, Convert.ToString(value, CultureInfo.InvariantCulture)); } } } /// /// Writes the specified with HTML encoding to . /// /// The instance to write to. /// The to write. protected void WriteTo(TextWriter writer, string value) { WriteLiteralTo(writer, HtmlEncoder.Encode(value)); } /// /// Writes the specified without HTML encoding to the . /// /// The instance to write to. /// The to write. protected void WriteLiteralTo(TextWriter writer, object value) { WriteLiteralTo(writer, Convert.ToString(value, CultureInfo.InvariantCulture)); } /// /// Writes the specified without HTML encoding to . /// /// The instance to write to. /// The to write. protected void WriteLiteralTo(TextWriter writer, string value) { if (!string.IsNullOrEmpty(value)) { writer.Write(value); } } protected string HtmlEncodeAndReplaceLineBreaks(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } // Split on line breaks before passing it through the encoder. return string.Join("
" + Environment.NewLine, input.Split(new[] { "\r\n" }, StringSplitOptions.None) .SelectMany(s => s.Split(new[] { '\r', '\n' }, StringSplitOptions.None)) .Select(HtmlEncoder.Encode)); } } }