Revert "Remove existing implementation of StartupExceptionPage and use the one in Common"
This reverts commit 83e0d4798e.
This commit is contained in:
parent
83e0d4798e
commit
3f6b558cf3
|
|
@ -5,20 +5,16 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting.Builder;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Hosting.Views;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.StackTrace.Sources;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.Internal
|
||||
{
|
||||
|
|
@ -172,44 +168,15 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
// Generate an HTML error page.
|
||||
var hostingEnv = _applicationServices.GetRequiredService<IHostingEnvironment>();
|
||||
var showDetailedErrors = hostingEnv.IsDevelopment() || _options.DetailedErrors;
|
||||
var errorBytes = StartupExceptionPage.GenerateErrorHtml(showDetailedErrors, ex);
|
||||
|
||||
var model = new ErrorPageModel();
|
||||
var runtimeType = Microsoft.Extensions.Internal.RuntimeEnvironment.RuntimeType;
|
||||
model.RuntimeDisplayName = (runtimeType == "CoreCLR") ? ".NET Core" : runtimeType == "CLR" ? ".NET Framework" : "Mono";
|
||||
#if NETSTANDARD1_3
|
||||
var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).GetTypeInfo().Assembly;
|
||||
var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString();
|
||||
var clrVersion = assemblyVersion;
|
||||
#else
|
||||
var clrVersion = Environment.Version.ToString();
|
||||
#endif
|
||||
model.RuntimeArchitecture = RuntimeInformation.ProcessArchitecture.ToString();
|
||||
var currentAssembly = typeof(ErrorPage).GetTypeInfo().Assembly;
|
||||
model.CurrentAssemblyVesion = currentAssembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
|
||||
.InformationalVersion;
|
||||
model.ClrVersion = clrVersion;
|
||||
model.OperatingSystemDescription = RuntimeInformation.OSDescription;
|
||||
|
||||
if (showDetailedErrors)
|
||||
{
|
||||
var exceptionDetailProvider = new ExceptionDetailsProvider(
|
||||
hostingEnv.ContentRootFileProvider,
|
||||
sourceCodeLineCount: 6);
|
||||
|
||||
model.ErrorDetails = exceptionDetailProvider.GetDetails(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
model.ErrorDetails = new ExceptionDetails[0];
|
||||
}
|
||||
|
||||
var errorPage = new ErrorPage(model);
|
||||
return context =>
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.Headers["Cache-Control"] = "no-cache";
|
||||
return errorPage.ExecuteAsync(context);
|
||||
context.Response.Headers["Cache-Control"] = "private, max-age=0";
|
||||
context.Response.ContentType = "text/html; charset=utf-8";
|
||||
context.Response.ContentLength = errorBytes.Length;
|
||||
return context.Response.Body.WriteAsync(errorBytes, 0, errorBytes.Length);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
// <auto-generated />
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
internal static class Resources
|
||||
{
|
||||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.AspNetCore.Hosting.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// Internal Server Error
|
||||
/// </summary>
|
||||
internal static string ErrorPageHtml_Title
|
||||
{
|
||||
get { return GetString("ErrorPageHtml_Title"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal Server Error
|
||||
/// </summary>
|
||||
internal static string FormatErrorPageHtml_Title()
|
||||
{
|
||||
return GetString("ErrorPageHtml_Title");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An error occurred while starting the application.
|
||||
/// </summary>
|
||||
internal static string ErrorPageHtml_UnhandledException
|
||||
{
|
||||
get { return GetString("ErrorPageHtml_UnhandledException"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An error occurred while starting the application.
|
||||
/// </summary>
|
||||
internal static string FormatErrorPageHtml_UnhandledException()
|
||||
{
|
||||
return GetString("ErrorPageHtml_UnhandledException");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unknown location
|
||||
/// </summary>
|
||||
internal static string ErrorPageHtml_UnknownLocation
|
||||
{
|
||||
get { return GetString("ErrorPageHtml_UnknownLocation"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unknown location
|
||||
/// </summary>
|
||||
internal static string FormatErrorPageHtml_UnknownLocation()
|
||||
{
|
||||
return GetString("ErrorPageHtml_UnknownLocation");
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
||||
System.Diagnostics.Debug.Assert(value != null);
|
||||
|
||||
if (formatterNames != null)
|
||||
{
|
||||
for (var i = 0; i < formatterNames.Length; i++)
|
||||
{
|
||||
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ErrorPageHtml_Title" xml:space="preserve">
|
||||
<value>Internal Server Error</value>
|
||||
</data>
|
||||
<data name="ErrorPageHtml_UnhandledException" xml:space="preserve">
|
||||
<value>An error occurred while starting the application.</value>
|
||||
</data>
|
||||
<data name="ErrorPageHtml_UnknownLocation" xml:space="preserve">
|
||||
<value>Unknown location</value>
|
||||
</data>
|
||||
</root>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,162 +0,0 @@
|
|||
@using System
|
||||
@using System.Globalization
|
||||
@using System.Linq
|
||||
@using System.Net
|
||||
@using System.Reflection
|
||||
@using Microsoft.AspNetCore.Hosting.Views
|
||||
|
||||
@functions
|
||||
{
|
||||
public ErrorPage(ErrorPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public ErrorPageModel Model { get; set; }
|
||||
}
|
||||
@{
|
||||
Response.ContentType = "text/html; charset=utf-8";
|
||||
var location = string.Empty;
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>@Resources.ErrorPageHtml_Title</title>
|
||||
<style>
|
||||
<%$ include: ErrorPage.css %>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>@Resources.ErrorPageHtml_UnhandledException</h1>
|
||||
@foreach (var errorDetail in Model.ErrorDetails)
|
||||
{
|
||||
<div class="titleerror">@errorDetail.Error.GetType().Name: @{ Output.Write(HtmlEncodeAndReplaceLineBreaks(errorDetail.Error.Message)); }</div>
|
||||
@{
|
||||
var firstFrame = errorDetail.StackFrames.FirstOrDefault();
|
||||
if (firstFrame != null)
|
||||
{
|
||||
location = firstFrame.Function;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(location) && firstFrame != null && !string.IsNullOrEmpty(firstFrame.File))
|
||||
{
|
||||
<p class="location">@location in <code title="@firstFrame.File">@System.IO.Path.GetFileName(firstFrame.File)</code>, line @firstFrame.Line</p>
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(location))
|
||||
{
|
||||
<p class="location">@location</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="location">@Resources.ErrorPageHtml_UnknownLocation</p>
|
||||
}
|
||||
|
||||
var reflectionTypeLoadException = errorDetail.Error as ReflectionTypeLoadException;
|
||||
if (reflectionTypeLoadException != null)
|
||||
{
|
||||
if (reflectionTypeLoadException.LoaderExceptions.Length > 0)
|
||||
{
|
||||
<h3>Loader Exceptions:</h3>
|
||||
<ul>
|
||||
@foreach (var ex in reflectionTypeLoadException.LoaderExceptions)
|
||||
{
|
||||
<li>@ex.Message</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
}
|
||||
<div id="stackpage" class="page">
|
||||
<ul>
|
||||
@{
|
||||
var exceptionCount = 0;
|
||||
var stackFrameCount = 0;
|
||||
var exceptionDetailId = "";
|
||||
var frameId = "";
|
||||
}
|
||||
@foreach (var errorDetail in Model.ErrorDetails)
|
||||
{
|
||||
@{
|
||||
exceptionCount++;
|
||||
exceptionDetailId = "exceptionDetail" + exceptionCount;
|
||||
}
|
||||
<li>
|
||||
<h2 class="stackerror">@errorDetail.Error.GetType().Name: @errorDetail.Error.Message</h2>
|
||||
<ul>
|
||||
@foreach (var frame in errorDetail.StackFrames)
|
||||
{
|
||||
@{
|
||||
stackFrameCount++;
|
||||
frameId = "frame" + stackFrameCount;
|
||||
}
|
||||
<li class="frame" id="@frameId">
|
||||
@if (string.IsNullOrEmpty(frame.File))
|
||||
{
|
||||
<h3>@frame.Function</h3>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h3>@frame.Function in <code title="@frame.File">@System.IO.Path.GetFileName(frame.File)</code></h3>
|
||||
}
|
||||
|
||||
@if (frame.Line != 0 && frame.ContextCode.Any())
|
||||
{
|
||||
<button class="expandCollapseButton" data-frameId="@frameId">+</button>
|
||||
<div class="source">
|
||||
@if (frame.PreContextCode.Any())
|
||||
{
|
||||
<ol start="@frame.PreContextLine" class="collapsible">
|
||||
@foreach (var line in frame.PreContextCode)
|
||||
{
|
||||
<li><span>@line</span></li>
|
||||
}
|
||||
</ol>
|
||||
}
|
||||
|
||||
<ol start="@frame.Line" class="highlight">
|
||||
@foreach (var line in frame.ContextCode)
|
||||
{
|
||||
<li><span>@line</span></li>
|
||||
}
|
||||
</ol>
|
||||
|
||||
@if (frame.PostContextCode.Any())
|
||||
{
|
||||
<ol start='@(frame.Line + 1)' class="collapsible">
|
||||
@foreach (var line in frame.PostContextCode)
|
||||
{
|
||||
<li><span>@line</span></li>
|
||||
}
|
||||
</ol>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<br/>
|
||||
<div class="rawExceptionBlock">
|
||||
<div class="showRawExceptionContainer">
|
||||
<button class="showRawException" data-exceptionDetailId="@exceptionDetailId">Show raw exception details</button>
|
||||
</div>
|
||||
<div id="@exceptionDetailId" class="rawExceptionDetails">
|
||||
<pre class="rawExceptionStackTrace">@errorDetail.Error.ToString()</pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<footer>
|
||||
@Model.RuntimeDisplayName @Model.RuntimeArchitecture v@(Model.ClrVersion) | Microsoft.AspNetCore.Hosting version @Model.CurrentAssemblyVesion | @Model.OperatingSystemDescription | <a href="http://go.microsoft.com/fwlink/?LinkId=517394">Need help?</a>
|
||||
</footer>
|
||||
<script>
|
||||
//<!--
|
||||
<%$ include: ErrorPage.js %>
|
||||
//-->
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
|
||||
font-size: .813em;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
/*font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif;*/
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #44525e;
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 10px 5px 0 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #363636;
|
||||
margin: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Consolas, "Courier New", courier, monospace;
|
||||
}
|
||||
|
||||
body .titleerror {
|
||||
padding: 3px 3px 6px 3px;
|
||||
display: block;
|
||||
font-size: 1.5em;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
body .location {
|
||||
margin: 3px 0 10px 30px;
|
||||
}
|
||||
|
||||
#header {
|
||||
font-size: 18px;
|
||||
padding: 15px 0;
|
||||
border-top: 1px #ddd solid;
|
||||
border-bottom: 1px #ddd solid;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#header li {
|
||||
display: inline;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
color: #a0a0a0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#header .selected {
|
||||
background: #44c5f2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#stackpage ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
/*border-bottom: 1px #ddd solid;*/
|
||||
}
|
||||
|
||||
#stackpage .details {
|
||||
font-size: 1.2em;
|
||||
padding: 3px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#stackpage .stackerror {
|
||||
padding: 5px;
|
||||
border-bottom: 1px #ddd solid;
|
||||
}
|
||||
|
||||
|
||||
#stackpage .frame {
|
||||
padding: 0;
|
||||
margin: 0 0 0 30px;
|
||||
}
|
||||
|
||||
#stackpage .frame h3 {
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#stackpage .source {
|
||||
padding: 0 0 0 30px;
|
||||
}
|
||||
|
||||
#stackpage .source ol li {
|
||||
font-family: Consolas, "Courier New", courier, monospace;
|
||||
white-space: pre;
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
|
||||
#stackpage .frame .source .highlight li span {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
#stackpage .source ol.collapsible li {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#stackpage .source ol.collapsible li span {
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.page table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.page th {
|
||||
vertical-align: bottom;
|
||||
padding: 10px 5px 5px 5px;
|
||||
font-weight: 400;
|
||||
color: #a0a0a0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.page td {
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
.page th, .page td {
|
||||
border-right: 1px #ddd solid;
|
||||
border-bottom: 1px #ddd solid;
|
||||
border-left: 1px transparent solid;
|
||||
border-top: 1px transparent solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page th:last-child, .page td:last-child {
|
||||
border-right: 1px transparent solid;
|
||||
}
|
||||
|
||||
.page .length {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1ba1e2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #13709e;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.showRawException {
|
||||
cursor: pointer;
|
||||
color: #44c5f2;
|
||||
background-color: transparent;
|
||||
font-size: 1.2em;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rawExceptionStackTrace {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.rawExceptionBlock {
|
||||
border-top: 1px #ddd solid;
|
||||
border-bottom: 1px #ddd solid;
|
||||
}
|
||||
|
||||
.showRawExceptionContainer {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.expandCollapseButton {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
font-size: 10px;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
background-color: #eee;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
(function (window, undefined) {
|
||||
"use strict";
|
||||
|
||||
function ns(selector, element) {
|
||||
return new NodeCollection(selector, element);
|
||||
}
|
||||
|
||||
function NodeCollection(selector, element) {
|
||||
this.items = [];
|
||||
element = element || window.document;
|
||||
|
||||
var nodeList;
|
||||
|
||||
if (typeof (selector) === "string") {
|
||||
nodeList = element.querySelectorAll(selector);
|
||||
for (var i = 0, l = nodeList.length; i < l; i++) {
|
||||
this.items.push(nodeList.item(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodeCollection.prototype = {
|
||||
each: function (callback) {
|
||||
for (var i = 0, l = this.items.length; i < l; i++) {
|
||||
callback(this.items[i], i);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
children: function (selector) {
|
||||
var children = [];
|
||||
|
||||
this.each(function (el) {
|
||||
children = children.concat(ns(selector, el).items);
|
||||
});
|
||||
|
||||
return ns(children);
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.each(function (el) {
|
||||
el.style.display = "none";
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
this.each(function (el) {
|
||||
el.style.display = el.style.display === "none" ? "" : "none";
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.each(function (el) {
|
||||
el.style.display = "";
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
addClass: function (className) {
|
||||
this.each(function (el) {
|
||||
var existingClassName = el.className,
|
||||
classNames;
|
||||
if (!existingClassName) {
|
||||
el.className = className;
|
||||
} else {
|
||||
classNames = existingClassName.split(" ");
|
||||
if (classNames.indexOf(className) < 0) {
|
||||
el.className = existingClassName + " " + className;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeClass: function (className) {
|
||||
this.each(function (el) {
|
||||
var existingClassName = el.className,
|
||||
classNames, index;
|
||||
if (existingClassName === className) {
|
||||
el.className = "";
|
||||
} else if (existingClassName) {
|
||||
classNames = existingClassName.split(" ");
|
||||
index = classNames.indexOf(className);
|
||||
if (index > 0) {
|
||||
classNames.splice(index, 1);
|
||||
el.className = classNames.join(" ");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
attr: function (name) {
|
||||
if (this.items.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.items[0].getAttribute(name);
|
||||
},
|
||||
|
||||
on: function (eventName, handler) {
|
||||
this.each(function (el, idx) {
|
||||
var callback = function (e) {
|
||||
e = e || window.event;
|
||||
if (!e.which && e.keyCode) {
|
||||
e.which = e.keyCode; // Normalize IE8 key events
|
||||
}
|
||||
handler.apply(el, [e]);
|
||||
};
|
||||
|
||||
if (el.addEventListener) { // DOM Events
|
||||
el.addEventListener(eventName, callback, false);
|
||||
} else if (el.attachEvent) { // IE8 events
|
||||
el.attachEvent("on" + eventName, callback);
|
||||
} else {
|
||||
el["on" + type] = callback;
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
click: function (handler) {
|
||||
return this.on("click", handler);
|
||||
},
|
||||
|
||||
keypress: function (handler) {
|
||||
return this.on("keypress", handler);
|
||||
}
|
||||
};
|
||||
|
||||
function frame(el) {
|
||||
ns(".source .collapsible", el).toggle();
|
||||
}
|
||||
|
||||
function expandCollapseButton(el) {
|
||||
var frameId = el.getAttribute("data-frameId");
|
||||
frame(document.getElementById(frameId));
|
||||
if (el.innerText === "+") {
|
||||
el.innerText = "-";
|
||||
}
|
||||
else {
|
||||
el.innerText = "+";
|
||||
}
|
||||
}
|
||||
|
||||
function tab(el) {
|
||||
var unselected = ns("#header .selected").removeClass("selected").attr("id");
|
||||
var selected = ns("#" + el.id).addClass("selected").attr("id");
|
||||
|
||||
ns("#" + unselected + "page").hide();
|
||||
ns("#" + selected + "page").show();
|
||||
}
|
||||
|
||||
ns(".rawExceptionDetails").hide();
|
||||
ns(".collapsible").hide();
|
||||
ns(".page").hide();
|
||||
ns("#stackpage").show();
|
||||
|
||||
ns(".expandCollapseButton")
|
||||
.click(function () {
|
||||
expandCollapseButton(this);
|
||||
})
|
||||
.keypress(function (e) {
|
||||
if (e.which === 13) {
|
||||
expandCollapseButton(this);
|
||||
}
|
||||
});
|
||||
|
||||
ns("#header li")
|
||||
.click(function () {
|
||||
tab(this);
|
||||
})
|
||||
.keypress(function (e) {
|
||||
if (e.which === 13) {
|
||||
tab(this);
|
||||
}
|
||||
});
|
||||
|
||||
ns(".showRawException")
|
||||
.click(function () {
|
||||
var exceptionDetailId = this.getAttribute("data-exceptionDetailId");
|
||||
ns("#" + exceptionDetailId).toggle();
|
||||
});
|
||||
})(window);
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.Extensions.StackTrace.Sources;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds data to be displayed on the error page.
|
||||
/// </summary>
|
||||
internal class ErrorPageModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Detailed information about each exception in the stack.
|
||||
/// </summary>
|
||||
public IEnumerable<ExceptionDetails> ErrorDetails { get; set; }
|
||||
|
||||
public string RuntimeDisplayName { get; set; }
|
||||
|
||||
public string RuntimeArchitecture { get; set; }
|
||||
|
||||
public string ClrVersion { get; set; }
|
||||
|
||||
public string CurrentAssemblyVesion { get; set; }
|
||||
|
||||
public string OperatingSystemDescription { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
// 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.Reflection;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.Extensions.StackTrace.Sources;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
internal static class StartupExceptionPage
|
||||
{
|
||||
private static readonly string _errorPageFormatString = GetResourceString("GenericError.html", escapeBraces: true);
|
||||
private static readonly string _errorMessageFormatString = GetResourceString("GenericError_Message.html");
|
||||
private static readonly string _errorExceptionFormatString = GetResourceString("GenericError_Exception.html");
|
||||
private static readonly string _errorFooterFormatString = GetResourceString("GenericError_Footer.html");
|
||||
|
||||
public static byte[] GenerateErrorHtml(bool showDetails, Exception exception)
|
||||
{
|
||||
// Build the message for each error
|
||||
var builder = new StringBuilder();
|
||||
var rawExceptionDetails = new StringBuilder();
|
||||
|
||||
if (!showDetails)
|
||||
{
|
||||
WriteMessage("An error occurred while starting the application.", builder);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(exception != null);
|
||||
var wasSourceCodeWrittenOntoPage = false;
|
||||
var flattenedExceptions = FlattenAndReverseExceptionTree(exception);
|
||||
foreach (var innerEx in flattenedExceptions)
|
||||
{
|
||||
WriteException(innerEx, builder, ref wasSourceCodeWrittenOntoPage);
|
||||
}
|
||||
|
||||
WriteRawExceptionDetails("Show raw exception details", exception.ToString(), rawExceptionDetails);
|
||||
}
|
||||
|
||||
// Generate the footer
|
||||
var footer = showDetails ? GenerateFooterEncoded() : null;
|
||||
|
||||
// And generate the full markup
|
||||
return Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, _errorPageFormatString, builder, rawExceptionDetails, footer));
|
||||
}
|
||||
|
||||
private static string BuildCodeSnippetDiv(StackFrameInfo frameInfo)
|
||||
{
|
||||
var filename = frameInfo.FilePath;
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
int failingLineNumber = frameInfo.LineNumber;
|
||||
if (failingLineNumber >= 1)
|
||||
{
|
||||
var lines = GetFailingCallSiteInFile(filename, failingLineNumber);
|
||||
if (lines != null)
|
||||
{
|
||||
return @"<div class=""codeSnippet"">"
|
||||
+ @"<div class=""filename""><code>" + HtmlEncodeAndReplaceLineBreaks(filename) + "</code></div>" + Environment.NewLine
|
||||
+ string.Join(Environment.NewLine, lines) + "</div>" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string BuildLineForStackFrame(StackFrameInfo frameInfo)
|
||||
{
|
||||
var builder = new StringBuilder("<pre>");
|
||||
var stackFrame = frameInfo.StackFrame;
|
||||
var method = stackFrame.GetMethod();
|
||||
var displayInfo = frameInfo.MethodDisplayInfo;
|
||||
|
||||
// Special case: no method available
|
||||
if (method == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// First, write the type name
|
||||
var type = method.DeclaringType;
|
||||
if (type != null)
|
||||
{
|
||||
// Special-case ExceptionDispatchInfo.Throw()
|
||||
if (type == typeof(ExceptionDispatchInfo) && method.Name == "Throw")
|
||||
{
|
||||
return @"<pre><span class=""faded"">--- exception rethrown ---</span></pre>";
|
||||
}
|
||||
|
||||
var typeName = displayInfo.DeclaringTypeName;
|
||||
// Separate the namespace component from the type name so that we can format it differently.
|
||||
if (!string.IsNullOrEmpty(typeName) && !string.IsNullOrEmpty(type.Namespace))
|
||||
{
|
||||
builder.Append($@"<span class=""faded"">at {HtmlEncodeAndReplaceLineBreaks(type.Namespace)}</span>");
|
||||
typeName = typeName.Substring(type.Namespace.Length);
|
||||
}
|
||||
|
||||
builder.Append(HtmlEncodeAndReplaceLineBreaks(typeName));
|
||||
}
|
||||
|
||||
// Next, write the method signature
|
||||
builder.Append(displayInfo.Name);
|
||||
|
||||
// Build method parameters
|
||||
var methodParameters = "(" + string.Join(", ", displayInfo.Parameters) + ")";
|
||||
builder.Append($@"<span class=""faded"">{HtmlEncodeAndReplaceLineBreaks(methodParameters)}</span>");
|
||||
|
||||
// Do we have source information for this frame?
|
||||
if (stackFrame.GetILOffset() != -1)
|
||||
{
|
||||
var filename = frameInfo.FilePath;
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
builder.AppendFormat(CultureInfo.InvariantCulture, " in {0}:line {1:D}", HtmlEncodeAndReplaceLineBreaks(filename), frameInfo.LineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// Finish
|
||||
builder.Append("</pre>");
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static string GetResourceString(string name, bool escapeBraces = false)
|
||||
{
|
||||
// '{' and '}' are special in CSS, so we use "[[[0]]]" instead for {0} (and so on).
|
||||
var assembly = typeof(StartupExceptionPage).GetTypeInfo().Assembly;
|
||||
var resourceName = assembly.GetName().Name + ".compiler.resources." + name;
|
||||
var manifestStream = assembly.GetManifestResourceStream(resourceName);
|
||||
var formatString = new StreamReader(manifestStream, Encoding.UTF8, detectEncodingFromByteOrderMarks: false).ReadToEnd();
|
||||
if (escapeBraces)
|
||||
{
|
||||
formatString = formatString.Replace("{", "{{").Replace("}", "}}").Replace("[[[", "{").Replace("]]]", "}");
|
||||
}
|
||||
|
||||
return formatString;
|
||||
}
|
||||
|
||||
private static List<string> GetFailingCallSiteInFile(string filename, int failedLineNumber)
|
||||
{
|
||||
// We figure out the [first, last] range of lines to read from the file.
|
||||
var firstLineNumber = failedLineNumber - 2;
|
||||
firstLineNumber = Math.Max(1, firstLineNumber);
|
||||
var lastLineNumber = failedLineNumber + 2;
|
||||
lastLineNumber = Math.Max(lastLineNumber, failedLineNumber);
|
||||
|
||||
// Figure out how many characters lastLineNumber will take to print.
|
||||
var lastLineNumberCharLength = lastLineNumber.ToString("D", CultureInfo.InvariantCulture).Length;
|
||||
|
||||
var errorSubContents = new List<string>();
|
||||
var didReadFailingLine = false;
|
||||
|
||||
try
|
||||
{
|
||||
var thisLineNum = 0;
|
||||
foreach (var line in File.ReadLines(filename))
|
||||
{
|
||||
thisLineNum++;
|
||||
|
||||
// Are we within the correct range?
|
||||
if (thisLineNum < firstLineNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (thisLineNum > lastLineNumber)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var encodedLine = HtmlEncodeAndReplaceLineBreaks("Line "
|
||||
+ thisLineNum.ToString("D", CultureInfo.InvariantCulture).PadLeft(lastLineNumberCharLength)
|
||||
+ ": "
|
||||
+ line);
|
||||
|
||||
if (thisLineNum == failedLineNumber)
|
||||
{
|
||||
didReadFailingLine = true;
|
||||
errorSubContents.Add(@"<div class=""line error""><code>" + encodedLine + "</code></div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
errorSubContents.Add(@"<div class=""line""><code>" + encodedLine + "</code></div>");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If there's an error for any reason, don't show source.
|
||||
return null;
|
||||
}
|
||||
|
||||
return (didReadFailingLine) ? errorSubContents : null;
|
||||
}
|
||||
|
||||
private static string GenerateFooterEncoded()
|
||||
{
|
||||
var runtimeType = HtmlEncodeAndReplaceLineBreaks(Microsoft.Extensions.Internal.RuntimeEnvironment.RuntimeType);
|
||||
var runtimeDisplayName = runtimeType == "CoreCLR" ? ".NET Core" : runtimeType == "CLR" ? ".NET Framework" : "Mono";
|
||||
#if NETSTANDARD1_3
|
||||
var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).GetTypeInfo().Assembly;
|
||||
var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString();
|
||||
var clrVersion = HtmlEncodeAndReplaceLineBreaks(assemblyVersion);
|
||||
#else
|
||||
var clrVersion = HtmlEncodeAndReplaceLineBreaks(Environment.Version.ToString());
|
||||
#endif
|
||||
var runtimeArch = HtmlEncodeAndReplaceLineBreaks(RuntimeInformation.ProcessArchitecture.ToString());
|
||||
var currentAssembly = typeof(StartupExceptionPage).GetTypeInfo().Assembly;
|
||||
var currentAssemblyVersion = currentAssembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
||||
currentAssemblyVersion = HtmlEncodeAndReplaceLineBreaks(currentAssemblyVersion);
|
||||
|
||||
var osDescription = HtmlEncodeAndReplaceLineBreaks(RuntimeInformation.OSDescription);
|
||||
|
||||
return string.Format(CultureInfo.InvariantCulture, _errorFooterFormatString, runtimeDisplayName, runtimeArch, clrVersion,
|
||||
currentAssemblyVersion, osDescription);
|
||||
}
|
||||
|
||||
private static string HtmlEncodeAndReplaceLineBreaks(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// Split on line breaks before passing it through the encoder.
|
||||
// We use the static default encoder since we can't depend on DI in the error handling logic.
|
||||
return string.Join("<br />" + Environment.NewLine,
|
||||
input.Split(new[] { "\r\n" }, StringSplitOptions.None)
|
||||
.SelectMany(s => s.Split(new[] { '\r', '\n' }, StringSplitOptions.None))
|
||||
.Select(HtmlEncoder.Default.Encode));
|
||||
}
|
||||
|
||||
private static void WriteException(Exception ex, StringBuilder builder, ref bool wasFailingCallSiteSourceWritten)
|
||||
{
|
||||
string inlineSourceDiv = null;
|
||||
|
||||
// First, build the stack trace
|
||||
var firstStackFrame = true;
|
||||
var stackTraceBuilder = new StringBuilder();
|
||||
foreach (var frameInfo in StackTraceHelper.GetFrames(ex))
|
||||
{
|
||||
if (!firstStackFrame)
|
||||
{
|
||||
stackTraceBuilder.Append("<br />");
|
||||
}
|
||||
firstStackFrame = false;
|
||||
var thisFrameLine = BuildLineForStackFrame(frameInfo);
|
||||
stackTraceBuilder.AppendLine(thisFrameLine);
|
||||
|
||||
// Try to include the source code in the error page if we can.
|
||||
if (!wasFailingCallSiteSourceWritten && inlineSourceDiv == null)
|
||||
{
|
||||
inlineSourceDiv = BuildCodeSnippetDiv(frameInfo);
|
||||
if (inlineSourceDiv != null)
|
||||
{
|
||||
wasFailingCallSiteSourceWritten = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, build the rest of the <div>
|
||||
builder.AppendFormat(CultureInfo.InvariantCulture, _errorExceptionFormatString,
|
||||
HtmlEncodeAndReplaceLineBreaks(ex.GetType().FullName),
|
||||
HtmlEncodeAndReplaceLineBreaks(ex.Message),
|
||||
inlineSourceDiv,
|
||||
stackTraceBuilder);
|
||||
}
|
||||
|
||||
private static void WriteRawExceptionDetails(string linkText, string line, StringBuilder rawExceptionDetails)
|
||||
{
|
||||
rawExceptionDetails
|
||||
.AppendLine("<div class=\"rawExceptionBlock\">")
|
||||
.AppendFormat($" <div><a href=\"#\" onclick=\"javascript: showRawException(); return false;\">{linkText}</a></div>")
|
||||
.AppendLine()
|
||||
.AppendLine(" <div id=\"rawException\">")
|
||||
.Append(" <pre>");
|
||||
|
||||
rawExceptionDetails.AppendLine(line);
|
||||
|
||||
rawExceptionDetails
|
||||
.AppendLine("</pre>")
|
||||
.AppendLine(" </div>")
|
||||
.AppendLine("</div>");
|
||||
}
|
||||
|
||||
private static void WriteMessage(string message, StringBuilder builder)
|
||||
{
|
||||
// Build the <div>
|
||||
builder.AppendFormat(CultureInfo.InvariantCulture, _errorMessageFormatString,
|
||||
HtmlEncodeAndReplaceLineBreaks(message));
|
||||
}
|
||||
|
||||
private static IEnumerable<Exception> FlattenAndReverseExceptionTree(Exception ex)
|
||||
{
|
||||
// ReflectionTypeLoadException is special because the details are in
|
||||
// the LoaderExceptions property
|
||||
var typeLoadException = ex as ReflectionTypeLoadException;
|
||||
if (typeLoadException != null)
|
||||
{
|
||||
var typeLoadExceptions = new List<Exception>();
|
||||
foreach (var loadException in typeLoadException.LoaderExceptions)
|
||||
{
|
||||
typeLoadExceptions.AddRange(FlattenAndReverseExceptionTree(loadException));
|
||||
}
|
||||
|
||||
typeLoadExceptions.Add(ex);
|
||||
return typeLoadExceptions;
|
||||
}
|
||||
|
||||
var list = new List<Exception>();
|
||||
while (ex != null)
|
||||
{
|
||||
list.Add(ex);
|
||||
ex = ex.InnerException;
|
||||
}
|
||||
list.Reverse();
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,17 +24,13 @@
|
|||
"Microsoft.AspNetCore.Hosting.Server.Abstractions": "1.1.0-*",
|
||||
"Microsoft.AspNetCore.Http": "1.1.0-*",
|
||||
"Microsoft.AspNetCore.Http.Extensions": "1.1.0-*",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "1.1.0-*",
|
||||
"Microsoft.Extensions.Options": "1.1.0-*",
|
||||
"Microsoft.Extensions.Configuration": "1.1.0-*",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0-*",
|
||||
"Microsoft.Extensions.DependencyInjection": "1.1.0-*",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "1.1.0-*",
|
||||
"Microsoft.Extensions.Logging": "1.1.0-*",
|
||||
"Microsoft.Extensions.Options": "1.1.0-*",
|
||||
"Microsoft.Extensions.PlatformAbstractions": "1.1.0-*",
|
||||
"Microsoft.Extensions.RazorViews.Sources": {
|
||||
"type": "build",
|
||||
"version": "1.1.0-*"
|
||||
},
|
||||
"Microsoft.Extensions.RuntimeEnvironment.Sources": {
|
||||
"type": "build",
|
||||
"version": "1.1.0-*"
|
||||
|
|
@ -72,8 +68,5 @@
|
|||
"System.Reflection.Extensions": "4.0.1-*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"RazorPageGenerator": "1.1.0-*"
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
using (host)
|
||||
{
|
||||
host.Start();
|
||||
await AssertResponseContains(server.RequestDelegate, "Message from the LoaderException</div>");
|
||||
await AssertResponseContains(server.RequestDelegate, "Message from the LoaderException</span>");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -481,20 +481,20 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
|
||||
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnv.ApplicationName);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Configure_SupportsStaticMethodDelegate()
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseServer(new TestServer())
|
||||
.Configure(StaticConfigureMethod)
|
||||
.Configure(StaticConfigureMethod)
|
||||
.Build();
|
||||
|
||||
var hostingEnv = host.Services.GetService<IHostingEnvironment>();
|
||||
Assert.Equal("Microsoft.AspNetCore.Hosting.Tests", hostingEnv.ApplicationName);
|
||||
}
|
||||
|
||||
private static void StaticConfigureMethod(IApplicationBuilder app)
|
||||
private static void StaticConfigureMethod(IApplicationBuilder app)
|
||||
{ }
|
||||
|
||||
private IWebHostBuilder CreateWebHostBuilder()
|
||||
|
|
|
|||
Loading…
Reference in New Issue