// 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));
}
}
}