diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs index c2a591b5b8c1..8098c5838f8f 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs @@ -5,16 +5,20 @@ 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 { @@ -168,15 +172,44 @@ private RequestDelegate BuildApplication() // Generate an HTML error page. var hostingEnv = _applicationServices.GetRequiredService(); 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() + .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"] = "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); + context.Response.Headers["Cache-Control"] = "no-cache"; + return errorPage.ExecuteAsync(context); }; } } diff --git a/src/Microsoft.AspNetCore.Hosting/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Hosting/Properties/Resources.Designer.cs new file mode 100644 index 000000000000..397c84eba2f4 --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/Properties/Resources.Designer.cs @@ -0,0 +1,78 @@ +// +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); + + /// + /// Internal Server Error + /// + internal static string ErrorPageHtml_Title + { + get { return GetString("ErrorPageHtml_Title"); } + } + + /// + /// Internal Server Error + /// + internal static string FormatErrorPageHtml_Title() + { + return GetString("ErrorPageHtml_Title"); + } + + /// + /// An error occurred while starting the application. + /// + internal static string ErrorPageHtml_UnhandledException + { + get { return GetString("ErrorPageHtml_UnhandledException"); } + } + + /// + /// An error occurred while starting the application. + /// + internal static string FormatErrorPageHtml_UnhandledException() + { + return GetString("ErrorPageHtml_UnhandledException"); + } + + /// + /// Unknown location + /// + internal static string ErrorPageHtml_UnknownLocation + { + get { return GetString("ErrorPageHtml_UnknownLocation"); } + } + + /// + /// Unknown location + /// + 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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Hosting/Resources.resx b/src/Microsoft.AspNetCore.Hosting/Resources.resx new file mode 100644 index 000000000000..6af96304664d --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/Resources.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Internal Server Error + + + An error occurred while starting the application. + + + Unknown location + + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Hosting/Startup/ExceptionPage/Views/ErrorPage.Designer.cs b/src/Microsoft.AspNetCore.Hosting/Startup/ExceptionPage/Views/ErrorPage.Designer.cs new file mode 100644 index 000000000000..52a6db45d33d --- /dev/null +++ b/src/Microsoft.AspNetCore.Hosting/Startup/ExceptionPage/Views/ErrorPage.Designer.cs @@ -0,0 +1,1055 @@ +namespace Microsoft.AspNetCore.Hosting.Views +{ +#line 1 "ErrorPage.cshtml" +using System + +#line default +#line hidden + ; +#line 2 "ErrorPage.cshtml" +using System.Globalization + +#line default +#line hidden + ; +#line 3 "ErrorPage.cshtml" +using System.Linq + +#line default +#line hidden + ; +#line 4 "ErrorPage.cshtml" +using System.Net + +#line default +#line hidden + ; +#line 5 "ErrorPage.cshtml" +using System.Reflection + +#line default +#line hidden + ; +#line 6 "ErrorPage.cshtml" +using Microsoft.AspNetCore.Hosting.Views + +#line default +#line hidden + ; + using System.Threading.Tasks; + + internal class ErrorPage : Microsoft.Extensions.RazorViews.BaseView + { +#line 9 "ErrorPage.cshtml" + + public ErrorPage(ErrorPageModel model) + { + Model = model; + } + + public ErrorPageModel Model { get; set; } + +#line default +#line hidden + #line hidden + public ErrorPage() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + WriteLiteral("\r\n"); +#line 17 "ErrorPage.cshtml" + + Response.ContentType = "text/html; charset=utf-8"; + var location = string.Empty; + +#line default +#line hidden + + WriteLiteral("\r\n