Remove FiltersWebSite
This commit is contained in:
parent
aba35c673f
commit
ae2d82c748
13
Mvc.sln
13
Mvc.sln
|
|
@ -42,8 +42,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorWebSite", "test\WebSit
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FormatterWebSite", "test\WebSites\FormatterWebSite\FormatterWebSite.csproj", "{62735776-46FF-4170-9392-02E128A69B89}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FiltersWebSite", "test\WebSites\FiltersWebSite\FiltersWebSite.csproj", "{1976AC4A-FEA4-4587-A158-D9F79736D2B6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiExplorerWebSite", "test\WebSites\ApiExplorerWebSite\ApiExplorerWebSite.csproj", "{61061528-071E-424E-965A-07BCC2F02672}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VersioningWebSite", "test\WebSites\VersioningWebSite\VersioningWebSite.csproj", "{C6304029-78C8-4604-99BE-2078DCA1DD36}"
|
||||
|
|
@ -285,16 +283,6 @@ Global
|
|||
{62735776-46FF-4170-9392-02E128A69B89}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{62735776-46FF-4170-9392-02E128A69B89}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{62735776-46FF-4170-9392-02E128A69B89}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{61061528-071E-424E-965A-07BCC2F02672}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{61061528-071E-424E-965A-07BCC2F02672}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{61061528-071E-424E-965A-07BCC2F02672}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -878,7 +866,6 @@ Global
|
|||
{5F945B82-FE5F-425C-956C-8BC2F2020254} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{B07CAF59-11ED-40E3-A5DB-E1178F84FA78} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{62735776-46FF-4170-9392-02E128A69B89} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{1976AC4A-FEA4-4587-A158-D9F79736D2B6} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{61061528-071E-424E-965A-07BCC2F02672} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{C6304029-78C8-4604-99BE-2078DCA1DD36} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{6DB9B8D0-80F7-4E70-BBB0-0B4C04D79A47} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
|
|
|
|||
|
|
@ -473,24 +473,6 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("true", response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AlwaysRunResultFilters_CanRunWhenResourceFiltersShortCircuit()
|
||||
{
|
||||
// Arrange
|
||||
var url = "Filters/AlwaysRunResultFiltersCanRunWhenResourceFilterShortCircuit";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url)
|
||||
{
|
||||
Content = new StringContent("Test", Encoding.UTF8, "application/json"),
|
||||
};
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(422, (int)response.StatusCode);
|
||||
Assert.Equal("Can't process this!", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApplicationAssemblyPartIsListedAsFirstAssembly()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,113 +1,28 @@
|
|||
// 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.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FiltersWebSite;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters.Xml;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class FiltersTest : IClassFixture<MvcTestFixture<FiltersWebSite.Startup>>
|
||||
public class FiltersTest : IClassFixture<MvcTestFixture<BasicWebSite.Startup>>
|
||||
{
|
||||
public FiltersTest(MvcTestFixture<FiltersWebSite.Startup> fixture)
|
||||
public FiltersTest(MvcTestFixture<BasicWebSite.Startup> fixture)
|
||||
{
|
||||
Client = fixture.Client;
|
||||
}
|
||||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
// A controller can only be an action filter and result filter, so we don't have entries
|
||||
// for the other filter types implemented by the controller.
|
||||
[Fact]
|
||||
public async Task ListAllFilters()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new string[]
|
||||
{
|
||||
"Global Authorization Filter - OnAuthorization",
|
||||
"On Controller Authorization Filter - OnAuthorization",
|
||||
"Authorize Filter On Action - OnAuthorization",
|
||||
"Global Resource Filter - OnResourceExecuting",
|
||||
"Controller Resource Filter - OnResourceExecuting",
|
||||
"Action Resource Filter - OnResourceExecuting",
|
||||
"Controller Override - OnActionExecuting",
|
||||
"Global Action Filter - OnActionExecuting",
|
||||
"On Controller Action Filter - OnActionExecuting",
|
||||
"On Action Action Filter - OnActionExecuting",
|
||||
"Executing Action",
|
||||
"On Action Action Filter - OnActionExecuted",
|
||||
"On Controller Action Filter - OnActionExecuted",
|
||||
"Global Action Filter - OnActionExecuted",
|
||||
"Controller Override - OnActionExecuted",
|
||||
"Controller Override - OnResultExecuting",
|
||||
"Global Result Filter - OnResultExecuted",
|
||||
"On Controller Result Filter - OnResultExecuting",
|
||||
"On Action Result Filter - OnResultExecuting",
|
||||
"On Action Result Filter - OnResultExecuted",
|
||||
"On Controller Result Filter - OnResultExecuted",
|
||||
"Global Result Filter - OnResultExecuted",
|
||||
"Controller Override - OnResultExecuted",
|
||||
"Action Resource Filter - OnResourceExecuted",
|
||||
"Controller Resource Filter - OnResourceExecuted",
|
||||
"Global Resource Filter - OnResourceExecuted",
|
||||
};
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync("http://localhost/Products/GetPrice/5");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var filters = response.Headers.GetValues("filters").ToArray();
|
||||
|
||||
var i = 0;
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
Assert.Equal(expected[i++], filter);
|
||||
}
|
||||
|
||||
Assert.Equal(expected.Length, filters.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AnonymousUsersAreBlocked()
|
||||
public async Task CanAuthorize_UsersByRole()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Anonymous/GetHelloWorld");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AllowsAnonymousUsersToAccessController()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/RandomNumber/GetRandomNumber");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("4", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[InlineData("AdminRole")]
|
||||
[InlineData("InteractiveUsers")]
|
||||
[InlineData("ApiManagers")]
|
||||
public async Task CanAuthorize(string testAction)
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/AuthorizeUser/" + testAction);
|
||||
var response = await Client.GetAsync("AuthorizeUser/AdminRole");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
@ -115,10 +30,10 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AllowAnonymousOverridesAuthorize()
|
||||
public async Task CanAuthorize_UsersByPolicyRequirements()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/AuthorizeUser/AlwaysCanCallAllowAnonymous");
|
||||
var response = await Client.GetAsync("AuthorizeUser/ApiManagers");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
@ -129,414 +44,12 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
public async Task ImpossiblePolicyFailsAuthorize()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/AuthorizeUser/Impossible");
|
||||
var response = await Client.GetAsync("AuthorizeUser/Impossible");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ServiceFilterUsesRegisteredServicesAsFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/RandomNumber/GetRandomNumber");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("4", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ServiceFilterThrowsIfServiceIsNotRegistered()
|
||||
{
|
||||
// Arrange
|
||||
var url = "http://localhost/RandomNumber/GetAuthorizedRandomNumber";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypeFilterInitializesArguments()
|
||||
{
|
||||
// Arrange
|
||||
var url = "http://localhost/RandomNumber/GetModifiedRandomNumber?randomNumber=10";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("22", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypeFilterThrowsIfServicesAreNotRegistered()
|
||||
{
|
||||
// Arrange
|
||||
var url = "http://localhost/RandomNumber/GetHalfOfModifiedRandomNumber?randomNumber=3";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidOperationException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ActionFilterOverridesActionExecuted()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/XmlSerializer/GetDummyClass?sampleInput=10");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
XmlAssert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResultFilterOverridesOnResultExecuting()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/DummyClass/GetDummyClass");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
XmlAssert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>120</SampleInt></DummyClass>",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResultFilterOverridesOnResultExecuted()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/DummyClass/GetEmptyActionResult");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var result = response.Headers.GetValues("OnResultExecuted");
|
||||
Assert.Equal(new string[] { "ResultExecutedSuccessfully" }, result);
|
||||
}
|
||||
|
||||
// Verifies result filter is executed after action filter.
|
||||
[Fact]
|
||||
public async Task OrderOfExecutionOfFilters_WhenOrderAttribute_IsNotMentioned()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/GetSampleString");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Result filter, Action Filter - OnActionExecuted, From Controller",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action filter handles the exception thrown in the action.
|
||||
// Verifies if Result filter is executed after that.
|
||||
[Fact]
|
||||
public async Task ExceptionsHandledInActionFilters_WillNotShortCircuitResultFilters()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowExceptionAndHandleInActionFilter");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Result filter, Hi from Action Filter", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Exception filter present on the Action handles the exception, followed by Global Exception filter.
|
||||
// Verifies that Result filter is skipped.
|
||||
[Fact]
|
||||
public async Task ExceptionFilter_OnAction_ShortCircuitsResultFilters()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowExcpetion");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"GlobalExceptionFilter.OnException, Action Exception Filter",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// No Exception filter is present on Action, Controller.
|
||||
// Verifies if Global exception filter handles the exception.
|
||||
[Fact]
|
||||
public async Task GlobalExceptionFilter_HandlesAnException()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Exception/GetError?error=RandomError");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("GlobalExceptionFilter.OnException", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action, Controller, and a Global Exception filters are present.
|
||||
// Verifies they are executed in the above mentioned order.
|
||||
[Fact]
|
||||
public async Task ExceptionFilter_Scope()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ExceptionOrder/GetError");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"GlobalExceptionFilter.OnException, " +
|
||||
"ControllerExceptionFilter.OnException, " +
|
||||
"Action Exception Filter",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action, Controller have an action filter.
|
||||
// Verifies they are executed in the mentioned order.
|
||||
[Fact]
|
||||
public async Task ActionFilter_Scope()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ActionFilter/GetHelloWorld");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"Controller override - OnActionExecuted, " +
|
||||
"GlobalActionFilter.OnActionExecuted, " +
|
||||
"Controller Action filter - OnActionExecuted, " +
|
||||
"Action Filter - OnActionExecuted, " +
|
||||
"Hello World, " + // Return value from Action
|
||||
"Action Filter - OnActionExecuting, " +
|
||||
"Controller Action filter - OnActionExecuting, " +
|
||||
"GlobalActionFilter.OnActionExecuting, " +
|
||||
"Controller override - OnActionExecuting",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action, Controller have an result filter.
|
||||
// Verifies that Controller Result filter is executed before Action filter.
|
||||
[Fact]
|
||||
public async Task ResultFilter_Scope()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ResultFilter/GetHelloWorld");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"Result filter, " +
|
||||
"Controller Result filter, " +
|
||||
"GlobalResultFilter.OnResultExecuting, " +
|
||||
"Controller Override, " +
|
||||
"Hello World", // Return value from Action
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has multiple TypeFilters with Order.
|
||||
// Verifies if the filters are executed in the mentioned order.
|
||||
[Fact]
|
||||
public async Task FiltersWithOrder()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/RandomNumber/GetOrderedRandomNumber");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("88", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has multiple action filters with Order.
|
||||
// Verifies they are executed in the mentioned order.
|
||||
[Fact]
|
||||
public async Task ActionFiltersWithOrder()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ActionFilterOrder");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"Action Filter - OnActionExecuted, " +
|
||||
"Controller Action filter - OnActionExecuted, " +
|
||||
"Hello World", // Return value from Action
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has multiple result filters with Order.
|
||||
// Verifies they are executed in the mentioned order.
|
||||
[Fact]
|
||||
public async Task ResultFiltersWithOrder()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ResultFilterOrder");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(
|
||||
"Result filter, Controller Result filter, Hello World",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has an action filter which sets the Result.
|
||||
// Verifies the Action was not executed
|
||||
[Fact]
|
||||
public async Task ActionFilterShortCircuitsAction()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/DummyClass/ActionNeverGetsExecuted");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("The Action was never executed", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has an Result filter which sets the Result.
|
||||
// Verifies ObjectResult was not executed.
|
||||
[Fact]
|
||||
public async Task ResultFilterShortCircuitsResult()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/DummyClass/ResultNeverGetsExecuted");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("The Result was never executed", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Action has two Exception filters.
|
||||
// Verifies that the second Exception Filter was not executed.
|
||||
[Fact]
|
||||
public async Task ExceptionFilterShortCircuitsAnotherExceptionFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowRandomExcpetion");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Result Filter throws.
|
||||
// Exception Filters don't get a chance to handle this.
|
||||
[Fact]
|
||||
public async Task ThrowingFilters_ResultFilter_NotHandledByGlobalExceptionFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowingResultFilter");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidProgramException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
// Action Filter throws.
|
||||
// Verifies the Global Exception Filter handles it.
|
||||
[Fact]
|
||||
public async Task ThrowingFilters_ActionFilter_HandledByGlobalExceptionFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowingActionFilter");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("GlobalExceptionFilter.OnException", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
// Authorization Filter throws.
|
||||
// Exception Filters don't get a chance to handle this.
|
||||
[Fact]
|
||||
public async Task ThrowingFilters_AuthFilter_NotHandledByGlobalExceptionFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowingAuthorizationFilter");
|
||||
|
||||
// Assert
|
||||
var exception = response.GetServerException();
|
||||
Assert.Equal(typeof(InvalidProgramException).FullName, exception.ExceptionType);
|
||||
}
|
||||
|
||||
// Exception Filter throws.
|
||||
// Verifies the thrown exception is ignored.
|
||||
[Fact]
|
||||
public async Task ThrowingExceptionFilter_ExceptionFilter_NotHandledByGlobalExceptionFilter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Home/ThrowingExceptionFilter");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Throwing Exception Filter", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResourceFilter_ShortCircuitsUsingObjectResult_UsesOptions()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{ sampleInt: 10 }";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/ResourceFilter/Post");
|
||||
request.Content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
// Uses formatters from options.
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
// Notice this has been formatted using StringOutputFormatter and not JsonOutputFormatter.
|
||||
Assert.Equal("someValue", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResourceFilter_ShortCircuitsUsingObjectResult_WithJsonFormatter_ReturnsResponse()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{ sampleInt: 10 }";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/ResourceFilter/Get");
|
||||
request.Content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("\"someValue\"", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResourceFilter_RemovingValueProviderFactoriesForAnAction_DoesNotAffectOtherActions()
|
||||
{
|
||||
// Request to an action which does NOT expect form value model binding
|
||||
// Arrange & Act
|
||||
var response = await Client.PostAsync(
|
||||
"http://localhost/ResourceFilter/FormValueModelBinding_Disabled",
|
||||
new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("SampleInt", "10") }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("text/plain", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("Data:0", await response.Content.ReadAsStringAsync());
|
||||
|
||||
// Request to an action which expects form value model binding
|
||||
// Arrange & Act
|
||||
response = await Client.PostAsync(
|
||||
"http://localhost/ResourceFilter/FormValueModelBinding_Enabled",
|
||||
new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("SampleInt", "10") }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("text/plain", response.Content.Headers.ContentType.MediaType);
|
||||
Assert.Equal("Data:10", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("en-US", "en-US")]
|
||||
[InlineData("fr", "fr")]
|
||||
|
|
@ -546,7 +59,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
string expected)
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync($"http://localhost/{culture}/MiddlewareFilterTest/CultureFromRouteData");
|
||||
var response = await Client.GetAsync($"{culture}/Filters/MiddlewareFilterTest");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
@ -554,5 +67,51 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
$"CurrentCulture:{expected},CurrentUICulture:{expected}",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AlwaysRunResultFilters_CanRunWhenResourceFiltersShortCircuit()
|
||||
{
|
||||
// Arrange
|
||||
var url = "Filters/AlwaysRunResultFiltersCanRunWhenResourceFilterShortCircuit";
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url)
|
||||
{
|
||||
Content = new StringContent("Test", Encoding.UTF8, "application/json"),
|
||||
};
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(422, (int)response.StatusCode);
|
||||
Assert.Equal("Can't process this!", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FiltersCanBeDeclaredGlobally()
|
||||
{
|
||||
// Arrange
|
||||
var url = "Filters/TraceResult";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetStringAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("This value was set by TraceResourceFilter", response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ServiceFiltersWork()
|
||||
{
|
||||
// Arrange
|
||||
var url = "Filters/ServiceFilterTest";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Service filter content", await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal(new[] { "True" }, response.Headers.GetValues("X-ServiceActionFilter"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +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 System.Net;
|
||||
using System.Net.Http;
|
||||
using FiltersWebSite;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public static class HttpResponseMessageExceptions
|
||||
{
|
||||
public static ExceptionInfo GetServerException(this HttpResponseMessage response)
|
||||
{
|
||||
if (response.StatusCode != HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new AssertActualExpectedException(
|
||||
HttpStatusCode.InternalServerError,
|
||||
response.StatusCode,
|
||||
"A server-side exception should be returned as a 500.");
|
||||
}
|
||||
|
||||
var headers = response.Headers;
|
||||
|
||||
IEnumerable<string> exceptionMessageHeader;
|
||||
IEnumerable<string> exceptionTypeHeader;
|
||||
if (!headers.TryGetValues(ErrorReporterMiddleware.ExceptionMessageHeader, out exceptionMessageHeader))
|
||||
{
|
||||
throw new XunitException(
|
||||
"No value for the '" + ErrorReporterMiddleware.ExceptionMessageHeader + "' header.");
|
||||
}
|
||||
|
||||
if (!headers.TryGetValues(ErrorReporterMiddleware.ExceptionTypeHeader, out exceptionTypeHeader))
|
||||
{
|
||||
throw new XunitException(
|
||||
"No value for the '" + ErrorReporterMiddleware.ExceptionTypeHeader + "' header.");
|
||||
}
|
||||
|
||||
return new ExceptionInfo()
|
||||
{
|
||||
ExceptionMessage = Assert.Single(exceptionMessageHeader),
|
||||
ExceptionType = Assert.Single(exceptionTypeHeader),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@
|
|||
<ProjectReference Include="..\WebSites\CorsWebSite\CorsWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\ErrorPageMiddlewareWebSite\ErrorPageMiddlewareWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\FilesWebSite\FilesWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\FiltersWebSite\FiltersWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\FormatterWebSite\FormatterWebSite.csproj" />
|
||||
<ProjectReference Include="..\WebSites\HtmlGenerationWebSite\HtmlGenerationWebSite.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Mvc.TestCommon\Microsoft.AspNetCore.Mvc.TestCommon.csproj" />
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class BasicAuthenticationHandler : AuthenticationHandler<BasicOptions>
|
||||
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
public BasicAuthenticationHandler(IOptionsMonitor<BasicOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
|
||||
public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{ }
|
||||
|
||||
|
|
@ -22,15 +22,18 @@ namespace FiltersWebSite
|
|||
{
|
||||
var principal = new ClaimsPrincipal();
|
||||
principal.AddIdentity(new ClaimsIdentity(
|
||||
new Claim[] {
|
||||
new Claim("Permission", "CanViewPage"),
|
||||
new[]
|
||||
{
|
||||
new Claim("Manager", "yes"),
|
||||
new Claim(ClaimTypes.Role, "Administrator"),
|
||||
new Claim(ClaimTypes.NameIdentifier, "John")
|
||||
},
|
||||
Scheme.Name));
|
||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal,
|
||||
new AuthenticationProperties(), Scheme.Name)));
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(
|
||||
principal,
|
||||
new AuthenticationProperties(),
|
||||
Scheme.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc.Formatters.Xml\Microsoft.AspNetCore.Mvc.Formatters.Xml.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="$(MicrosoftAspNetCoreAuthenticationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Localization.Routing" Version="$(MicrosoftAspNetCoreLocalizationRoutingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Session" Version="$(MicrosoftAspNetCoreSessionPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// 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.Security.Claims;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BasicWebSite
|
||||
{
|
||||
internal static class ConfigureAuthPoliciesExtensions
|
||||
{
|
||||
public static void ConfigureBaseWebSiteAuthPolicies(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
// This policy cannot succeed since the claim is never added
|
||||
options.AddPolicy("Impossible", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Api");
|
||||
policy.RequireClaim("Never");
|
||||
});
|
||||
options.AddPolicy("Api", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Api");
|
||||
policy.RequireClaim(ClaimTypes.NameIdentifier);
|
||||
});
|
||||
options.AddPolicy("Api-Manager", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Api");
|
||||
policy.Requirements.Add(Operations.Edit);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
[Authorize("Api")]
|
||||
public class AuthorizeUserController : Controller
|
||||
|
|
@ -21,23 +22,10 @@ namespace FiltersWebSite
|
|||
return "Hello World!";
|
||||
}
|
||||
|
||||
[Authorize("Interactive")]
|
||||
public string InteractiveUsers()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
[Authorize("Impossible")]
|
||||
[AllowAnonymous]
|
||||
public string AlwaysCanCallAllowAnonymous()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
[Authorize("Impossible")]
|
||||
public string Impossible()
|
||||
{
|
||||
return "Hello World!";
|
||||
throw new Exception("Shouldn't be invoked.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,10 @@
|
|||
// 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.Threading.Tasks;
|
||||
using System.Globalization;
|
||||
using BasicWebSite.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
{
|
||||
|
|
@ -18,5 +16,18 @@ namespace BasicWebSite.Controllers
|
|||
[UnprocessableResultFilter]
|
||||
public IActionResult AlwaysRunResultFiltersCanRunWhenResourceFilterShortCircuit([FromBody] Product product) =>
|
||||
throw new Exception("Shouldn't be executed");
|
||||
|
||||
[ServiceFilter(typeof(ServiceActionFilter))]
|
||||
public IActionResult ServiceFilterTest() => Content("Service filter content");
|
||||
|
||||
[TraceResultOutputFilter]
|
||||
public IActionResult TraceResult() => new EmptyResult();
|
||||
|
||||
[Route("{culture}/[controller]/[action]")]
|
||||
[MiddlewareFilter(typeof(LocalizationPipeline))]
|
||||
public IActionResult MiddlewareFilterTest()
|
||||
{
|
||||
return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// 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.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class ServiceActionFilter : IActionFilter
|
||||
{
|
||||
private readonly ILogger<ServiceActionFilter> _logger;
|
||||
|
||||
public ServiceActionFilter(ILogger<ServiceActionFilter> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
_logger.LogInformation($"Executing {nameof(ServiceActionFilter)}.");
|
||||
context.HttpContext.Response.Headers["X-ServiceActionFilter"] = "True";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
// 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.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class ShortCircuitResultFilter : ResultFilterAttribute
|
||||
public class TraceResultOutputFilter : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
context.Result = new ContentResult
|
||||
{
|
||||
Content = "The Result was never executed"
|
||||
};
|
||||
var trace = context.HttpContext.Items[nameof(TraceResourceFilter)];
|
||||
context.Result = new ObjectResult(trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// 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.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class TraceResourceFilter : IResourceFilter
|
||||
{
|
||||
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Items[nameof(TraceResourceFilter)] = $"This value was set by {nameof(TraceResourceFilter)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.Globalization;
|
||||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Localization;
|
|||
using Microsoft.AspNetCore.Mvc.Localization;
|
||||
using Microsoft.AspNetCore.Localization.Routing;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class LocalizationPipeline
|
||||
{
|
||||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public class ManagerHandler : AuthorizationHandler<OperationAuthorizationRequirement>
|
||||
{
|
||||
|
|
@ -3,12 +3,10 @@
|
|||
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
|
||||
namespace FiltersWebSite
|
||||
namespace BasicWebSite
|
||||
{
|
||||
public static class Operations
|
||||
{
|
||||
public static OperationAuthorizationRequirement Edit = new OperationAuthorizationRequirement { Name = "Edit" };
|
||||
public static OperationAuthorizationRequirement Create = new OperationAuthorizationRequirement { Name = "Create" };
|
||||
public static OperationAuthorizationRequirement Delete = new OperationAuthorizationRequirement { Name = "Delete" };
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
|
|
@ -14,8 +17,17 @@ namespace BasicWebSite
|
|||
// Set up application services
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication()
|
||||
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("Api", _ => { });
|
||||
services.AddTransient<IAuthorizationHandler, ManagerHandler>();
|
||||
|
||||
services
|
||||
.AddMvc(options => options.Conventions.Add(new ApplicationDescription("This is a basic website.")))
|
||||
.AddMvc(options =>
|
||||
{
|
||||
options.Conventions.Add(new ApplicationDescription("This is a basic website."));
|
||||
// Filter that records a value in HttpContext.Items
|
||||
options.Filters.Add(new TraceResourceFilter());
|
||||
})
|
||||
.AddXmlDataContractSerializerFormatters();
|
||||
|
||||
services.Configure<ApiBehaviorOptions>(options =>
|
||||
|
|
@ -34,11 +46,16 @@ namespace BasicWebSite
|
|||
};
|
||||
});
|
||||
|
||||
services.ConfigureBaseWebSiteAuthPolicies();
|
||||
|
||||
services.AddTransient<IAuthorizationHandler, ManagerHandler>();
|
||||
|
||||
services.AddLogging();
|
||||
services.AddSingleton<IActionDescriptorProvider, ActionDescriptorCreationCounter>();
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddSingleton<ContactsRepository>();
|
||||
services.AddScoped<RequestIdService>();
|
||||
services.AddTransient<ServiceActionFilter>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace BasicWebSite
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
services.ConfigureBaseWebSiteAuthPolicies();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace BasicWebSite
|
|||
{
|
||||
o.CheckConsentNeeded = httpContext => true;
|
||||
});
|
||||
|
||||
services.ConfigureBaseWebSiteAuthPolicies();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ namespace BasicWebSite
|
|||
.AddMvc()
|
||||
.AddSessionStateTempDataProvider();
|
||||
services.AddSession();
|
||||
|
||||
services.ConfigureBaseWebSiteAuthPolicies();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -1,16 +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;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class BasicOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +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.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[ControllerActionFilter]
|
||||
public class ActionFilterController : Controller
|
||||
{
|
||||
[ChangeContentActionFilter]
|
||||
public IActionResult GetHelloWorld(IList<ContentResult> fromGlobalActionFilter)
|
||||
{
|
||||
// Should have got content from Global Action Filter followed by Controller Override.
|
||||
if (fromGlobalActionFilter != null)
|
||||
{
|
||||
ContentResult combinedResult = null;
|
||||
var resultsFromActionFilters = fromGlobalActionFilter as List<ContentResult>;
|
||||
foreach (var result in resultsFromActionFilters)
|
||||
{
|
||||
combinedResult = Helpers.GetContentResult(combinedResult, result.Content);
|
||||
}
|
||||
|
||||
return Helpers.GetContentResult(combinedResult, "Hello World");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
object obj;
|
||||
List<ContentResult> filters;
|
||||
|
||||
if (context.ActionArguments.TryGetValue("fromGlobalActionFilter", out obj))
|
||||
{
|
||||
filters = (List<ContentResult>)obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
filters = new List<ContentResult>();
|
||||
context.ActionArguments.Add("fromGlobalActionFilter", filters);
|
||||
}
|
||||
|
||||
filters.Add(Helpers.GetContentResult(context.Result, "Controller override - OnActionExecuting"));
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Controller override - OnActionExecuted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[BlockAnonymous]
|
||||
public class AnonymousController : Controller
|
||||
{
|
||||
public string GetHelloWorld()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +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.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class DummyClassController : Controller
|
||||
{
|
||||
[ModifyResultsFilter]
|
||||
public DummyClass GetDummyClass()
|
||||
{
|
||||
return new DummyClass()
|
||||
{
|
||||
SampleInt = 10
|
||||
};
|
||||
}
|
||||
|
||||
[AddHeader]
|
||||
public IActionResult GetEmptyActionResult()
|
||||
{
|
||||
return new TestActionResult();
|
||||
}
|
||||
|
||||
[ShortCircuitActionFilter]
|
||||
public string ActionNeverGetsExecuted()
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
[ShortCircuitResultFilter]
|
||||
public IActionResult ResultNeverGetsExecuted()
|
||||
{
|
||||
return new ObjectResult("Returned in Object Result");
|
||||
}
|
||||
}
|
||||
|
||||
public class TestActionResult : IActionResult
|
||||
{
|
||||
public Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ExceptionController : Controller
|
||||
{
|
||||
public string GetError(string error)
|
||||
{
|
||||
throw new InvalidOperationException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +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;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[ControllerExceptionFilter]
|
||||
public class ExceptionOrderController : Controller
|
||||
{
|
||||
[HandleInvalidOperationExceptionFilter]
|
||||
public string GetError(string error)
|
||||
{
|
||||
throw new InvalidOperationException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +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;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite.Controllers
|
||||
{
|
||||
public class HomeController
|
||||
{
|
||||
[ChangeContentActionFilter]
|
||||
[ChangeContentResultFilter]
|
||||
public IActionResult GetSampleString()
|
||||
{
|
||||
return new ContentResult()
|
||||
{
|
||||
Content = "From Controller"
|
||||
};
|
||||
}
|
||||
|
||||
[ThrowingResultFilter]
|
||||
[HandleInvalidOperationExceptionFilter]
|
||||
public IActionResult ThrowExcpetion()
|
||||
{
|
||||
throw new InvalidOperationException("Controller threw.");
|
||||
}
|
||||
|
||||
[HandleExceptionActionFilter]
|
||||
[ChangeContentResultFilter]
|
||||
public IActionResult ThrowExceptionAndHandleInActionFilter()
|
||||
{
|
||||
throw new InvalidOperationException("Controller threw.");
|
||||
}
|
||||
|
||||
[ControllerActionFilter(Order = 2)]
|
||||
[ChangeContentActionFilter(Order = 1)]
|
||||
public IActionResult ActionFilterOrder()
|
||||
{
|
||||
return new ContentResult()
|
||||
{
|
||||
Content = "Hello World"
|
||||
};
|
||||
}
|
||||
|
||||
[ControllerResultFilter(Order = 1)]
|
||||
[ChangeContentResultFilter(Order = 2)]
|
||||
public IActionResult ResultFilterOrder()
|
||||
{
|
||||
return new ContentResult()
|
||||
{
|
||||
Content = "Hello World"
|
||||
};
|
||||
}
|
||||
|
||||
[ThrowingResultFilter]
|
||||
public string ThrowingResultFilter()
|
||||
{
|
||||
return "Throwing Result Filter";
|
||||
}
|
||||
|
||||
[ThrowingActionFilter]
|
||||
public string ThrowingActionFilter()
|
||||
{
|
||||
return "Throwing Action Filter";
|
||||
}
|
||||
|
||||
[ThrowingExceptionFilter]
|
||||
public string ThrowingExceptionFilter()
|
||||
{
|
||||
return "Throwing Exception Filter";
|
||||
}
|
||||
|
||||
[ThrowingAuthorizationFilter]
|
||||
public string ThrowingAuthorizationFilter()
|
||||
{
|
||||
return "Throwing Authorization Filter";
|
||||
}
|
||||
|
||||
[HandleInvalidOperationExceptionFilter]
|
||||
[ShortCircuitExceptionFilter(Order=12)]
|
||||
public IActionResult ThrowRandomExcpetion()
|
||||
{
|
||||
throw new InvalidOperationException("Controller threw.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +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.Globalization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class MiddlewareFilterTestController : Controller
|
||||
{
|
||||
[Route("{culture}/[controller]/[action]")]
|
||||
[MiddlewareFilter(typeof(LocalizationPipeline))]
|
||||
public IActionResult CultureFromRouteData()
|
||||
{
|
||||
return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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 Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
// This controller will list the filters that are configured for each action in a header.
|
||||
// This exercises the merging of filters with the global filters collection.
|
||||
[ControllerResultFilter]
|
||||
[ControllerActionFilter]
|
||||
[ControllerAuthorizationFilter]
|
||||
[TracingResourceFilter("Controller Resource Filter")]
|
||||
public class ProductsController : Controller, IResultFilter
|
||||
{
|
||||
[PassThroughResultFilter]
|
||||
[PassThroughActionFilter]
|
||||
[AuthorizeUser]
|
||||
[TracingResourceFilter("Action Resource Filter")]
|
||||
public IActionResult GetPrice(int id)
|
||||
{
|
||||
Response.Headers.Append("filters", "Executing Action");
|
||||
// This skips the ExecuteResultAsync in ActionResult. Thus result is not set.
|
||||
// Hence we can see all the OnResultExecuted functions in the response.
|
||||
return new TestActionResult();
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "Controller Override - OnActionExecuting");
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "Controller Override - OnActionExecuted");
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "Controller Override - OnResultExecuted");
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "Controller Override - OnResultExecuting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[HandleInvalidOperationExceptionFilter]
|
||||
public class RandomNumberController : Controller
|
||||
{
|
||||
[ServiceFilter(typeof(RandomNumberFilter))]
|
||||
public int GetRandomNumber()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
[ServiceFilter(typeof(AuthorizeUserAttribute))]
|
||||
public int GetAuthorizedRandomNumber()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(RandomNumberProvider))]
|
||||
public int GetModifiedRandomNumber(int randomNumber)
|
||||
{
|
||||
return randomNumber / 2;
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(ModifiedRandomNumberProvider))]
|
||||
public int GetHalfOfModifiedRandomNumber(int randomNumber)
|
||||
{
|
||||
return randomNumber / 2;
|
||||
}
|
||||
|
||||
[TypeFilter(typeof(RandomNumberModifier), Order = 2)]
|
||||
[TypeFilter(typeof(RandomNumberProvider), Order = 1)]
|
||||
public int GetOrderedRandomNumber(int randomNumber)
|
||||
{
|
||||
return randomNumber;
|
||||
}
|
||||
|
||||
public string ThrowException()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +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;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FiltersWebSite.Controllers
|
||||
{
|
||||
[Route("ResourceFilter/[action]")]
|
||||
public class ResourceFilterController : Controller
|
||||
{
|
||||
[HttpPost]
|
||||
[ShortCircuitWithFormatter]
|
||||
public string Get()
|
||||
{
|
||||
return "NeverGetsExecuted";
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ShortCircuit]
|
||||
public string Post()
|
||||
{
|
||||
return "NeverGetsExecuted";
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult FormValueModelBinding_Enabled(DummyClass dc)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
return Ok("Data:" + dc?.SampleInt);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[DisableFormValueModelBinding]
|
||||
public IActionResult FormValueModelBinding_Disabled(DummyClass dc)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
return Ok("Data:" + dc?.SampleInt);
|
||||
}
|
||||
|
||||
private class ShortCircuitWithFormatterAttribute : Attribute, IResourceFilter
|
||||
{
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
var mvcOptions = context.HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>();
|
||||
var formatter = mvcOptions.Value.OutputFormatters.OfType<JsonOutputFormatter>().First();
|
||||
var result = new ObjectResult("someValue");
|
||||
result.Formatters.Add(formatter);
|
||||
|
||||
context.Result = result;
|
||||
}
|
||||
}
|
||||
|
||||
private class ShortCircuitAttribute : Attribute, IResourceFilter
|
||||
{
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
// ShortCircuit.
|
||||
context.Result = new ObjectResult("someValue");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[ControllerResultFilter]
|
||||
public class ResultFilterController : Controller, IResultFilter
|
||||
{
|
||||
[ChangeContentResultFilter]
|
||||
public IActionResult GetHelloWorld()
|
||||
{
|
||||
return Helpers.GetContentResult(null, "Hello World");
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Controller Override");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[SerializationActionFilter]
|
||||
public class XmlSerializerController : Controller
|
||||
{
|
||||
public DummyClass GetDummyClass(int sampleInput)
|
||||
{
|
||||
return new DummyClass { SampleInt = sampleInput };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
/// <summary>
|
||||
/// A middleware that reports errors via header values. Useful for tests that want to verify
|
||||
/// an exception that goes unhandled by the MVC part of the stack.
|
||||
/// </summary>
|
||||
public class ErrorReporterMiddleware
|
||||
{
|
||||
public static readonly string ExceptionMessageHeader = "ExceptionMessage";
|
||||
public static readonly string ExceptionTypeHeader = "ExceptionType";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public ErrorReporterMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (context.Response.HasStarted)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
|
||||
var escapedMessage = exception.Message.Replace('\r', '_').Replace('\n', '_');
|
||||
|
||||
context.Response.Headers.Add(ExceptionTypeHeader, new string[] { exception.GetType().FullName });
|
||||
context.Response.Headers.Add(ExceptionMessageHeader, new string[] { escapedMessage });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class AddHeaderAttribute : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add(
|
||||
"OnResultExecuted", new string[] { "ResultExecutedSuccessfully" });
|
||||
|
||||
base.OnResultExecuted(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +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;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class AuthorizeUserAttribute : Attribute, IAuthorizationFilter
|
||||
{
|
||||
public virtual void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Authorize Filter On Action - OnAuthorization");
|
||||
}
|
||||
|
||||
context.HttpContext.User = new ClaimsPrincipal(
|
||||
new ClaimsIdentity(
|
||||
new Claim[] {
|
||||
new Claim("Permission", "CanViewPage"),
|
||||
new Claim(ClaimTypes.Role, "Administrator"),
|
||||
new Claim(ClaimTypes.NameIdentifier, "John")},
|
||||
"Basic"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +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;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class BlockAnonymous : Attribute, IAuthorizationFilter
|
||||
{
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
if (!HasAllowAnonymous(context))
|
||||
{
|
||||
var user = context.HttpContext.User;
|
||||
var userIsAnonymous =
|
||||
user == null ||
|
||||
user.Identity == null ||
|
||||
!user.Identity.IsAuthenticated;
|
||||
|
||||
if (userIsAnonymous)
|
||||
{
|
||||
context.Result = new UnauthorizedResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasAllowAnonymous(AuthorizationFilterContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
return context.Filters.Any(item => item is IAllowAnonymousFilter);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +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.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ChangeContentActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Action Filter - OnActionExecuted");
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ActionFilterController).GetMethod(nameof(ActionFilterController.GetHelloWorld)))
|
||||
{
|
||||
(context.ActionArguments["fromGlobalActionFilter"] as List<ContentResult>).
|
||||
Add(Helpers.GetContentResult(context.Result, "Action Filter - OnActionExecuting"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ChangeContentResultFilter : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Result filter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +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.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ControllerActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Controller Action Filter - OnActionExecuted");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Controller Action filter - OnActionExecuted");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Controller Action Filter - OnActionExecuting");
|
||||
}
|
||||
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ActionFilterController).GetMethod(nameof(ActionFilterController.GetHelloWorld)))
|
||||
{
|
||||
(context.ActionArguments["fromGlobalActionFilter"] as List<ContentResult>)
|
||||
.Add(Helpers.GetContentResult(context.Result, "Controller Action filter - OnActionExecuting"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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 Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ControllerAuthorizationFilter : AuthorizeUserAttribute
|
||||
{
|
||||
public override void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "On Controller Authorization Filter - OnAuthorization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ControllerExceptionFilter : ExceptionFilterAttribute
|
||||
{
|
||||
public override void OnException(ExceptionContext context)
|
||||
{
|
||||
if (context.Exception.GetType() == typeof(InvalidOperationException))
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "ControllerExceptionFilter.OnException");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +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.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ControllerResultFilter : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Controller Result Filter - OnResultExecuting");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Controller Result filter");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Controller Result Filter - OnResultExecuted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +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;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
|
||||
{
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
var formValueProviderFactory = context.ValueProviderFactories
|
||||
.OfType<FormValueProviderFactory>()
|
||||
.FirstOrDefault();
|
||||
if (formValueProviderFactory != null)
|
||||
{
|
||||
context.ValueProviderFactories.Remove(formValueProviderFactory);
|
||||
}
|
||||
|
||||
var jqueryFormValueProviderFactory = context.ValueProviderFactories
|
||||
.OfType<JQueryFormValueProviderFactory>()
|
||||
.FirstOrDefault();
|
||||
if (jqueryFormValueProviderFactory != null)
|
||||
{
|
||||
context.ValueProviderFactories.Remove(jqueryFormValueProviderFactory);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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 System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class GlobalActionFilter : IActionFilter
|
||||
{
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ActionFilterController).GetMethod(nameof(ActionFilterController.GetHelloWorld)))
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "GlobalActionFilter.OnActionExecuted");
|
||||
}
|
||||
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Global Action Filter - OnActionExecuted");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ActionFilterController).GetMethod(nameof(ActionFilterController.GetHelloWorld)))
|
||||
{
|
||||
(context.ActionArguments["fromGlobalActionFilter"] as List<ContentResult>)
|
||||
.Add(Helpers.GetContentResult(null, "GlobalActionFilter.OnActionExecuting"));
|
||||
}
|
||||
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Global Action Filter - OnActionExecuting");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +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;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class GlobalAuthorizationFilter : Attribute, IAuthorizationFilter
|
||||
{
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Global Authorization Filter - OnAuthorization");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class GlobalExceptionFilter : IExceptionFilter
|
||||
{
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "GlobalExceptionFilter.OnException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +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.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class GlobalResultFilter : IResultFilter
|
||||
{
|
||||
public void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Global Result Filter - OnResultExecuted");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ResultFilterController).GetMethod(nameof(ResultFilterController.GetHelloWorld)))
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "GlobalResultFilter.OnResultExecuting");
|
||||
}
|
||||
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"Global Result Filter - OnResultExecuted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class HandleExceptionActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
if (context.Exception != null)
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(null, "Hi from Action Filter");
|
||||
|
||||
context.Exception = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class HandleInvalidOperationExceptionFilter : ExceptionFilterAttribute
|
||||
{
|
||||
public override void OnException(ExceptionContext context)
|
||||
{
|
||||
if (context.Exception.GetType() == typeof(InvalidOperationException))
|
||||
{
|
||||
context.Result = Helpers.GetContentResult(context.Result, "Action Exception Filter");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ModifiedRandomNumberProvider : IActionFilter
|
||||
{
|
||||
private DummyService _dummyService;
|
||||
|
||||
public ModifiedRandomNumberProvider(DummyService dummyService)
|
||||
{
|
||||
_dummyService = dummyService;
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.ActionArguments["randomNumber"] = _dummyService.RandomNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ModifyResultsFilterAttribute : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
var objResult = context.Result as ObjectResult;
|
||||
var dummyClass = objResult.Value as DummyClass;
|
||||
dummyClass.SampleInt = 120;
|
||||
|
||||
objResult.Formatters.Add(new XmlSerializerOutputFormatter());
|
||||
|
||||
base.OnResultExecuting(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +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 Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class PassThroughActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "On Action Action Filter - OnActionExecuting");
|
||||
}
|
||||
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters", "On Action Action Filter - OnActionExecuted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +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.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class PassThroughResultFilter : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Action Result Filter - OnResultExecuting");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResultExecuted(ResultExecutedContext context)
|
||||
{
|
||||
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
|
||||
if (controllerActionDescriptor.MethodInfo ==
|
||||
typeof(ProductsController).GetMethod(nameof(ProductsController.GetPrice)))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append("filters",
|
||||
"On Action Result Filter - OnResultExecuted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class RandomNumberFilter : IActionFilter
|
||||
{
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
context.Result = new ContentResult()
|
||||
{
|
||||
Content = "4",
|
||||
ContentType = "text/plain"
|
||||
};
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class RandomNumberModifier : IActionFilter
|
||||
{
|
||||
private RandomNumberService _random;
|
||||
|
||||
public RandomNumberModifier(RandomNumberService random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var paramterValue = (int)context.ActionArguments["randomNumber"];
|
||||
context.ActionArguments["randomNumber"] = paramterValue + _random.GetRandamNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class RandomNumberProvider : IActionFilter
|
||||
{
|
||||
private RandomNumberService _random;
|
||||
|
||||
public RandomNumberProvider(RandomNumberService random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.ActionArguments["randomNumber"] = _random.GetRandamNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class SerializationActionFilterAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
var result = context.Result as ObjectResult;
|
||||
if (result != null)
|
||||
{
|
||||
result.Formatters.Add(new XmlSerializerOutputFormatter());
|
||||
}
|
||||
|
||||
base.OnActionExecuted(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ShortCircuitActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
context.Result = new ContentResult
|
||||
{
|
||||
Content = "The Action was never executed",
|
||||
ContentType = "text/plain"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +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 Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ShortCircuitExceptionFilter : ExceptionFilterAttribute
|
||||
{
|
||||
public override void OnException(ExceptionContext context)
|
||||
{
|
||||
context.ExceptionHandled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +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;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public class TestSyncResourceFilter : Attribute, IResourceFilter, IOrderedFilter
|
||||
{
|
||||
public enum Action
|
||||
{
|
||||
PassThrough,
|
||||
ThrowException,
|
||||
Shortcircuit
|
||||
}
|
||||
|
||||
public readonly string ExceptionMessage = $"Error!! in {nameof(TestSyncResourceFilter)}";
|
||||
|
||||
public readonly string ShortcircuitMessage = $"Shortcircuited by {nameof(TestSyncResourceFilter)}";
|
||||
|
||||
public Action FilterAction { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
if (FilterAction == Action.PassThrough)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (FilterAction == Action.ThrowException)
|
||||
{
|
||||
throw new InvalidOperationException(ExceptionMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = new ContentResult()
|
||||
{
|
||||
Content = ShortcircuitMessage,
|
||||
StatusCode = 400,
|
||||
ContentType = "text/abcd"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public class TestAsyncResourceFilter : Attribute, IAsyncResourceFilter, IOrderedFilter
|
||||
{
|
||||
public enum Action
|
||||
{
|
||||
PassThrough,
|
||||
ThrowException,
|
||||
Shortcircuit
|
||||
}
|
||||
|
||||
public readonly string ExceptionMessage = $"Error!! in {nameof(TestAsyncResourceFilter)}";
|
||||
|
||||
public readonly string ShortcircuitMessage = $"Shortcircuited by {nameof(TestAsyncResourceFilter)}";
|
||||
|
||||
public Action FilterAction { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
|
||||
{
|
||||
if (FilterAction == Action.PassThrough)
|
||||
{
|
||||
return next();
|
||||
}
|
||||
else if (FilterAction == Action.ThrowException)
|
||||
{
|
||||
throw new InvalidOperationException(ExceptionMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Result = new ContentResult()
|
||||
{
|
||||
Content = ShortcircuitMessage,
|
||||
StatusCode = 400,
|
||||
ContentType = "text/abcd"
|
||||
};
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ThrowingActionFilter : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
throw new InvalidProgramException("Action Filter threw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ThrowingAuthorizationFilter : Attribute, IAuthorizationFilter
|
||||
{
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
throw new InvalidProgramException("Authorization Filter Threw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ThrowingExceptionFilter : ExceptionFilterAttribute
|
||||
{
|
||||
public override void OnException(ExceptionContext context)
|
||||
{
|
||||
throw new InvalidProgramException("Exception Filter threw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class ThrowingResultFilter : ResultFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
throw new InvalidProgramException("Result Filter threw.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +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;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class TracingResourceFilter : Attribute, IResourceFilter
|
||||
{
|
||||
public TracingResourceFilter(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
if (!context.HttpContext.Response.HasStarted)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append(
|
||||
"filters",
|
||||
Name + " - OnResourceExecuted");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Append(
|
||||
"filters",
|
||||
Name + " - OnResourceExecuting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(StandardTestWebsiteTfms)</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc\Microsoft.AspNetCore.Mvc.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Mvc.Formatters.Xml\Microsoft.AspNetCore.Mvc.Formatters.Xml.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="$(MicrosoftAspNetCoreAuthenticationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Localization.Routing" Version="$(MicrosoftAspNetCoreLocalizationRoutingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,28 +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 Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
public static ContentResult GetContentResult(object result, string message)
|
||||
{
|
||||
var actualResult = result as ContentResult;
|
||||
var content = message;
|
||||
|
||||
if (actualResult != null)
|
||||
{
|
||||
content += ", " + actualResult.Content;
|
||||
}
|
||||
|
||||
return new ContentResult()
|
||||
{
|
||||
Content = content,
|
||||
ContentType = "text/plain",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +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.
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class DummyClass
|
||||
{
|
||||
public int SampleInt { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +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.
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class DummyService
|
||||
{
|
||||
public int RandomNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +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.
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class RandomNumberService
|
||||
{
|
||||
public int GetRandamNumber()
|
||||
{
|
||||
return 44;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,82 +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.IO;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FiltersWebSite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
// Set up application services
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication()
|
||||
.AddScheme<BasicOptions, BasicAuthenticationHandler>("Interactive", _ => { })
|
||||
.AddScheme<BasicOptions, BasicAuthenticationHandler>("Api", _ => { });
|
||||
services.AddMvc();
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
// This policy cannot succeed since the claim is never added
|
||||
options.AddPolicy("Impossible", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Interactive");
|
||||
policy.RequireClaim("Never");
|
||||
});
|
||||
options.AddPolicy("Api", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Api");
|
||||
policy.RequireClaim(ClaimTypes.NameIdentifier);
|
||||
});
|
||||
options.AddPolicy("Api-Manager", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Api");
|
||||
policy.Requirements.Add(Operations.Edit);
|
||||
});
|
||||
options.AddPolicy("Interactive", policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add("Interactive");
|
||||
policy.RequireClaim(ClaimTypes.NameIdentifier)
|
||||
.RequireClaim("Permission", "CanViewPage");
|
||||
});
|
||||
});
|
||||
services.AddSingleton<RandomNumberFilter>();
|
||||
services.AddSingleton<RandomNumberService>();
|
||||
services.AddTransient<IAuthorizationHandler, ManagerHandler>();
|
||||
|
||||
services.Configure<MvcOptions>(options =>
|
||||
{
|
||||
options.Filters.Add(new GlobalExceptionFilter());
|
||||
options.Filters.Add(new GlobalActionFilter());
|
||||
options.Filters.Add(new GlobalResultFilter());
|
||||
options.Filters.Add(new GlobalAuthorizationFilter());
|
||||
options.Filters.Add(new TracingResourceFilter("Global Resource Filter"));
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseMiddleware<ErrorReporterMiddleware>();
|
||||
|
||||
app.UseMvcWithDefaultRoute();
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseStartup<Startup>()
|
||||
.UseKestrel()
|
||||
.UseIISIntegration()
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
FiltersWebSite
|
||||
===
|
||||
|
||||
This web site illustrates how to use filters to customize request and response. It shows how filters can be
|
||||
used at a global, controller or action level and how they can be extended.
|
||||
Loading…
Reference in New Issue