diff --git a/samples/MvcSample.Web/Controllers/FormatFilterController.cs b/samples/MvcSample.Web/Controllers/FormatFilterController.cs
index 945331cd76..5debd2d10b 100644
--- a/samples/MvcSample.Web/Controllers/FormatFilterController.cs
+++ b/samples/MvcSample.Web/Controllers/FormatFilterController.cs
@@ -5,14 +5,15 @@ using Microsoft.AspNet.Mvc;
namespace MvcSample.Web.Controllers
{
+ [Route("[controller]/[action]/{id}.{format?}")]
public class FormatFilterController : Controller
{
public Product GetProduct(int id)
{
return new Product() { SampleInt = id };
}
-
- [Produces("application/custom", "application/json", "text/json")]
+
+ [Produces("application/json", "text/json")]
public Product ProducesMethod(int id)
{
return new Product() { SampleInt = id }; ;
diff --git a/samples/MvcSample.Web/Startup.cs b/samples/MvcSample.Web/Startup.cs
index 38763af5cd..023640a31c 100644
--- a/samples/MvcSample.Web/Startup.cs
+++ b/samples/MvcSample.Web/Startup.cs
@@ -114,7 +114,6 @@ namespace MvcSample.Web
app.UseMvc(routes =>
{
- routes.MapRoute("FormatRoute", "{controller}/{action}/{id}.{format?}");
routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}");
routes.MapRoute(
"controllerActionRoute",
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilter.cs
new file mode 100644
index 0000000000..b2043a4dde
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilter.cs
@@ -0,0 +1,136 @@
+// 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 System.Linq;
+using Microsoft.AspNet.Mvc.Description;
+using Microsoft.Net.Http.Headers;
+
+namespace Microsoft.AspNet.Mvc
+{
+ ///
+ /// A filter which will use the format value in the route data or query string to set the content type on an
+ /// returned from an action.
+ ///
+ public class FormatFilter : IFormatFilter, IResourceFilter, IResultFilter
+ {
+ ///
+ /// Initializes an instance of .
+ ///
+ /// .
+ public FormatFilter(MvcOptions options, ActionContext actionContext)
+ {
+ IsActive = true;
+ Format = GetFormat(actionContext);
+
+ if (string.IsNullOrEmpty(Format))
+ {
+ IsActive = false;
+ return;
+ }
+
+ ContentType = options.FormatterMappings.GetMediaTypeMappingForFormat(Format);
+ }
+
+ ///
+ /// format value in the current request. null if format not present in the current request.
+ ///
+ public string Format { get; private set; }
+
+ ///
+ /// for the format value in the current request.
+ ///
+ public MediaTypeHeaderValue ContentType { get; private set; }
+
+ ///
+ /// true if the current is active and will execute.
+ ///
+ public bool IsActive { get; private set; }
+
+ ///
+ /// As a , this filter looks at the request and rejects it before going ahead if
+ /// 1. The format in the request doesnt match any format in the map.
+ /// 2. If there is a conflicting producesFilter.
+ ///
+ /// The .
+ public void OnResourceExecuting([NotNull] ResourceExecutingContext context)
+ {
+ if (!IsActive)
+ {
+ return; // no format specified by user, so the filter is muted
+ }
+
+ if (ContentType == null)
+ {
+ // no contentType exists for the format, return 404
+ context.Result = new HttpNotFoundResult();
+ }
+ else
+ {
+ var responseTypeFilters = context.Filters.OfType();
+ var contentTypes = new List();
+
+ foreach (var filter in responseTypeFilters)
+ {
+ filter.SetContentTypes(contentTypes);
+ }
+
+ if (contentTypes.Count != 0)
+ {
+ // There is no IApiResponseMetadataProvider to generate the content type user asked for. We have to
+ // exit here with not found result.
+ if (!contentTypes.Any(c => ContentType.IsSubsetOf(c)))
+ {
+ context.Result = new HttpNotFoundResult();
+ }
+ }
+ }
+ }
+
+ ///
+ public void OnResourceExecuted([NotNull] ResourceExecutedContext context)
+ {
+ }
+
+ ///
+ /// Sets a Content Type on an using a format value from the request.
+ ///
+ /// The .
+ public void OnResultExecuting([NotNull] ResultExecutingContext context)
+ {
+ if (!IsActive)
+ {
+ return; // no format specified by user, so the filter is muted
+ }
+
+ var objectResult = context.Result as ObjectResult;
+ if (objectResult != null)
+ {
+ objectResult.ContentTypes.Clear();
+ objectResult.ContentTypes.Add(ContentType);
+ }
+ }
+
+ ///
+ public void OnResultExecuted([NotNull] ResultExecutedContext context)
+ {
+ }
+
+ private string GetFormat(ActionContext context)
+ {
+ object format = null;
+
+ if (!context.RouteData.Values.TryGetValue("format", out format))
+ {
+ format = context.HttpContext.Request.Query["format"];
+ }
+
+ if (format != null)
+ {
+ return format.ToString();
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilterAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilterAttribute.cs
index 1950971929..8836373227 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilterAttribute.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilterAttribute.cs
@@ -2,13 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using Microsoft.AspNet.Mvc.Description;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
-using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNet.Mvc
{
@@ -17,117 +12,18 @@ namespace Microsoft.AspNet.Mvc
/// returned from an action.
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
- public class FormatFilterAttribute : Attribute, IFormatFilter, IResourceFilter, IResultFilter
+ public class FormatFilterAttribute : Attribute, IFilterFactory
{
///
- /// As a , this filter looks at the request and rejects it before going ahead if
- /// 1. The format in the request doesnt match any format in the map.
- /// 2. If there is a conflicting producesFilter.
+ /// Creates an instance of
///
- /// The .
- public void OnResourceExecuting([NotNull] ResourceExecutingContext context)
+ /// The
+ /// An instance of
+ public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider)
{
- var format = GetFormat(context);
-
- if (!string.IsNullOrEmpty(format))
- {
- var formatContentType = GetContentType(format, context);
- if (formatContentType == null)
- {
- // no contentType exists for the format, return 404
- context.Result = new HttpNotFoundResult();
- }
- else
- {
- var responseTypeFilters = context.Filters.OfType();
- var contentTypes = new List();
-
- foreach (var filter in responseTypeFilters)
- {
- filter.SetContentTypes(contentTypes);
- }
-
- if (contentTypes.Count != 0)
- {
- // If formatfilterContentType is not subset of any of the content types produced by
- // IApiResponseMetadataProviders, return 404
- if (!contentTypes.Any(c => formatContentType.IsSubsetOf(c)))
- {
- context.Result = new HttpNotFoundResult();
- }
- }
- }
- }
- }
-
- ///
- public void OnResourceExecuted([NotNull] ResourceExecutedContext context)
- {
-
- }
-
- ///
- /// Sets a Content Type on an using a format value from the request.
- ///
- /// The .
- public void OnResultExecuting([NotNull] ResultExecutingContext context)
- {
- var format = GetFormat(context);
- if (!string.IsNullOrEmpty(format))
- {
- var objectResult = context.Result as ObjectResult;
- if (objectResult != null)
- {
- var contentType = GetContentType(format, context);
- Debug.Assert(contentType != null);
- objectResult.ContentTypes.Clear();
- objectResult.ContentTypes.Add(contentType);
- }
- }
- }
-
- ///
- public void OnResultExecuted([NotNull] ResultExecutedContext context)
- {
-
- }
-
- ///
- /// Returns true if the filter is active and will execute; otherwise, false. The filter is active
- /// if the current request contains format value.
- ///
- /// The
- /// true if the current request contains format value; otherwise, false.
- public bool IsActive(FilterContext context)
- {
- var format = GetFormat(context);
-
- return !string.IsNullOrEmpty(format);
- }
-
- private string GetFormat(FilterContext context)
- {
- object format = null;
-
- if (!context.RouteData.Values.TryGetValue("format", out format))
- {
- format = context.HttpContext.Request.Query["format"];
- }
-
- if (format != null)
- {
- return format.ToString();
- }
-
- return null;
- }
-
- private MediaTypeHeaderValue GetContentType(string format, FilterContext context)
- {
- var options = context.HttpContext.RequestServices.GetRequiredService>();
- var contentType = options.Options.FormatterMappings.GetMediaTypeMappingForFormat(format);
-
- return contentType;
+ var options = serviceProvider.GetRequiredService>();
+ var actionContext = serviceProvider.GetRequiredService>();
+ return new FormatFilter(options.Options, actionContext.Value);
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/IFormatFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/IFormatFilter.cs
index 09ebc7e262..0b05f4c535 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/IFormatFilter.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/IFormatFilter.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using Microsoft.Net.Http.Headers;
+
namespace Microsoft.AspNet.Mvc
{
///
@@ -9,12 +11,18 @@ namespace Microsoft.AspNet.Mvc
public interface IFormatFilter : IFilter
{
///
- /// Returns true if the filter will produce a content type for the current request, otherwise
- /// false.
+ /// format value in the current request. null if format not present in the current request.
///
- /// The
- /// true if the filter will produce a content type for the current request; otherwise,
- /// false.
- bool IsActive(FilterContext context);
+ string Format { get; }
+
+ ///
+ /// for the format value in the current request.
+ ///
+ MediaTypeHeaderValue ContentType { get; }
+
+ ///
+ /// true if the current is active and will execute.
+ ///
+ bool IsActive { get; }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/ProducesAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/ProducesAttribute.cs
index a3e74c662d..2a12120ec5 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Filters/ProducesAttribute.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Filters/ProducesAttribute.cs
@@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Mvc
{
// Check if there are any IFormatFilter in the pipeline, and if any of them is active. If there is one,
// do not override the content type value.
- if (context.Filters.OfType().All(f => !f.IsActive(context)))
+ if (context.Filters.OfType().All(f => !f.IsActive))
{
SetContentTypes(objectResult.ContentTypes);
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/FormatterMappings.cs b/src/Microsoft.AspNet.Mvc.Core/FormatterMappings.cs
index b759c9dadb..b1f18673e1 100644
--- a/src/Microsoft.AspNet.Mvc.Core/FormatterMappings.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/FormatterMappings.cs
@@ -3,10 +3,8 @@
using System;
using System.Collections.Generic;
-using Microsoft.Net.Http.Headers;
-using System.Collections.ObjectModel;
-using System.Globalization;
using Microsoft.AspNet.Mvc.Core;
+using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNet.Mvc
{
diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs
index 745481bd5b..8ce05b618e 100644
--- a/src/Microsoft.AspNet.Mvc/MvcServices.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs
@@ -75,6 +75,8 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient, DefaultFilterProvider>();
+ yield return describe.Transient();
+
// Dataflow - ModelBinding, Validation and Formatting
yield return describe.Transient();
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/FormatFilterTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/FormatFilterTest.cs
index 25e581643b..001c0e8cc7 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/FormatFilterTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/FormatFilterTest.cs
@@ -3,8 +3,8 @@
using System;
using Microsoft.AspNet.Http;
-using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Http.Core;
+using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
@@ -37,16 +37,15 @@ namespace Microsoft.AspNet.Mvc
FormatSource place,
string contentType)
{
- // Arrange
+ // Arrange
var mediaType = MediaTypeHeaderValue.Parse("application/json");
- var resultExecutingContext = CreateResultExecutingContext(
- format,
- FormatSource.RouteData);
- var resourceExecutingContext = CreateResourceExecutingContext(
- new IFilter[] { },
- format,
- FormatSource.RouteData);
- var filter = new FormatFilterAttribute();
+ var mockObjects = new MockObjects(format, place);
+
+ var resultExecutingContext = mockObjects.CreateResultExecutingContext();
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { });
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -70,16 +69,21 @@ namespace Microsoft.AspNet.Mvc
// Arrange
var mediaType = MediaTypeHeaderValue.Parse("application/json");
+ var mockObjects = new MockObjects("json", FormatSource.RouteData);
- var httpContext = CreateMockHttpContext();
+ var httpContext = new Mock();
+ httpContext
+ .Setup(c => c.RequestServices)
+ .Returns(mockObjects.MockServiceProvider);
+
+ // Query contains xml
+ httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
+ httpContext.Setup(c => c.Request.Query.Get("format")).Returns("xml");
// Routedata contains json
var data = new RouteData();
data.Values.Add("format", "json");
- // Query contains xml
- httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
- httpContext.Setup(c => c.Request.Query.Get("format")).Returns("xml");
var ac = new ActionContext(httpContext.Object, data, new ActionDescriptor());
var resultExecutingContext = new ResultExecutingContext(
@@ -92,7 +96,8 @@ namespace Microsoft.AspNet.Mvc
ac,
new IFilter[] { });
- var filter = new FormatFilterAttribute();
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -115,14 +120,18 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var mediaType = MediaTypeHeaderValue.Parse(contentType);
- var resultExecutingContext = CreateResultExecutingContext(format, place);
- var resourceExecutingContext = CreateResourceExecutingContext(new IFilter[] { }, format, place);
- var options = resultExecutingContext.HttpContext.RequestServices.GetService>();
+
+ var mockObjects = new MockObjects(format, place);
+ var resultExecutingContext = mockObjects.CreateResultExecutingContext();
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { });
+
+ var options = mockObjects.MockServiceProvider.GetService>();
options.Options.FormatterMappings.SetMediaTypeMappingForFormat(
format,
MediaTypeHeaderValue.Parse(contentType));
-
- var filter = new FormatFilterAttribute();
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -135,17 +144,18 @@ namespace Microsoft.AspNet.Mvc
}
[Theory]
- [InlineData("foo", FormatSource.RouteData, "application/foo")]
- [InlineData("foo", FormatSource.QueryData, "application/foo")]
+ [InlineData("foo", FormatSource.RouteData)]
+ [InlineData("foo", FormatSource.QueryData)]
public void FormatFilter_ContextContainsNonExistingFormat(
string format,
- FormatSource place,
- string contentType)
+ FormatSource place)
{
- // Arrange
- var mediaType = MediaTypeHeaderValue.Parse(contentType);
- var resourceExecutingContext = CreateResourceExecutingContext(new IFilter[] { }, format, place);
- var filter = new FormatFilterAttribute();
+ // Arrange
+ var mockObjects = new MockObjects(format, place);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { });
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -159,8 +169,11 @@ namespace Microsoft.AspNet.Mvc
public void FormatFilter_ContextDoesntContainFormat()
{
// Arrange
- var resourceExecutingContext = CreateResourceExecutingContext(new IFilter[] { });
- var filter = new FormatFilterAttribute();
+ var mockObjects = new MockObjects();
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { });
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -179,14 +192,17 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var produces = new ProducesAttribute(contentType, new string[] { "application/foo", "text/bar" });
- var context = CreateResourceExecutingContext(new IFilter[] { produces }, format, place);
- var filter = new FormatFilterAttribute();
+ var mockObjects = new MockObjects(format, place);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { produces });
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
- filter.OnResourceExecuting(context);
+ filter.OnResourceExecuting(resourceExecutingContext);
// Assert
- Assert.Null(context.Result);
+ Assert.Null(resourceExecutingContext.Result);
}
[Fact]
@@ -194,18 +210,21 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var produces = new ProducesAttribute("application/xml;version=1", new string [] { });
- var context = CreateResourceExecutingContext(new IFilter[] { produces }, "xml", FormatSource.RouteData);
- var options = context.HttpContext.RequestServices.GetService>();
+ var mockObjects = new MockObjects("xml", FormatSource.RouteData);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { produces });
+ var options = mockObjects.MockServiceProvider.GetService>();
options.Options.FormatterMappings.SetMediaTypeMappingForFormat(
"xml",
MediaTypeHeaderValue.Parse("application/xml"));
- var filter = new FormatFilterAttribute();
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
- filter.OnResourceExecuting(context);
+ filter.OnResourceExecuting(resourceExecutingContext);
// Assert
- Assert.Null(context.Result);
+ Assert.Null(resourceExecutingContext.Result);
}
[Fact]
@@ -213,18 +232,22 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var produces = new ProducesAttribute("application/*", new string[] { });
- var context = CreateResourceExecutingContext(new IFilter[] { produces }, "xml", FormatSource.RouteData);
- var options = context.HttpContext.RequestServices.GetService>();
+
+ var mockObjects = new MockObjects("xml", FormatSource.RouteData);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { produces });
+ var options = mockObjects.MockServiceProvider.GetService>();
options.Options.FormatterMappings.SetMediaTypeMappingForFormat(
"xml",
MediaTypeHeaderValue.Parse("application/xml"));
- var filter = new FormatFilterAttribute();
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
- filter.OnResourceExecuting(context);
+ filter.OnResourceExecuting(resourceExecutingContext);
// Assert
- Assert.Null(context.Result);
+ Assert.Null(resourceExecutingContext.Result);
}
[Fact]
@@ -232,42 +255,50 @@ namespace Microsoft.AspNet.Mvc
{
// Arrange
var produces = new ProducesAttribute("application/xml", new string[] { });
- var context = CreateResourceExecutingContext(new IFilter[] { produces }, "xml", FormatSource.RouteData);
- var options = context.HttpContext.RequestServices.GetService>();
+ var mockObjects = new MockObjects("xml", FormatSource.RouteData);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { produces });
+ var options = mockObjects.MockServiceProvider.GetService>();
options.Options.FormatterMappings.SetMediaTypeMappingForFormat(
- "xml",
+ "xml",
MediaTypeHeaderValue.Parse("application/xml;version=1"));
- var filter = new FormatFilterAttribute();
+
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
- filter.OnResourceExecuting(context);
+ filter.OnResourceExecuting(resourceExecutingContext);
// Assert
- var actionResult = context.Result;
+ var actionResult = resourceExecutingContext.Result;
Assert.IsType(actionResult);
}
[Theory]
- [InlineData("json", FormatSource.RouteData, "application/json")]
- [InlineData("json", FormatSource.QueryData, "application/json")]
+ [InlineData("json", FormatSource.RouteData)]
+ [InlineData("json", FormatSource.QueryData)]
public void FormatFilter_ContextContainsFormat_ContainsProducesFilter_Conflicting(
string format,
- FormatSource place,
- string contentType)
+ FormatSource place)
{
// Arrange
- var mediaType = MediaTypeHeaderValue.Parse(contentType);
var produces = new ProducesAttribute("application/xml", new string[] { "application/foo", "text/bar" });
- var context = CreateResourceExecutingContext(new IFilter[] { produces }, format, place);
- var filter = new FormatFilterAttribute();
+ var mockObjects = new MockObjects(format, place);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { produces });
+ var options = mockObjects.MockServiceProvider.GetService>();
+ options.Options.FormatterMappings.SetMediaTypeMappingForFormat(
+ "xml",
+ MediaTypeHeaderValue.Parse("application/xml"));
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
+
// Act
- filter.OnResourceExecuting(context);
+ filter.OnResourceExecuting(resourceExecutingContext);
// Assert
- var result = Assert.IsType(context.Result);
+ var result = Assert.IsType(resourceExecutingContext.Result);
}
-
+
[Theory]
[InlineData("", FormatSource.RouteData)]
[InlineData(null, FormatSource.QueryData)]
@@ -277,12 +308,11 @@ namespace Microsoft.AspNet.Mvc
string format,
FormatSource place)
{
- // Arrange
- var resourceExecutingContext = CreateResourceExecutingContext(
- new IFilter[] { },
- format,
- place);
- var filter = new FormatFilterAttribute();
+ // Arrange
+ var mockObjects = new MockObjects(format, place);
+ var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilter[] { });
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
// Act
filter.OnResourceExecuting(resourceExecutingContext);
@@ -301,99 +331,14 @@ namespace Microsoft.AspNet.Mvc
FormatSource place,
bool expected)
{
- // Arrange
- var resultExecutingContext = CreateResultExecutingContext(format, place);
- var filter = new FormatFilterAttribute();
+ // Arrange
+ var mockObjects = new MockObjects(format, place);
+ var resultExecutingContext = mockObjects.CreateResultExecutingContext();
+ var filterAttribute = new FormatFilterAttribute();
+ var filter = (FormatFilter)filterAttribute.CreateInstance(mockObjects.MockServiceProvider);
- // Act
- var isActive = filter.IsActive(resultExecutingContext);
-
- // Assert
- Assert.Equal(expected, isActive);
- }
-
- private static ResourceExecutingContext CreateResourceExecutingContext(
- IFilter[] filters,
- string format = null,
- FormatSource? place = null)
- {
- if (format == null || place == null)
- {
- var context = new ResourceExecutingContext(
- CreateActionContext(),
- filters);
- return context;
- }
-
- var context1 = new ResourceExecutingContext(
- CreateActionContext(format, place),
- filters);
- return context1;
- }
-
- private static ResultExecutingContext CreateResultExecutingContext(
- string format = null,
- FormatSource? place = null)
- {
- if (format == null && place == null)
- {
- return new ResultExecutingContext(
- new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
- new IFilter[] { },
- new ObjectResult("Some Value"),
- controller: new object());
- }
-
- return new ResultExecutingContext(
- CreateActionContext(format, place),
- new IFilter[] { },
- new ObjectResult("Some Value"),
- controller: new object());
- }
-
- private static ActionContext CreateActionContext(string format = null, FormatSource? place = null)
- {
- var httpContext = CreateMockHttpContext();
- var data = new RouteData();
-
- if (place == FormatSource.RouteData || place == FormatSource.RouteAndQueryData)
- {
- data.Values.Add("format", format);
- httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
- }
-
- if (place == FormatSource.QueryData || place == FormatSource.RouteAndQueryData)
- {
- httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
- httpContext.Setup(c => c.Request.Query["format"]).Returns(format);
- }
- else if (place == null && format == null)
- {
- httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
- }
-
- return new ActionContext(httpContext.Object, data, new ActionDescriptor());
- }
-
- private static Mock CreateMockHttpContext()
- {
- var options = new MvcOptions();
- MvcOptionsSetup.ConfigureMvc(options);
- var mvcOptions = new Mock>();
- mvcOptions.Setup(o => o.Options).Returns(options);
-
- var serviceProvider = new Mock();
- serviceProvider
- .Setup(s => s.GetService(It.Is(t => t == typeof(IOptions))))
- .Returns(mvcOptions.Object);
-
- var httpContext = new Mock();
- httpContext
- .Setup(c => c.RequestServices)
- .Returns(serviceProvider.Object);
-
- httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
- return httpContext;
+ // Act and Assert
+ Assert.Equal(expected, filter.IsActive);
}
private static void AssertMediaTypesEqual(
@@ -411,6 +356,108 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(item.Value, NameValueHeaderValue.Find(actualMediaType.Parameters, item.Name).Value);
}
}
+
+ public class MockObjects
+ {
+ public IServiceProvider MockServiceProvider { get; private set; }
+ public HttpContext MockHttpContext { get; private set; }
+ public ActionContext MockActionContext { get; private set; }
+
+ public MockObjects(string format = null, FormatSource? place = null)
+ {
+ var httpContext = new Mock();
+ MockServiceProvider = CreateMockServiceProvider(httpContext, format, place);
+
+ httpContext
+ .Setup(c => c.RequestServices)
+ .Returns(MockServiceProvider);
+
+ httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
+
+ MockHttpContext = httpContext.Object;
+ //MockActionContext = CreateMockActionContext(httpContext, format, place);
+ }
+
+ public ResourceExecutingContext CreateResourceExecutingContext(IFilter[] filters)
+ {
+ var context = new ResourceExecutingContext(
+ MockActionContext,
+ filters);
+ return context;
+ }
+
+ public ResultExecutingContext CreateResultExecutingContext()
+ {
+ return new ResultExecutingContext(
+ MockActionContext,
+ new IFilter[] { },
+ new ObjectResult("Some Value"),
+ controller: new object());
+ }
+
+ private ActionContext CreateMockActionContext(
+ Mock httpContext,
+ string format,
+ FormatSource? place)
+ {
+ var data = new RouteData();
+
+ if (place == FormatSource.RouteData || place == FormatSource.RouteAndQueryData)
+ {
+ data.Values.Add("format", format);
+ httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
+ }
+
+ if (place == FormatSource.QueryData || place == FormatSource.RouteAndQueryData)
+ {
+ httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
+ httpContext.Setup(c => c.Request.Query["format"]).Returns(format);
+ }
+ else if (place == null && format == null)
+ {
+ httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
+ }
+
+ return new ActionContext(httpContext.Object, data, new ActionDescriptor());
+ }
+
+ private IServiceProvider CreateMockServiceProvider(
+ Mock httpContext,
+ string format = null,
+ FormatSource? place = null)
+ {
+ // Setup options on mock service provider
+ var options = new MvcOptions();
+ //MvcOptionsSetup.ConfigureMvc(options);
+
+ // Set up default output formatters.
+ options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
+ options.OutputFormatters.Add(new StringOutputFormatter());
+ options.OutputFormatters.Add(new JsonOutputFormatter());
+
+ // Set up default mapping for json extensions to content type
+ options.FormatterMappings.SetMediaTypeMappingForFormat("json", MediaTypeHeaderValue.Parse("application/json"));
+
+ var mvcOptions = new Mock>();
+ mvcOptions.Setup(o => o.Options).Returns(options);
+
+ var serviceProvider = new Mock();
+ serviceProvider
+ .Setup(s => s.GetService(It.Is(t => t == typeof(IOptions))))
+ .Returns(mvcOptions.Object);
+
+ // Setup MVC services on mock service provider
+ MockActionContext = CreateMockActionContext(httpContext, format, place);
+ var scopedInstance = new Mock>();
+ scopedInstance.Setup(s => s.Value).Returns(MockActionContext);
+
+ serviceProvider
+ .Setup(s => s.GetService(It.Is(t => t == typeof(IScopedInstance))))
+ .Returns(scopedInstance.Object);
+
+ return serviceProvider.Object;
+ }
+ }
#endif
}
}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/ProducesAttributeTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/ProducesAttributeTests.cs
index 6b9147d16c..d056dbd575 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Filters/ProducesAttributeTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Filters/ProducesAttributeTests.cs
@@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Mvc.Test
ValidateMediaType(mediaType1, objectResult.ContentTypes[0]);
ValidateMediaType(mediaType2, objectResult.ContentTypes[1]);
}
-
+
[Fact]
public async Task ProducesContentAttribute_FormatFilterAttribute_NotActive()
{
@@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc.Test
var producesContentAttribute = new ProducesAttribute("application/xml");
var formatFilter = new Mock();
- formatFilter.Setup(f => f.IsActive(It.IsAny()))
+ formatFilter.Setup(f => f.IsActive)
.Returns(false);
var filters = new IFilter[] { producesContentAttribute, formatFilter.Object };
@@ -69,7 +69,7 @@ namespace Microsoft.AspNet.Mvc.Test
var producesContentAttribute = new ProducesAttribute("application/xml");
var formatFilter = new Mock();
- formatFilter.Setup(f => f.IsActive(It.IsAny()))
+ formatFilter.Setup(f => f.IsActive)
.Returns(true);
var filters = new IFilter[] { producesContentAttribute, formatFilter.Object };