FormatFilter overrides content type set explicitly by the developer
This commit is contained in:
parent
aab051a20f
commit
7a955bcbc0
|
|
@ -15,7 +15,7 @@ namespace FormatFilterSample.Web
|
||||||
// Set up application services
|
// Set up application services
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddMvc(options =>
|
var mvcBuilder = services.AddMvc(options =>
|
||||||
{
|
{
|
||||||
var formatFilter = new FormatFilterAttribute();
|
var formatFilter = new FormatFilterAttribute();
|
||||||
options.Filters.Add(formatFilter);
|
options.Filters.Add(formatFilter);
|
||||||
|
|
@ -28,6 +28,8 @@ namespace FormatFilterSample.Web
|
||||||
"custom",
|
"custom",
|
||||||
MediaTypeHeaderValue.Parse("application/custom"));
|
MediaTypeHeaderValue.Parse("application/custom"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mvcBuilder.AddXmlDataContractSerializerFormatters();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
||||||
|
"Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-*",
|
||||||
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*"
|
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,22 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectResult = context.Result as ObjectResult;
|
var objectResult = context.Result as ObjectResult;
|
||||||
if (objectResult != null)
|
if (objectResult == null)
|
||||||
{
|
{
|
||||||
var contentType = _options.FormatterMappings.GetMediaTypeMappingForFormat(format);
|
return;
|
||||||
objectResult.ContentTypes.Clear();
|
|
||||||
objectResult.ContentTypes.Add(contentType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the action sets a single content type, then its takes precedence over the user
|
||||||
|
// supplied content type based on format mapping.
|
||||||
|
if ((objectResult.ContentTypes != null && objectResult.ContentTypes.Count == 1) ||
|
||||||
|
!string.IsNullOrEmpty(context.HttpContext.Response.ContentType))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentType = _options.FormatterMappings.GetMediaTypeMappingForFormat(format);
|
||||||
|
objectResult.ContentTypes.Clear();
|
||||||
|
objectResult.ContentTypes.Add(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
{
|
{
|
||||||
// If the format is present in both route and query data, the one in route data wins
|
// If the format is present in both route and query data, the one in route data wins
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
var mediaType = MediaTypeHeaderValue.Parse("application/json");
|
var mediaType = MediaTypeHeaderValue.Parse("application/json");
|
||||||
var mockObjects = new MockObjects("json", FormatSource.RouteData);
|
var mockObjects = new MockObjects("json", FormatSource.RouteData);
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext.Setup(c => c.Response).Returns(new Mock<HttpResponse>().Object);
|
||||||
|
|
||||||
// Query contains xml
|
// Query contains xml
|
||||||
httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
|
httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true);
|
||||||
httpContext.Setup(c => c.Request.Query["format"]).Returns("xml");
|
httpContext.Setup(c => c.Request.Query["format"]).Returns("xml");
|
||||||
|
|
||||||
|
|
@ -106,7 +107,7 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
FormatSource place,
|
FormatSource place,
|
||||||
string contentType)
|
string contentType)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mediaType = MediaTypeHeaderValue.Parse(contentType);
|
var mediaType = MediaTypeHeaderValue.Parse(contentType);
|
||||||
|
|
||||||
var mockObjects = new MockObjects(format, place);
|
var mockObjects = new MockObjects(format, place);
|
||||||
|
|
@ -226,7 +227,7 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
// Act
|
// Act
|
||||||
filter.OnResourceExecuting(resourceExecutingContext);
|
filter.OnResourceExecuting(resourceExecutingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var actionResult = resourceExecutingContext.Result;
|
var actionResult = resourceExecutingContext.Result;
|
||||||
Assert.IsType<HttpNotFoundResult>(actionResult);
|
Assert.IsType<HttpNotFoundResult>(actionResult);
|
||||||
}
|
}
|
||||||
|
|
@ -298,6 +299,73 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
Assert.Equal(expected, filter.GetFormat(context));
|
Assert.Equal(expected, filter.GetFormat(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatFilter_ExplicitContentType_SetOnObjectResult_TakesPrecedence()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaType = MediaTypeHeaderValue.Parse("application/foo");
|
||||||
|
var mockObjects = new MockObjects("json", FormatSource.QueryData);
|
||||||
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext.Setup(c => c.Response).Returns(new Mock<HttpResponse>().Object);
|
||||||
|
httpContext.Setup(c => c.Request.Query["format"]).Returns("json");
|
||||||
|
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
||||||
|
var objectResult = new ObjectResult("Hello!");
|
||||||
|
objectResult.ContentTypes.Add(new MediaTypeHeaderValue("application/foo"));
|
||||||
|
var resultExecutingContext = new ResultExecutingContext(
|
||||||
|
actionContext,
|
||||||
|
new IFilterMetadata[] { },
|
||||||
|
objectResult,
|
||||||
|
controller: new object());
|
||||||
|
|
||||||
|
var resourceExecutingContext = new ResourceExecutingContext(
|
||||||
|
actionContext,
|
||||||
|
new IFilterMetadata[] { });
|
||||||
|
|
||||||
|
var filter = new FormatFilter(mockObjects.OptionsManager);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
filter.OnResourceExecuting(resourceExecutingContext);
|
||||||
|
filter.OnResultExecuting(resultExecutingContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var result = Assert.IsType<ObjectResult>(resultExecutingContext.Result);
|
||||||
|
Assert.Equal(1, result.ContentTypes.Count);
|
||||||
|
AssertMediaTypesEqual(mediaType, result.ContentTypes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatFilter_ExplicitContentType_SetOnResponse_TakesPrecedence()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaType = MediaTypeHeaderValue.Parse("application/foo");
|
||||||
|
var mockObjects = new MockObjects("json", FormatSource.QueryData);
|
||||||
|
var response = new Mock<HttpResponse>();
|
||||||
|
response.Setup(r => r.ContentType).Returns("application/foo");
|
||||||
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext.Setup(c => c.Response).Returns(response.Object);
|
||||||
|
httpContext.Setup(c => c.Request.Query["format"]).Returns("json");
|
||||||
|
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
||||||
|
var resultExecutingContext = new ResultExecutingContext(
|
||||||
|
actionContext,
|
||||||
|
new IFilterMetadata[] { },
|
||||||
|
new ObjectResult("Hello!"),
|
||||||
|
controller: new object());
|
||||||
|
|
||||||
|
var resourceExecutingContext = new ResourceExecutingContext(
|
||||||
|
actionContext,
|
||||||
|
new IFilterMetadata[] { });
|
||||||
|
|
||||||
|
var filter = new FormatFilter(mockObjects.OptionsManager);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
filter.OnResourceExecuting(resourceExecutingContext);
|
||||||
|
filter.OnResultExecuting(resultExecutingContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var result = Assert.IsType<ObjectResult>(resultExecutingContext.Result);
|
||||||
|
Assert.Equal(0, result.ContentTypes.Count);
|
||||||
|
}
|
||||||
|
|
||||||
private static void AssertMediaTypesEqual(
|
private static void AssertMediaTypesEqual(
|
||||||
MediaTypeHeaderValue expectedMediaType,
|
MediaTypeHeaderValue expectedMediaType,
|
||||||
MediaTypeHeaderValue actualMediaType)
|
MediaTypeHeaderValue actualMediaType)
|
||||||
|
|
@ -326,6 +394,7 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
||||||
{
|
{
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
|
httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(false);
|
||||||
|
httpContext.Setup(c => c.Response).Returns(new Mock<HttpResponse>().Object);
|
||||||
MockHttpContext = httpContext.Object;
|
MockHttpContext = httpContext.Object;
|
||||||
|
|
||||||
Initialize(httpContext, format, place);
|
Initialize(httpContext, format, place);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue