[Fixes #1791]Remove XML formatter from defaults
This commit is contained in:
parent
9aff289dfe
commit
02f4ca9f05
|
|
@ -50,6 +50,8 @@ namespace MvcSample.Web
|
||||||
services.Configure<MvcOptions>(options =>
|
services.Configure<MvcOptions>(options =>
|
||||||
{
|
{
|
||||||
options.Filters.Add(typeof(PassThroughAttribute), order: 17);
|
options.Filters.Add(typeof(PassThroughAttribute), order: 17);
|
||||||
|
|
||||||
|
options.AddXmlDataContractSerializerFormatter();
|
||||||
});
|
});
|
||||||
services.Configure<RazorViewEngineOptions>(options =>
|
services.Configure<RazorViewEngineOptions>(options =>
|
||||||
{
|
{
|
||||||
|
|
@ -90,6 +92,7 @@ namespace MvcSample.Web
|
||||||
services.Configure<MvcOptions>(options =>
|
services.Configure<MvcOptions>(options =>
|
||||||
{
|
{
|
||||||
options.Filters.Add(typeof(PassThroughAttribute), order: 17);
|
options.Filters.Add(typeof(PassThroughAttribute), order: 17);
|
||||||
|
options.AddXmlDataContractSerializerFormatter();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,15 @@ namespace TagHelperSample.Web
|
||||||
app.UseServices(services =>
|
app.UseServices(services =>
|
||||||
{
|
{
|
||||||
services.AddMvc();
|
services.AddMvc();
|
||||||
|
|
||||||
// Setup services with a test AssemblyProvider so that only the sample's assemblies are loaded. This
|
// Setup services with a test AssemblyProvider so that only the sample's assemblies are loaded. This
|
||||||
// prevents loading controllers from other assemblies when the sample is used in functional tests.
|
// prevents loading controllers from other assemblies when the sample is used in functional tests.
|
||||||
services.AddTransient<IAssemblyProvider, TestAssemblyProvider<Startup>>();
|
services.AddTransient<IAssemblyProvider, TestAssemblyProvider<Startup>>();
|
||||||
|
|
||||||
|
services.Configure<MvcOptions>(options =>
|
||||||
|
{
|
||||||
|
options.AddXmlDataContractSerializerFormatter();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
app.UseMvc();
|
app.UseMvc();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,9 @@
|
||||||
<DevelopmentServerPort>30540</DevelopmentServerPort>
|
<DevelopmentServerPort>30540</DevelopmentServerPort>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
|
@ -63,20 +64,43 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public virtual IOutputFormatter SelectFormatter(OutputFormatterContext formatterContext,
|
public virtual IOutputFormatter SelectFormatter(OutputFormatterContext formatterContext,
|
||||||
IEnumerable<IOutputFormatter> formatters)
|
IEnumerable<IOutputFormatter> formatters)
|
||||||
{
|
{
|
||||||
var incomingAcceptHeader = formatterContext.ActionContext.HttpContext.Request.GetTypedHeaders().Accept;
|
var incomingAcceptHeaderMediaTypes = formatterContext.ActionContext.HttpContext.Request.GetTypedHeaders().Accept ??
|
||||||
var sortedAcceptHeaders = SortMediaTypeHeaderValues(incomingAcceptHeader)
|
new MediaTypeHeaderValue[] { };
|
||||||
.Where(header => header.Quality != HeaderQuality.NoMatch)
|
|
||||||
.ToArray();
|
// By default we want to ignore considering accept headers for content negotiation when
|
||||||
|
// they have a media type like */* in them. Browsers typically have these media types.
|
||||||
|
// In these cases we would want the first formatter in the list of output formatters to
|
||||||
|
// write the response. This default behavior can be changed through options, so checking here.
|
||||||
|
var options = formatterContext.ActionContext.HttpContext
|
||||||
|
.RequestServices
|
||||||
|
.GetRequiredService<IOptions<MvcOptions>>()
|
||||||
|
.Options;
|
||||||
|
|
||||||
|
var respectAcceptHeader = true;
|
||||||
|
if (options.RespectBrowserAcceptHeader == false
|
||||||
|
&& incomingAcceptHeaderMediaTypes.Any(mediaType => mediaType.MatchesAllTypes))
|
||||||
|
{
|
||||||
|
respectAcceptHeader = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<MediaTypeHeaderValue> sortedAcceptHeaderMediaTypes = null;
|
||||||
|
if (respectAcceptHeader)
|
||||||
|
{
|
||||||
|
sortedAcceptHeaderMediaTypes = SortMediaTypeHeaderValues(incomingAcceptHeaderMediaTypes)
|
||||||
|
.Where(header => header.Quality != HeaderQuality.NoMatch);
|
||||||
|
}
|
||||||
|
|
||||||
IOutputFormatter selectedFormatter = null;
|
IOutputFormatter selectedFormatter = null;
|
||||||
|
|
||||||
if (ContentTypes == null || ContentTypes.Count == 0)
|
if (ContentTypes == null || ContentTypes.Count == 0)
|
||||||
{
|
{
|
||||||
// Select based on sorted accept headers.
|
if (respectAcceptHeader)
|
||||||
selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
|
{
|
||||||
formatterContext,
|
// Select based on sorted accept headers.
|
||||||
formatters,
|
selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
|
||||||
sortedAcceptHeaders);
|
formatterContext,
|
||||||
|
formatters,
|
||||||
|
sortedAcceptHeaderMediaTypes);
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedFormatter == null)
|
if (selectedFormatter == null)
|
||||||
{
|
{
|
||||||
|
|
@ -124,16 +148,15 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Filter and remove accept headers which cannot support any of the user specified content types.
|
if (respectAcceptHeader)
|
||||||
var filteredAndSortedAcceptHeaders = sortedAcceptHeaders
|
|
||||||
.Where(acceptHeader =>
|
|
||||||
ContentTypes
|
|
||||||
.Any(contentType =>
|
|
||||||
contentType.IsSubsetOf(acceptHeader)))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
if (filteredAndSortedAcceptHeaders.Length > 0)
|
|
||||||
{
|
{
|
||||||
|
// Filter and remove accept headers which cannot support any of the user specified content types.
|
||||||
|
var filteredAndSortedAcceptHeaders = sortedAcceptHeaderMediaTypes
|
||||||
|
.Where(acceptHeader =>
|
||||||
|
ContentTypes
|
||||||
|
.Any(contentType =>
|
||||||
|
contentType.IsSubsetOf(acceptHeader)));
|
||||||
|
|
||||||
selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
|
selectedFormatter = SelectFormatterUsingSortedAcceptHeaders(
|
||||||
formatterContext,
|
formatterContext,
|
||||||
formatters,
|
formatters,
|
||||||
|
|
@ -194,20 +217,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return selectedFormatter;
|
return selectedFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MediaTypeHeaderValue[] SortMediaTypeHeaderValues
|
private static IEnumerable<MediaTypeHeaderValue> SortMediaTypeHeaderValues(
|
||||||
(IEnumerable<MediaTypeHeaderValue> headerValues)
|
IEnumerable<MediaTypeHeaderValue> headerValues)
|
||||||
{
|
{
|
||||||
if (headerValues == null)
|
|
||||||
{
|
|
||||||
return new MediaTypeHeaderValue[] { };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
|
// Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
|
||||||
// are quite expensive so OrderBy() performs better.
|
// are quite expensive so OrderBy() performs better.
|
||||||
return headerValues.OrderByDescending(headerValue =>
|
return headerValues.OrderByDescending(headerValue =>
|
||||||
headerValue,
|
headerValue,
|
||||||
MediaTypeHeaderValueComparer.QualityComparer)
|
MediaTypeHeaderValueComparer.QualityComparer);
|
||||||
.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IOutputFormatter> GetDefaultFormatters(ActionContext context)
|
private IEnumerable<IOutputFormatter> GetDefaultFormatters(ActionContext context)
|
||||||
|
|
|
||||||
|
|
@ -125,5 +125,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// the <see cref="ApplicationModel"/> when discovering actions.
|
/// the <see cref="ApplicationModel"/> when discovering actions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<IApplicationModelConvention> ApplicationModelConventions { get; private set; }
|
public List<IApplicationModelConvention> ApplicationModelConventions { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the flag which causes content negotiation to ignore Accept header
|
||||||
|
/// when it contains the media type */*. <see langword="false"/> by default.
|
||||||
|
/// </summary>
|
||||||
|
public bool RespectBrowserAcceptHeader { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
public static class MvcOptionsExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds <see cref="XmlDataContractSerializerInputFormatter"/> and
|
||||||
|
/// <see cref="XmlDataContractSerializerOutputFormatter"/> to the input and output formatter
|
||||||
|
/// collections respectively.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The MvcOptions</param>
|
||||||
|
public static void AddXmlDataContractSerializerFormatter([NotNull] this MvcOptions options)
|
||||||
|
{
|
||||||
|
options.OutputFormatters.Add(
|
||||||
|
new XmlDataContractSerializerOutputFormatter(XmlOutputFormatter.GetDefaultXmlWriterSettings()));
|
||||||
|
|
||||||
|
options.InputFormatters.Add(new XmlDataContractSerializerInputFormatter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -44,12 +44,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
|
options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
|
||||||
options.OutputFormatters.Add(new TextPlainFormatter());
|
options.OutputFormatters.Add(new TextPlainFormatter());
|
||||||
options.OutputFormatters.Add(new JsonOutputFormatter());
|
options.OutputFormatters.Add(new JsonOutputFormatter());
|
||||||
options.OutputFormatters.Add(
|
|
||||||
new XmlDataContractSerializerOutputFormatter(XmlOutputFormatter.GetDefaultXmlWriterSettings()));
|
|
||||||
|
|
||||||
// Set up default input formatters.
|
// Set up default input formatters.
|
||||||
options.InputFormatters.Add(new JsonInputFormatter());
|
options.InputFormatters.Add(new JsonInputFormatter());
|
||||||
options.InputFormatters.Add(new XmlDataContractSerializerInputFormatter());
|
|
||||||
|
|
||||||
// Set up ValueProviders
|
// Set up ValueProviders
|
||||||
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
|
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Http.Core.Collections;
|
using Microsoft.AspNet.Http.Core.Collections;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -92,6 +93,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var services = new Mock<IServiceProvider>();
|
var services = new Mock<IServiceProvider>();
|
||||||
services.Setup(p => p.GetService(typeof(IOutputFormattersProvider))).Returns(new TestOutputFormatterProvider());
|
services.Setup(p => p.GetService(typeof(IOutputFormattersProvider))).Returns(new TestOutputFormatterProvider());
|
||||||
httpContext.RequestServices = services.Object;
|
httpContext.RequestServices = services.Object;
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
services.Setup(p => p.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return httpContext;
|
return httpContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -97,6 +98,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
httpContext.Setup(o => o.Request)
|
httpContext.Setup(o => o.Request)
|
||||||
.Returns(request);
|
.Returns(request);
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
httpContext.Setup(o => o.Response)
|
httpContext.Setup(o => o.Response)
|
||||||
.Returns(response);
|
.Returns(response);
|
||||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -69,7 +70,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
.Returns(response);
|
.Returns(response);
|
||||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(new TestOutputFormatterProvider());
|
.Returns(new TestOutputFormatterProvider());
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
return httpContext.Object;
|
return httpContext.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
httpResponse.SetupGet(r => r.Body).Returns(stream);
|
httpResponse.SetupGet(r => r.Body).Returns(stream);
|
||||||
|
|
||||||
var actionContext = CreateMockActionContext(httpResponse.Object, acceptHeader);
|
var actionContext = CreateMockActionContext(httpResponse.Object, acceptHeader);
|
||||||
|
|
||||||
var result = new ObjectResult(input);
|
var result = new ObjectResult(input);
|
||||||
|
|
||||||
// Set the content type property explicitly.
|
// Set the content type property explicitly.
|
||||||
|
|
@ -467,10 +468,148 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
Assert.Equal(tempStream.ToArray(), ((MemoryStream)actionContext.HttpContext.Response.Body).ToArray());
|
Assert.Equal(tempStream.ToArray(), ((MemoryStream)actionContext.HttpContext.Response.Body).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActionContext CreateMockActionContext(HttpResponse response = null,
|
[Theory]
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||||
|
"application/json; charset=utf-8")] //Chrome
|
||||||
|
[InlineData("text/html, application/xhtml+xml, */*",
|
||||||
|
"application/json; charset=utf-8")] //IE
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||||
|
"application/json; charset=utf-8")] //Firefox
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||||
|
"application/json; charset=utf-8")] //Safari
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||||
|
"application/json; charset=utf-8")] //Opera
|
||||||
|
[InlineData("*/*", @"application/json; charset=utf-8")]
|
||||||
|
[InlineData("text/html,*/*;q=0.8,application/xml;q=0.9",
|
||||||
|
"application/json; charset=utf-8")]
|
||||||
|
public async Task ObjectResult_SelectDefaultFormatter_OnAllMediaRangeAcceptHeaderMediaType(
|
||||||
|
string acceptHeader,
|
||||||
|
string expectedResponseContentType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var objectResult = new ObjectResult(new Person() { Name = "John" });
|
||||||
|
var outputFormatters = new IOutputFormatter[] {
|
||||||
|
new HttpNoContentOutputFormatter(),
|
||||||
|
new TextPlainFormatter(),
|
||||||
|
new JsonOutputFormatter(),
|
||||||
|
new XmlDataContractSerializerOutputFormatter(XmlSerializerOutputFormatter.GetDefaultXmlWriterSettings())
|
||||||
|
};
|
||||||
|
var response = GetMockHttpResponse();
|
||||||
|
|
||||||
|
var actionContext = CreateMockActionContext(
|
||||||
|
outputFormatters,
|
||||||
|
response.Object,
|
||||||
|
requestAcceptHeader: acceptHeader);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await objectResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.VerifySet(resp => resp.ContentType = expectedResponseContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||||
|
"application/xml; charset=utf-8")] //Chrome
|
||||||
|
[InlineData("text/html, application/xhtml+xml, */*",
|
||||||
|
"application/json; charset=utf-8")] //IE
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||||
|
"application/xml; charset=utf-8")] //Firefox
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||||
|
"application/xml; charset=utf-8")] //Safari
|
||||||
|
[InlineData("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||||
|
"application/xml; charset=utf-8")] //Opera
|
||||||
|
[InlineData("*/*",
|
||||||
|
"application/json; charset=utf-8")]
|
||||||
|
[InlineData("text/html,*/*;q=0.8,application/xml;q=0.9",
|
||||||
|
"application/xml; charset=utf-8")]
|
||||||
|
public async Task ObjectResult_PerformsContentNegotiation_OnAllMediaRangeAcceptHeaderMediaType(
|
||||||
|
string acceptHeader,
|
||||||
|
string expectedResponseContentType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var objectResult = new ObjectResult(new Person() { Name = "John" });
|
||||||
|
var outputFormatters = new IOutputFormatter[] {
|
||||||
|
new HttpNoContentOutputFormatter(),
|
||||||
|
new TextPlainFormatter(),
|
||||||
|
new JsonOutputFormatter(),
|
||||||
|
new XmlDataContractSerializerOutputFormatter(XmlSerializerOutputFormatter.GetDefaultXmlWriterSettings())
|
||||||
|
};
|
||||||
|
var response = GetMockHttpResponse();
|
||||||
|
|
||||||
|
var actionContext = CreateMockActionContext(
|
||||||
|
outputFormatters,
|
||||||
|
response.Object,
|
||||||
|
requestAcceptHeader: acceptHeader,
|
||||||
|
respectBrowserAcceptHeader: true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await objectResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.VerifySet(resp => resp.ContentType = expectedResponseContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("application/xml;q=0.9,text/plain;q=0.5", "application/xml; charset=utf-8", false)]
|
||||||
|
[InlineData("application/xml;q=0.9,*/*;q=0.5", "application/json; charset=utf-8", false)]
|
||||||
|
[InlineData("application/xml;q=0.9,text/plain;q=0.5", "application/xml; charset=utf-8", true)]
|
||||||
|
[InlineData("application/xml;q=0.9,*/*;q=0.5", "application/xml; charset=utf-8", true)]
|
||||||
|
public async Task ObjectResult_WildcardAcceptMediaType_AndExplicitResponseContentType(
|
||||||
|
string acceptHeader,
|
||||||
|
string expectedResponseContentType,
|
||||||
|
bool respectBrowserAcceptHeader)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var objectResult = new ObjectResult(new Person() { Name = "John" });
|
||||||
|
objectResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
|
||||||
|
objectResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
|
||||||
|
var outputFormatters = new IOutputFormatter[] {
|
||||||
|
new HttpNoContentOutputFormatter(),
|
||||||
|
new TextPlainFormatter(),
|
||||||
|
new JsonOutputFormatter(),
|
||||||
|
new XmlDataContractSerializerOutputFormatter(XmlSerializerOutputFormatter.GetDefaultXmlWriterSettings())
|
||||||
|
};
|
||||||
|
var response = GetMockHttpResponse();
|
||||||
|
|
||||||
|
var actionContext = CreateMockActionContext(
|
||||||
|
outputFormatters,
|
||||||
|
response.Object,
|
||||||
|
acceptHeader,
|
||||||
|
respectBrowserAcceptHeader: respectBrowserAcceptHeader);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await objectResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.VerifySet(resp => resp.ContentType = expectedResponseContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionContext CreateMockActionContext(
|
||||||
|
HttpResponse response = null,
|
||||||
string requestAcceptHeader = "application/*",
|
string requestAcceptHeader = "application/*",
|
||||||
string requestContentType = "application/json",
|
string requestContentType = "application/json",
|
||||||
string requestAcceptCharsetHeader = "")
|
string requestAcceptCharsetHeader = "",
|
||||||
|
bool respectBrowserAcceptHeader = false)
|
||||||
|
{
|
||||||
|
var formatters = new IOutputFormatter[] { new TextPlainFormatter(), new JsonOutputFormatter() };
|
||||||
|
|
||||||
|
return CreateMockActionContext(
|
||||||
|
formatters,
|
||||||
|
response: response,
|
||||||
|
requestAcceptHeader: requestAcceptHeader,
|
||||||
|
requestContentType: requestContentType,
|
||||||
|
requestAcceptCharsetHeader: requestAcceptCharsetHeader,
|
||||||
|
respectBrowserAcceptHeader: respectBrowserAcceptHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionContext CreateMockActionContext(
|
||||||
|
IEnumerable<IOutputFormatter> outputFormatters,
|
||||||
|
HttpResponse response = null,
|
||||||
|
string requestAcceptHeader = "application/*",
|
||||||
|
string requestContentType = "application/json",
|
||||||
|
string requestAcceptCharsetHeader = "",
|
||||||
|
bool respectBrowserAcceptHeader = false)
|
||||||
{
|
{
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
if (response != null)
|
if (response != null)
|
||||||
|
|
@ -490,7 +629,17 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
httpContext.Setup(o => o.Request).Returns(request);
|
httpContext.Setup(o => o.Request).Returns(request);
|
||||||
httpContext.Setup(o => o.RequestServices).Returns(GetServiceProvider());
|
httpContext.Setup(o => o.RequestServices).Returns(GetServiceProvider());
|
||||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(new TestOutputFormatterProvider());
|
.Returns(new TestOutputFormatterProvider(outputFormatters));
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions()
|
||||||
|
{
|
||||||
|
RespectBrowserAcceptHeader = respectBrowserAcceptHeader
|
||||||
|
});
|
||||||
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
return new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -551,17 +700,25 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
|
|
||||||
private class TestOutputFormatterProvider : IOutputFormattersProvider
|
private class TestOutputFormatterProvider : IOutputFormattersProvider
|
||||||
{
|
{
|
||||||
|
private readonly IEnumerable<IOutputFormatter> _formatters;
|
||||||
|
|
||||||
|
public TestOutputFormatterProvider(IEnumerable<IOutputFormatter> formatters)
|
||||||
|
{
|
||||||
|
_formatters = formatters;
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyList<IOutputFormatter> OutputFormatters
|
public IReadOnlyList<IOutputFormatter> OutputFormatters
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new List<IOutputFormatter>()
|
return _formatters.ToList();
|
||||||
{
|
|
||||||
new TextPlainFormatter(),
|
|
||||||
new JsonOutputFormatter()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Person
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -1957,6 +1958,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
.Returns(mockFormattersProvider.Object);
|
.Returns(mockFormattersProvider.Object);
|
||||||
httpResponse.Body = new MemoryStream();
|
httpResponse.Body = new MemoryStream();
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
var actionContext = new ActionContext(
|
var actionContext = new ActionContext(
|
||||||
httpContext: httpContext.Object,
|
httpContext: httpContext.Object,
|
||||||
routeData: new RouteData(),
|
routeData: new RouteData(),
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -192,6 +193,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(mockFormattersProvider.Object);
|
.Returns(mockFormattersProvider.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
// This is the ultimate fallback, it will be used if none of the formatters from options
|
// This is the ultimate fallback, it will be used if none of the formatters from options
|
||||||
// work.
|
// work.
|
||||||
if (enableFallback)
|
if (enableFallback)
|
||||||
|
|
|
||||||
|
|
@ -279,11 +279,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
if (optionsAccessor == null)
|
if (optionsAccessor == null)
|
||||||
{
|
{
|
||||||
var mockOptionsAccessor = new Mock<IOptions<MvcOptions>>();
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
mockOptionsAccessor.SetupGet(o => o.Options)
|
options.SetupGet(o => o.Options)
|
||||||
.Returns(new MvcOptions());
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
optionsAccessor = mockOptionsAccessor.Object;
|
optionsAccessor = options.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// 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.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.TestHost;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
|
{
|
||||||
|
public class RespectBrowserAcceptHeaderTests
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _provider = TestHelper.CreateServices(nameof(FormatterWebSite));
|
||||||
|
private readonly Action<IApplicationBuilder> _app = new FormatterWebSite.Startup().Configure;
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("application/xml,*/*;0.2")]
|
||||||
|
[InlineData("application/xml,*/*")]
|
||||||
|
public async Task AllMediaRangeAcceptHeader_FirstFormatterInListWritesResponse(string acceptHeader)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.CreateClient();
|
||||||
|
client.DefaultRequestHeaders.Add("Accept", acceptHeader);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await client.GetAsync("http://localhost/RespectBrowserAcceptHeader/EmployeeInfo");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotNull(response.Content.Headers.ContentType);
|
||||||
|
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString());
|
||||||
|
var responseData = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Equal("{\"Id\":10,\"Name\":\"John\"}", responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("application/xml,*/*;0.2")]
|
||||||
|
[InlineData("application/xml,*/*")]
|
||||||
|
public async Task AllMediaRangeAcceptHeader_ProducesAttributeIsHonored(string acceptHeader)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.CreateClient();
|
||||||
|
client.DefaultRequestHeaders.Add("Accept", acceptHeader);
|
||||||
|
var expectedResponseData = "<RespectBrowserAcceptHeaderController.Employee xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"" +
|
||||||
|
" xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite.Controllers\"><Id>20</Id><Name>Mike" +
|
||||||
|
"</Name></RespectBrowserAcceptHeaderController.Employee>";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await client.GetAsync("http://localhost/RespectBrowserAcceptHeader/EmployeeInfoWithProduces");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotNull(response.Content.Headers.ContentType);
|
||||||
|
Assert.Equal("application/xml; charset=utf-8", response.Content.Headers.ContentType.ToString());
|
||||||
|
var responseData = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Equal(expectedResponseData, responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("application/xml,*/*;0.2")]
|
||||||
|
[InlineData("application/xml,*/*")]
|
||||||
|
public async Task AllMediaRangeAcceptHeader_WithContentTypeHeader_ContentTypeIsHonored(string acceptHeader)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.CreateClient();
|
||||||
|
client.DefaultRequestHeaders.Add("Accept", acceptHeader);
|
||||||
|
var requestData = "<RespectBrowserAcceptHeaderController.Employee xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"" +
|
||||||
|
" xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite.Controllers\"><Id>35</Id><Name>Jimmy" +
|
||||||
|
"</Name></RespectBrowserAcceptHeaderController.Employee>";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await client.PostAsync("http://localhost/RespectBrowserAcceptHeader/CreateEmployee",
|
||||||
|
new StringContent(requestData, Encoding.UTF8, "application/xml"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotNull(response.Content.Headers.ContentType);
|
||||||
|
Assert.Equal("application/xml; charset=utf-8", response.Content.Headers.ContentType.ToString());
|
||||||
|
var responseData = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Equal(requestData, responseData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
|
@ -14,4 +14,9 @@
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
||||||
|
|
@ -83,11 +83,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
setup.Configure(mvcOptions);
|
setup.Configure(mvcOptions);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(4, mvcOptions.OutputFormatters.Count);
|
Assert.Equal(3, mvcOptions.OutputFormatters.Count);
|
||||||
Assert.IsType<HttpNoContentOutputFormatter>(mvcOptions.OutputFormatters[0].Instance);
|
Assert.IsType<HttpNoContentOutputFormatter>(mvcOptions.OutputFormatters[0].Instance);
|
||||||
Assert.IsType<TextPlainFormatter>(mvcOptions.OutputFormatters[1].Instance);
|
Assert.IsType<TextPlainFormatter>(mvcOptions.OutputFormatters[1].Instance);
|
||||||
Assert.IsType<JsonOutputFormatter>(mvcOptions.OutputFormatters[2].Instance);
|
Assert.IsType<JsonOutputFormatter>(mvcOptions.OutputFormatters[2].Instance);
|
||||||
Assert.IsType<XmlDataContractSerializerOutputFormatter>(mvcOptions.OutputFormatters[3].Instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -101,9 +100,8 @@ namespace Microsoft.AspNet.Mvc
|
||||||
setup.Configure(mvcOptions);
|
setup.Configure(mvcOptions);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(2, mvcOptions.InputFormatters.Count);
|
Assert.Equal(1, mvcOptions.InputFormatters.Count);
|
||||||
Assert.IsType<JsonInputFormatter>(mvcOptions.InputFormatters[0].Instance);
|
Assert.IsType<JsonInputFormatter>(mvcOptions.InputFormatters[0].Instance);
|
||||||
Assert.IsType<XmlDataContractSerializerInputFormatter>(mvcOptions.InputFormatters[1].Instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -122,6 +120,20 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.IsType<DataMemberModelValidatorProvider>(mvcOptions.ModelValidatorProviders[1].Instance);
|
Assert.IsType<DataMemberModelValidatorProvider>(mvcOptions.ModelValidatorProviders[1].Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Setup_IgnoresAcceptHeaderHavingWildCardMediaAndSubMediaTypes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mvcOptions = new MvcOptions();
|
||||||
|
var setup = new MvcOptionsSetup();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
setup.Configure(mvcOptions);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(mvcOptions.RespectBrowserAcceptHeader);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Setup_SetsUpExcludeFromValidationDelegates()
|
public void Setup_SetsUpExcludeFromValidationDelegates()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -73,6 +74,13 @@ namespace System.Web.Http
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(formatters.Object);
|
.Returns(formatters.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return services.Object;
|
return services.Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -73,6 +74,13 @@ namespace System.Web.Http
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(formatters.Object);
|
.Returns(formatters.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return services.Object;
|
return services.Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -86,6 +87,13 @@ namespace System.Web.Http
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(formatters.Object);
|
.Returns(formatters.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return services.Object;
|
return services.Object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -75,6 +76,13 @@ namespace System.Web.Http
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(formatters.Object);
|
.Returns(formatters.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return services.Object;
|
return services.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Core;
|
using Microsoft.AspNet.Http.Core;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.OptionsModel;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -48,6 +49,13 @@ namespace System.Web.Http
|
||||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||||
.Returns(formatters.Object);
|
.Returns(formatters.Object);
|
||||||
|
|
||||||
|
var options = new Mock<IOptions<MvcOptions>>();
|
||||||
|
options.SetupGet(o => o.Options)
|
||||||
|
.Returns(new MvcOptions());
|
||||||
|
|
||||||
|
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
||||||
|
.Returns(options.Object);
|
||||||
|
|
||||||
return services.Object;
|
return services.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
|
|
@ -16,6 +17,11 @@ namespace ActionResultsWebSite
|
||||||
app.UseServices(services =>
|
app.UseServices(services =>
|
||||||
{
|
{
|
||||||
services.AddMvc(configuration);
|
services.AddMvc(configuration);
|
||||||
|
|
||||||
|
services.Configure<MvcOptions>(options =>
|
||||||
|
{
|
||||||
|
options.AddXmlDataContractSerializerFormatter();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// 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 FormatterWebSite.Controllers
|
||||||
|
{
|
||||||
|
public class RespectBrowserAcceptHeaderController : Controller
|
||||||
|
{
|
||||||
|
[HttpGet]
|
||||||
|
public Employee EmployeeInfo()
|
||||||
|
{
|
||||||
|
return new Employee()
|
||||||
|
{
|
||||||
|
Id = 10,
|
||||||
|
Name = "John"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Produces("application/xml")]
|
||||||
|
public Employee EmployeeInfoWithProduces()
|
||||||
|
{
|
||||||
|
return new Employee()
|
||||||
|
{
|
||||||
|
Id = 20,
|
||||||
|
Name = "Mike"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult CreateEmployee([FromBody]Employee employee)
|
||||||
|
{
|
||||||
|
if(!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return HttpBadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ObjectResult(employee);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Employee
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,4 +15,9 @@
|
||||||
<DevelopmentServerPort>49634</DevelopmentServerPort>
|
<DevelopmentServerPort>49634</DevelopmentServerPort>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -24,6 +24,8 @@ namespace FormatterWebSite
|
||||||
{
|
{
|
||||||
options.ValidationExcludeFilters.Add(typeof(Developer));
|
options.ValidationExcludeFilters.Add(typeof(Developer));
|
||||||
options.ValidationExcludeFilters.Add(typeof(Supplier));
|
options.ValidationExcludeFilters.Add(typeof(Supplier));
|
||||||
|
|
||||||
|
options.AddXmlDataContractSerializerFormatter();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ namespace ModelBindingWebSite
|
||||||
{
|
{
|
||||||
m.MaxModelValidationErrors = 8;
|
m.MaxModelValidationErrors = 8;
|
||||||
m.ModelBinders.Insert(0, typeof(TestMetadataAwareBinder));
|
m.ModelBinders.Insert(0, typeof(TestMetadataAwareBinder));
|
||||||
|
|
||||||
|
m.AddXmlDataContractSerializerFormatter();
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<ICalculator, DefaultCalculator>();
|
services.AddSingleton<ICalculator, DefaultCalculator>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue