Adding ability to turn off the status code pages
Added a feature named IStatusCodeFeature with an enabled property. MVC or any framework can get this feature and turn it off if it does not want status code pages logic to take over and send HTML response. Also refactored the sample flow to make it easier to understand.
This commit is contained in:
parent
31afaca7e3
commit
f243244972
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22228.1
|
||||
VisualStudioVersion = 14.0.22530.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{509A6F36-AD80-4A18-B5B1-717D38DFF29D}"
|
||||
EndProject
|
||||
|
|
@ -38,6 +38,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Diagnostic
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StatusCodePagesSample", "samples\StatusCodePagesSample\StatusCodePagesSample.kproj", "{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Diagnostics.Interfaces", "src\Microsoft.AspNet.Diagnostics.Interfaces\Microsoft.AspNet.Diagnostics.Interfaces.kproj", "{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -178,6 +180,18 @@ Global
|
|||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -195,5 +209,6 @@ Global
|
|||
{2F9B479D-8247-4210-804B-78E6DD5C3E98} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{624B0019-956A-4157-B008-270C5B229553} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -25,54 +26,75 @@ namespace StatusCodePagesSample
|
|||
// app.UseStatusCodePagesWithReExecute("/errors/{0}");
|
||||
|
||||
// "/[?statuscode=400]"
|
||||
app.Use((context, next) =>
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
if (context.Request.Path.HasValue && !context.Request.Path.Equals(new PathString("/")))
|
||||
{
|
||||
return next();
|
||||
}
|
||||
|
||||
// Check for ?statuscode=400
|
||||
var requestedStatusCode = context.Request.Query["statuscode"];
|
||||
if (!string.IsNullOrEmpty(requestedStatusCode))
|
||||
{
|
||||
context.Response.StatusCode = int.Parse(requestedStatusCode);
|
||||
return Task.FromResult(0);
|
||||
|
||||
// To turn off the StatusCode feature - For example the below code turns off the StatusCode middleware
|
||||
// if the query contains a disableStatusCodePages=true parameter.
|
||||
var disableStatusCodePages = context.Request.Query["disableStatusCodePages"];
|
||||
if (disableStatusCodePages == "true")
|
||||
{
|
||||
var statusCodePagesFeature = context.GetFeature<IStatusCodePagesFeature>();
|
||||
if (statusCodePagesFeature != null)
|
||||
{
|
||||
statusCodePagesFeature.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
await Task.FromResult(0);
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("<html><body>");
|
||||
builder.AppendLine("<a href=\"" +
|
||||
WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/\">" +
|
||||
WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/</a><br>");
|
||||
|
||||
for (int statusCode = 400; statusCode < 600; statusCode++)
|
||||
else
|
||||
{
|
||||
builder.AppendLine("<a href=\"?statuscode=" + statusCode + "\">" + statusCode + "</a><br>");
|
||||
await next();
|
||||
}
|
||||
builder.AppendLine("</body></html>");
|
||||
return context.Response.SendAsync(builder.ToString(), "text/html");
|
||||
});
|
||||
|
||||
// "/errors/400"
|
||||
app.Use((context, next) =>
|
||||
app.Map("/errors", error =>
|
||||
{
|
||||
PathString remainder;
|
||||
if (context.Request.Path.StartsWithSegments(new PathString("/errors"), out remainder))
|
||||
error.Run(async context =>
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("<html><body>");
|
||||
builder.AppendLine("An error occurred, Status Code: " + WebUtility.HtmlEncode(remainder.ToString().Substring(1)) + "<br>");
|
||||
builder.AppendLine("An error occurred, Status Code: " + WebUtility.HtmlEncode(context.Request.Path.ToString().Substring(1)) + "<br>");
|
||||
var referrer = context.Request.Headers["referer"];
|
||||
if (!string.IsNullOrEmpty(referrer))
|
||||
{
|
||||
builder.AppendLine("<a href=\"" + WebUtility.HtmlEncode(referrer) + "\">Retry " + WebUtility.HtmlEncode(referrer) + "</a><br>");
|
||||
}
|
||||
builder.AppendLine("</body></html>");
|
||||
return context.Response.SendAsync(builder.ToString(), "text/html");
|
||||
await context.Response.SendAsync(builder.ToString(), "text/html");
|
||||
});
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
// Generates the HTML with all status codes.
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("<html><body>");
|
||||
builder.AppendLine("<a href=\"" +
|
||||
WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/\">" +
|
||||
WebUtility.HtmlEncode(context.Request.PathBase.ToString()) + "/missingpage/</a><br>");
|
||||
|
||||
var space = string.Concat(Enumerable.Repeat(" ", 12));
|
||||
builder.AppendFormat("<br><b>{0}{1}{2}</b><br>", "Status Code", space, "Status Code Pages");
|
||||
for (int statusCode = 400; statusCode < 600; statusCode++)
|
||||
{
|
||||
builder.AppendFormat("{0}{1}{2}{3}<br>",
|
||||
statusCode,
|
||||
space + space,
|
||||
string.Format("<a href=\"?statuscode={0}\">[Enabled]</a>{1}", statusCode, space),
|
||||
string.Format("<a href=\"?statuscode={0}&disableStatusCodePages=true\">[Disabled]</a>{1}", statusCode, space));
|
||||
}
|
||||
return next();
|
||||
|
||||
builder.AppendLine("</body></html>");
|
||||
await context.Response.SendAsync(builder.ToString(), "text/html");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
"version": "1.0.0-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Diagnostics": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging.Interfaces": { "version": "1.0.0-*", "type": "build" },
|
||||
"Microsoft.Framework.Runtime.Interfaces": { "version": "1.0.0-*", "type": "build" }
|
||||
"Microsoft.Framework.Logging.Interfaces": "1.0.0-*"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the contract for an exception representing compilation failure.
|
||||
/// </summary>
|
||||
[AssemblyNeutral]
|
||||
public interface ICompilationException
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -2,14 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the contract for a file that fails compilation.
|
||||
/// </summary>
|
||||
[AssemblyNeutral]
|
||||
public interface ICompilationFailure
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the contract for diagnostic messages produced as result of compiling an instance
|
||||
/// of <see cref="ICompilationFailure"/>.
|
||||
/// </summary>
|
||||
[AssemblyNeutral]
|
||||
public interface ICompilationMessage
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -2,11 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface IErrorHandlerFeature
|
||||
{
|
||||
Exception Error { get; }
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Status code pages feature.
|
||||
/// </summary>
|
||||
public interface IStatusCodePagesFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if the status code middleware will handle responses.
|
||||
/// </summary>
|
||||
bool Enabled { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface IStatusCodeReExecuteFeature
|
||||
{
|
||||
string OriginalPathBase { get; set; }
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>83ffb65a-97b1-45aa-bcb8-3f43966bc8a3</ProjectGuid>
|
||||
<RootNamespace>Microsoft.AspNet.Diagnostics.Interfaces</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"description": "ASP.NET 5 diagnostics middleware interfaces.",
|
||||
"compilationOptions": { "warningsAsErrors": true },
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnetcore50": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.0.20-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Diagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Status code pages feature.
|
||||
/// </summary>
|
||||
public class StatusCodePagesFeature : IStatusCodePagesFeature
|
||||
{
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Diagnostics
|
|||
private readonly RequestDelegate _next;
|
||||
private readonly StatusCodePagesOptions _options;
|
||||
|
||||
public StatusCodePagesMiddleware(RequestDelegate next, [NotNull]StatusCodePagesOptions options)
|
||||
public StatusCodePagesMiddleware(RequestDelegate next, StatusCodePagesOptions options)
|
||||
{
|
||||
_next = next;
|
||||
_options = options;
|
||||
|
|
@ -25,8 +25,18 @@ namespace Microsoft.AspNet.Diagnostics
|
|||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var statusCodeFeature = new StatusCodePagesFeature();
|
||||
context.SetFeature<IStatusCodePagesFeature>(statusCodeFeature);
|
||||
|
||||
await _next(context);
|
||||
|
||||
if (!statusCodeFeature.Enabled)
|
||||
{
|
||||
// Check if the feature is still available because other middleware (such as a web API written in MVC) could
|
||||
// have disabled the feature to prevent HTML status code responses from showing up to an API client.
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing if a response body has already been provided.
|
||||
if (context.Response.HeadersSent
|
||||
|| context.Response.StatusCode < 400
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
"version": "1.0.0-*",
|
||||
"description": "ASP.NET 5 Middleware for error handling, error pages, and diagnostics information.",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Diagnostics.Interfaces": "1.0.0-*",
|
||||
"Microsoft.AspNet.RequestContainer": "1.0.0-*",
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||
"Microsoft.Framework.Runtime.Interfaces": { "version": "1.0.0-*", "type": "build" }
|
||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnet50": {},
|
||||
"aspnetcore50": {
|
||||
"dependencies": {
|
||||
"System.Reflection.Extensions": "4.0.0-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue