From d1782007958af882dd92516e0f53fdc01ca4d32a Mon Sep 17 00:00:00 2001 From: sornaks Date: Wed, 22 Oct 2014 13:54:09 -0700 Subject: [PATCH] Adding functional tests for Filters. --- src/Microsoft.AspNet.Mvc.Core/Controller.cs | 4 +- .../Filters/DefaultFilterProviderTest.cs | 6 +- .../FiltersTest.cs | 377 ++++++++++++++++-- .../project.json | 1 - .../Controllers/ActionFilterController.cs | 42 ++ .../Controllers/DummyClassController.cs | 13 +- .../Controllers/ExceptionOrderController.cs | 26 ++ .../Controllers/HomeController.cs | 86 ++++ .../Controllers/ProductsController.cs | 42 +- .../Controllers/RandomNumberController.cs | 15 + .../Controllers/ResultFilterController.cs | 26 ++ .../Filters/AuthorizeUserAttribute.cs | 6 + .../Filters/ChangeContentActionFilter.cs | 25 ++ .../Filters/ChangeContentResultFilter.cs | 15 + .../Filters/ControllerActionFilter.cs | 39 ++ .../Filters/ControllerAuthorizationFilter.cs | 15 + .../Filters/ControllerExceptionFilter.cs | 19 + .../Filters/ControllerResultFilter.cs | 32 ++ .../Filters/GlobalActionFilter.cs | 40 ++ .../Filters/GlobalAuthorizationFilter.cs | 19 + .../Filters/GlobalExceptionFilter.cs | 6 +- .../Filters/GlobalResultFilter.cs | 33 ++ .../Filters/HandleExceptionActionFilter.cs | 21 + .../HandleInvalidOperationExceptionFilter.cs | 19 + ...der.cs => ModifiedRandomNumberProvider.cs} | 0 .../Filters/PassThroughActionFilter.cs | 9 + .../Filters/PassThroughResultFilter.cs | 17 + .../Filters/RandomNumberModifier.cs | 27 ++ .../Filters/ShortCircuitActionFilter.cs | 19 + .../Filters/ShortCircuitExceptionFilter.cs | 15 + .../Filters/ShortCircuitResultFilter.cs | 18 + .../Filters/ThrowingActionFilter.cs | 16 + .../Filters/ThrowingAuthorizationFilter.cs | 16 + .../Filters/ThrowingExceptionFilter.cs | 16 + .../Filters/ThrowingResultFilter.cs | 16 + .../WebSites/FiltersWebSite/Helper/Helpers.cs | 27 ++ test/WebSites/FiltersWebSite/Startup.cs | 5 +- 37 files changed, 1066 insertions(+), 62 deletions(-) create mode 100644 test/WebSites/FiltersWebSite/Controllers/ActionFilterController.cs create mode 100644 test/WebSites/FiltersWebSite/Controllers/ExceptionOrderController.cs create mode 100644 test/WebSites/FiltersWebSite/Controllers/HomeController.cs create mode 100644 test/WebSites/FiltersWebSite/Controllers/ResultFilterController.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ChangeContentActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ChangeContentResultFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ControllerActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ControllerAuthorizationFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ControllerExceptionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ControllerResultFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/GlobalActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/GlobalAuthorizationFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/GlobalResultFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/HandleExceptionActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/HandleInvalidOperationExceptionFilter.cs rename test/WebSites/FiltersWebSite/Filters/{FakeRandomNumberProvider.cs => ModifiedRandomNumberProvider.cs} (100%) create mode 100644 test/WebSites/FiltersWebSite/Filters/RandomNumberModifier.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ShortCircuitExceptionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ShortCircuitResultFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ThrowingActionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ThrowingAuthorizationFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ThrowingExceptionFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Filters/ThrowingResultFilter.cs create mode 100644 test/WebSites/FiltersWebSite/Helper/Helpers.cs diff --git a/src/Microsoft.AspNet.Mvc.Core/Controller.cs b/src/Microsoft.AspNet.Mvc.Core/Controller.cs index 1726c54563..b0e74b6fd4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controller.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controller.cs @@ -125,8 +125,8 @@ namespace Microsoft.AspNet.Mvc { get { - // Controller-filter methods run closest the action by default. - return int.MaxValue; + // Controller-filter methods run farthest the action by default. + return int.MinValue; } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/DefaultFilterProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/DefaultFilterProviderTest.cs index 7da7fe847e..bb4ad77f9f 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/DefaultFilterProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/DefaultFilterProviderTest.cs @@ -135,10 +135,10 @@ namespace Microsoft.AspNet.Mvc.Filters { // Arrange var filter1 = new Mock(); - filter1.SetupGet(f => f.Order).Returns(int.MaxValue); + filter1.SetupGet(f => f.Order).Returns(int.MinValue); var filter2 = new Mock(); - filter2.SetupGet(f => f.Order).Returns(int.MaxValue); + filter2.SetupGet(f => f.Order).Returns(int.MinValue); var context = CreateFilterContext(new List() { @@ -160,7 +160,7 @@ namespace Microsoft.AspNet.Mvc.Filters Assert.Same(controller, controllerItem.Filter); Assert.Same(controller, controllerItem.Descriptor.Filter); Assert.Equal(FilterScope.Controller, controllerItem.Descriptor.Scope); - Assert.Equal(Int32.MaxValue, controllerItem.Descriptor.Order); + Assert.Equal(int.MinValue, controllerItem.Descriptor.Order); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs index 18bd1f49d8..0d6984876a 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/FiltersTest.cs @@ -6,7 +6,6 @@ using System.Net; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.TestHost; -using Newtonsoft.Json; using Xunit; namespace Microsoft.AspNet.Mvc.FunctionalTests @@ -30,30 +29,31 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal(HttpStatusCode.OK, response.StatusCode); var body = await response.Content.ReadAsStringAsync(); - var result = JsonConvert.DeserializeObject(body); - - Assert.Equal(19.95m, result); var filters = response.Headers.GetValues("filters"); Assert.Equal( - new string[] - { - // This one uses order to set itself 'first' even though it appears on the controller - "FiltersWebSite.PassThroughActionFilter", - - // Configured as global with default order - "FiltersWebSite.GlobalExceptionFilter", - - // Configured on the controller with default order - "FiltersWebSite.PassThroughResultFilter", - - // Configured on the action with default order - "FiltersWebSite.PassThroughActionFilter", - - // The controller itself - "FiltersWebSite.ProductsController", - }, - filters); + "Controller Override - OnAuthorization," + + "Global Authorization Filter - OnAuthorization," + + "On Controller Authorization Filter - OnAuthorization," + + "Authorize Filter On Action - OnAuthorization," + + "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", + (filters as string[])[0]); } [Fact] @@ -70,6 +70,21 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } + [Fact] + public async Task AllowsAnonymousUsersToAccessController() + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 CanAuthorizeParticularUsers() { @@ -78,28 +93,14 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var client = server.CreateClient(); // Act - var response = await client.GetAsync("http://localhost/AuthorizeUser/ReturnHelloWorldOnlyForAuthorizedUser"); + var response = await client.GetAsync( + "http://localhost/AuthorizeUser/ReturnHelloWorldOnlyForAuthorizedUser"); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync()); } - [Fact] - public async Task ExceptionFilterHandlesAnException() - { - // Arrange - var server = TestServer.Create(_services, _app); - var client = server.CreateClient(); - - // 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()); - } - [Fact] public async Task ServiceFilterUsesRegisteredServicesAsFilter() { @@ -204,5 +205,305 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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()); + } + + // Controller Override, 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // Act + var response = await client.GetAsync("http://localhost/ExceptionOrder/GetError"); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal( + "OnException implemented in Controller, " + + "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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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 + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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. + // Verifies the Global Exception Filter does not handle it. + [Fact] + public async Task ThrowingResultFilter_NotHandledByGlobalExceptionFilter() + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // Act & Assert + await Assert.ThrowsAsync( + () => client.GetAsync("http://localhost/Home/ThrowingResultFilter")); + } + + // Action Filter throws. + // Verifies the Global Exception Filter handles it. + [Theory] + [InlineData("http://localhost/Home/ThrowingActionFilter")] + [InlineData("http://localhost/Home/ThrowingAuthorizationFilter")] + public async Task ThrowingFilters_HandledByGlobalExceptionFilter(string url) + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // Act + var response = await client.GetAsync(url); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("GlobalExceptionFilter.OnException", await response.Content.ReadAsStringAsync()); + } + + // Exception Filter throws. + // Verifies the thrown exception is ignored. + [Fact] + public async Task ThrowingExceptionFilter_NotHandledByGlobalExceptionFilter() + { + // Arrange + var server = TestServer.Create(_services, _app); + var client = server.CreateClient(); + + // 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()); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json index b334fcb8a7..b382301089 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json @@ -28,7 +28,6 @@ "ViewComponentWebSite": "1.0.0", "XmlSerializerWebSite": "1.0.0", "WebApiCompatShimWebSite": "1.0.0", - "Microsoft.AspNet.TestHost": "1.0.0-*", "Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0", "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*", diff --git a/test/WebSites/FiltersWebSite/Controllers/ActionFilterController.cs b/test/WebSites/FiltersWebSite/Controllers/ActionFilterController.cs new file mode 100644 index 0000000000..ece954192e --- /dev/null +++ b/test/WebSites/FiltersWebSite/Controllers/ActionFilterController.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + [ControllerActionFilter] + public class ActionFilterController : Controller + { + [ChangeContentActionFilter] + public IActionResult GetHelloWorld(IList fromGlobalActionFilter) + { + // Should have got content from Global Action Filter followed by Controller Override. + if (fromGlobalActionFilter != null) + { + ContentResult combinedResult = null; + var resultsFromActionFilters = fromGlobalActionFilter as List; + 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) + { + (context.ActionArguments["fromGlobalActionFilter"] as List) + .Add(Helpers.GetContentResult(context.Result, "Controller override - OnActionExecuting")); + } + + public override void OnActionExecuted(ActionExecutedContext context) + { + context.Result = Helpers.GetContentResult(context.Result, "Controller override - OnActionExecuted"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/DummyClassController.cs b/test/WebSites/FiltersWebSite/Controllers/DummyClassController.cs index 4ba63649a1..1c1c4a712b 100644 --- a/test/WebSites/FiltersWebSite/Controllers/DummyClassController.cs +++ b/test/WebSites/FiltersWebSite/Controllers/DummyClassController.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Threading.Tasks; using Microsoft.AspNet.Mvc; @@ -23,6 +22,18 @@ namespace FiltersWebSite { 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 diff --git a/test/WebSites/FiltersWebSite/Controllers/ExceptionOrderController.cs b/test/WebSites/FiltersWebSite/Controllers/ExceptionOrderController.cs new file mode 100644 index 0000000000..ef64272c82 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Controllers/ExceptionOrderController.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + [ControllerExceptionFilter] + public class ExceptionOrderController : Controller, IExceptionFilter + { + [HandleInvalidOperationExceptionFilter] + public string GetError(string error) + { + throw new InvalidOperationException(error); + } + + public void OnException(ExceptionContext context) + { + if (context.Exception.GetType() == typeof(InvalidOperationException)) + { + context.Result = Helpers.GetContentResult(context.Result, "OnException implemented in Controller"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/HomeController.cs b/test/WebSites/FiltersWebSite/Controllers/HomeController.cs new file mode 100644 index 0000000000..2f55871b18 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Controllers/HomeController.cs @@ -0,0 +1,86 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.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] + public IActionResult ThrowRandomExcpetion() + { + throw new InvalidOperationException("Controller threw."); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/ProductsController.cs b/test/WebSites/FiltersWebSite/Controllers/ProductsController.cs index e457849b29..1730c2e79c 100644 --- a/test/WebSites/FiltersWebSite/Controllers/ProductsController.cs +++ b/test/WebSites/FiltersWebSite/Controllers/ProductsController.cs @@ -2,28 +2,50 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Mvc; -using System.Linq; 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. - [PassThroughActionFilter(Order = -2)] - [PassThroughResultFilter] - public class ProductsController : Controller + [ControllerResultFilter] + [ControllerActionFilter] + [ControllerAuthorizationFilter] + public class ProductsController : Controller, IResultFilter, IAuthorizationFilter { + [PassThroughResultFilter] [PassThroughActionFilter] - public decimal GetPrice(int id) + [AuthorizeUser] + public IActionResult GetPrice(int id) { - return 19.95m; + 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) { - // Log the filter names in a header - context.HttpContext.Response.Headers.Add( - "filters", - context.Filters.Select(f => f.GetType().FullName).ToArray()); + 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"); + } + + public void OnAuthorization(AuthorizationContext context) + { + context.HttpContext.Response.Headers.Append("filters", "Controller Override - OnAuthorization"); } } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/RandomNumberController.cs b/test/WebSites/FiltersWebSite/Controllers/RandomNumberController.cs index af56b58328..824c553cec 100644 --- a/test/WebSites/FiltersWebSite/Controllers/RandomNumberController.cs +++ b/test/WebSites/FiltersWebSite/Controllers/RandomNumberController.cs @@ -1,10 +1,13 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Mvc; namespace FiltersWebSite { + [AllowAnonymous] + [HandleInvalidOperationExceptionFilter] public class RandomNumberController : Controller { [ServiceFilter(typeof(RandomNumberFilter))] @@ -30,5 +33,17 @@ namespace FiltersWebSite { 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(); + } } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Controllers/ResultFilterController.cs b/test/WebSites/FiltersWebSite/Controllers/ResultFilterController.cs new file mode 100644 index 0000000000..4fafee0156 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Controllers/ResultFilterController.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +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"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/AuthorizeUserAttribute.cs b/test/WebSites/FiltersWebSite/Filters/AuthorizeUserAttribute.cs index 3c374fe648..f3538ac006 100644 --- a/test/WebSites/FiltersWebSite/Filters/AuthorizeUserAttribute.cs +++ b/test/WebSites/FiltersWebSite/Filters/AuthorizeUserAttribute.cs @@ -10,6 +10,12 @@ namespace FiltersWebSite { public override void OnAuthorization(AuthorizationContext context) { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Authorize Filter On Action - OnAuthorization"); + } + context.HttpContext.User = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { diff --git a/test/WebSites/FiltersWebSite/Filters/ChangeContentActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ChangeContentActionFilter.cs new file mode 100644 index 0000000000..cb538dc6ff --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ChangeContentActionFilter.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNet.Mvc; + +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) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ActionFilterController.GetHelloWorld") + { + (context.ActionArguments["fromGlobalActionFilter"] as List). + Add(Helpers.GetContentResult(context.Result, "Action Filter - OnActionExecuting")); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ChangeContentResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/ChangeContentResultFilter.cs new file mode 100644 index 0000000000..26b9380f51 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ChangeContentResultFilter.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ChangeContentResultFilter : ResultFilterAttribute + { + public override void OnResultExecuting(ResultExecutingContext context) + { + context.Result = Helpers.GetContentResult(context.Result, "Result filter"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ControllerActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ControllerActionFilter.cs new file mode 100644 index 0000000000..f1ab11db49 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ControllerActionFilter.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ControllerActionFilter : ActionFilterAttribute + { + public override void OnActionExecuted(ActionExecutedContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.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) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "On Controller Action Filter - OnActionExecuting"); + } + + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ActionFilterController.GetHelloWorld") + { + (context.ActionArguments["fromGlobalActionFilter"] as List) + .Add(Helpers.GetContentResult(context.Result, "Controller Action filter - OnActionExecuting")); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ControllerAuthorizationFilter.cs b/test/WebSites/FiltersWebSite/Filters/ControllerAuthorizationFilter.cs new file mode 100644 index 0000000000..4b2162e58c --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ControllerAuthorizationFilter.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ControllerAuthorizationFilter : AuthorizeUserAttribute + { + public override void OnAuthorization(AuthorizationContext context) + { + context.HttpContext.Response.Headers.Append("filters", "On Controller Authorization Filter - OnAuthorization"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ControllerExceptionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ControllerExceptionFilter.cs new file mode 100644 index 0000000000..4e1f3fa47b --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ControllerExceptionFilter.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +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"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ControllerResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/ControllerResultFilter.cs new file mode 100644 index 0000000000..e3deb3643a --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ControllerResultFilter.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ControllerResultFilter : ResultFilterAttribute + { + public override void OnResultExecuting(ResultExecutingContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.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) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "On Controller Result Filter - OnResultExecuted"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/GlobalActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/GlobalActionFilter.cs new file mode 100644 index 0000000000..37d5fc3737 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/GlobalActionFilter.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class GlobalActionFilter : IActionFilter + { + public void OnActionExecuted(ActionExecutedContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ActionFilterController.GetHelloWorld") + { + context.Result = Helpers.GetContentResult(context.Result, "GlobalActionFilter.OnActionExecuted"); + } + + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Global Action Filter - OnActionExecuted"); + } + } + + public void OnActionExecuting(ActionExecutingContext context) + { + if(context.ActionDescriptor.DisplayName == "FiltersWebSite.ActionFilterController.GetHelloWorld") + { + (context.ActionArguments["fromGlobalActionFilter"] as List) + .Add(Helpers.GetContentResult(null, "GlobalActionFilter.OnActionExecuting")); + } + + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Global Action Filter - OnActionExecuting"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/GlobalAuthorizationFilter.cs b/test/WebSites/FiltersWebSite/Filters/GlobalAuthorizationFilter.cs new file mode 100644 index 0000000000..00a59ac766 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/GlobalAuthorizationFilter.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class GlobalAuthorizationFilter : AuthorizationFilterAttribute + { + public override void OnAuthorization(AuthorizationContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Global Authorization Filter - OnAuthorization"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/GlobalExceptionFilter.cs b/test/WebSites/FiltersWebSite/Filters/GlobalExceptionFilter.cs index 15151d5e46..c4ea5407a4 100644 --- a/test/WebSites/FiltersWebSite/Filters/GlobalExceptionFilter.cs +++ b/test/WebSites/FiltersWebSite/Filters/GlobalExceptionFilter.cs @@ -9,11 +9,7 @@ namespace FiltersWebSite { public void OnException(ExceptionContext context) { - context.Result = new ContentResult() - { - Content = "GlobalExceptionFilter.OnException", - ContentType = "text/plain", - }; + context.Result = Helpers.GetContentResult(context.Result, "GlobalExceptionFilter.OnException"); } } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/GlobalResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/GlobalResultFilter.cs new file mode 100644 index 0000000000..492bb42fe1 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/GlobalResultFilter.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class GlobalResultFilter : IResultFilter + { + public void OnResultExecuted(ResultExecutedContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Global Result Filter - OnResultExecuted"); + } + } + + public void OnResultExecuting(ResultExecutingContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ResultFilterController.GetHelloWorld") + { + context.Result = Helpers.GetContentResult(context.Result, "GlobalResultFilter.OnResultExecuting"); + } + + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "Global Result Filter - OnResultExecuted"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/HandleExceptionActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/HandleExceptionActionFilter.cs new file mode 100644 index 0000000000..6bc0e2ce34 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/HandleExceptionActionFilter.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +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; + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/HandleInvalidOperationExceptionFilter.cs b/test/WebSites/FiltersWebSite/Filters/HandleInvalidOperationExceptionFilter.cs new file mode 100644 index 0000000000..861a27358b --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/HandleInvalidOperationExceptionFilter.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +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"); + } + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/FakeRandomNumberProvider.cs b/test/WebSites/FiltersWebSite/Filters/ModifiedRandomNumberProvider.cs similarity index 100% rename from test/WebSites/FiltersWebSite/Filters/FakeRandomNumberProvider.cs rename to test/WebSites/FiltersWebSite/Filters/ModifiedRandomNumberProvider.cs diff --git a/test/WebSites/FiltersWebSite/Filters/PassThroughActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/PassThroughActionFilter.cs index b1eb7188ee..23bdb63a0f 100644 --- a/test/WebSites/FiltersWebSite/Filters/PassThroughActionFilter.cs +++ b/test/WebSites/FiltersWebSite/Filters/PassThroughActionFilter.cs @@ -7,5 +7,14 @@ 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"); + } } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/PassThroughResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/PassThroughResultFilter.cs index d56ea51169..9524030dc2 100644 --- a/test/WebSites/FiltersWebSite/Filters/PassThroughResultFilter.cs +++ b/test/WebSites/FiltersWebSite/Filters/PassThroughResultFilter.cs @@ -7,5 +7,22 @@ namespace FiltersWebSite { public class PassThroughResultFilter : ResultFilterAttribute { + public override void OnResultExecuting(ResultExecutingContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "On Action Result Filter - OnResultExecuting"); + } + } + + public override void OnResultExecuted(ResultExecutedContext context) + { + if (context.ActionDescriptor.DisplayName == "FiltersWebSite.ProductsController.GetPrice") + { + context.HttpContext.Response.Headers.Append("filters", + "On Action Result Filter - OnResultExecuted"); + } + } } } \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/RandomNumberModifier.cs b/test/WebSites/FiltersWebSite/Filters/RandomNumberModifier.cs new file mode 100644 index 0000000000..f9a1139ada --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/RandomNumberModifier.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +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(); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs new file mode 100644 index 0000000000..d9b763d924 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +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" + }; + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ShortCircuitExceptionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ShortCircuitExceptionFilter.cs new file mode 100644 index 0000000000..3dd57c37ec --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ShortCircuitExceptionFilter.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ShortCircuitExceptionFilter : ExceptionFilterAttribute + { + public override void OnException(ExceptionContext context) + { + context.Exception = null; + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ShortCircuitResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/ShortCircuitResultFilter.cs new file mode 100644 index 0000000000..0666889c7c --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ShortCircuitResultFilter.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ShortCircuitResultFilter : ResultFilterAttribute + { + public override void OnResultExecuting(ResultExecutingContext context) + { + context.Result = new ContentResult + { + Content = "The Result was never executed" + }; + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ThrowingActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ThrowingActionFilter.cs new file mode 100644 index 0000000000..b40fab5bed --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ThrowingActionFilter.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ThrowingActionFilter : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext context) + { + throw new InvalidProgramException("Action Filter threw"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ThrowingAuthorizationFilter.cs b/test/WebSites/FiltersWebSite/Filters/ThrowingAuthorizationFilter.cs new file mode 100644 index 0000000000..82d4b84d0c --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ThrowingAuthorizationFilter.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ThrowingAuthorizationFilter : AuthorizationFilterAttribute + { + public override void OnAuthorization(AuthorizationContext context) + { + throw new InvalidProgramException("Authorization Filter Threw"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ThrowingExceptionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ThrowingExceptionFilter.cs new file mode 100644 index 0000000000..f799c4ec56 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ThrowingExceptionFilter.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ThrowingExceptionFilter : ExceptionFilterAttribute + { + public override void OnException(ExceptionContext context) + { + throw new InvalidProgramException("Exception Filter threw"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/ThrowingResultFilter.cs b/test/WebSites/FiltersWebSite/Filters/ThrowingResultFilter.cs new file mode 100644 index 0000000000..c00896cc33 --- /dev/null +++ b/test/WebSites/FiltersWebSite/Filters/ThrowingResultFilter.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Mvc; + +namespace FiltersWebSite +{ + public class ThrowingResultFilter : ResultFilterAttribute + { + public override void OnResultExecuting(ResultExecutingContext context) + { + throw new InvalidProgramException("Result Filter threw."); + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Helper/Helpers.cs b/test/WebSites/FiltersWebSite/Helper/Helpers.cs new file mode 100644 index 0000000000..19b95a6e9b --- /dev/null +++ b/test/WebSites/FiltersWebSite/Helper/Helpers.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Mvc; + +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", + }; + } + } +} \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Startup.cs b/test/WebSites/FiltersWebSite/Startup.cs index 90a39ef075..e546ed9162 100644 --- a/test/WebSites/FiltersWebSite/Startup.cs +++ b/test/WebSites/FiltersWebSite/Startup.cs @@ -1,11 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Mvc; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; namespace FiltersWebSite { @@ -24,6 +22,9 @@ namespace FiltersWebSite services.Configure(options => { options.Filters.Add(new GlobalExceptionFilter()); + options.Filters.Add(new GlobalActionFilter()); + options.Filters.Add(new GlobalResultFilter()); + options.Filters.Add(new GlobalAuthorizationFilter()); }); });