diff --git a/samples/MvcSample.Web/Startup.cs b/samples/MvcSample.Web/Startup.cs index 64afcbb810..d656371647 100644 --- a/samples/MvcSample.Web/Startup.cs +++ b/samples/MvcSample.Web/Startup.cs @@ -15,6 +15,7 @@ using MvcSample.Web.Services; #if ASPNET50 using Autofac; using Microsoft.Framework.DependencyInjection.Autofac; +using Microsoft.AspNet.Mvc.Core.Filters; #endif namespace MvcSample.Web @@ -114,6 +115,8 @@ namespace MvcSample.Web { routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}"); + routes.MapRoute("formatRoute", "{controller}/{action}/{format}"); + routes.MapRoute( "controllerActionRoute", "{controller}/{action}", diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/UrlExtensionFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/UrlExtensionFilter.cs new file mode 100644 index 0000000000..bf2faca5a0 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/UrlExtensionFilter.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNet.Mvc.HeaderValueAbstractions; +using Microsoft.Framework.OptionsModel; +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNet.Mvc.Core.Filters +{ + public class UrlExtensionFilter : IResultFilter + { + //private Dictionary FormatContentTypeMap = + // new Dictionary(); + + //public void AddFormatMapping(string format, MediaTypeHeaderValue contentType) + //{ + // if(FormatContentTypeMap.ContainsKey(format)) + // { + // FormatContentTypeMap.Remove(format); + // } + + // FormatContentTypeMap.Add(format, contentType); + //} + + public void OnResultExecuting([NotNull] ResultExecutingContext context) + { + var options = (IOptions)context.HttpContext.RequestServices.GetService(typeof(IOptions)); + + if (context.RouteData.Values.ContainsKey("format")) + { + var format = context.RouteData.Values["format"].ToString(); + var contentType = options.Options.OutputFormatterOptions.GetContentTypeForFormat(format); + if (contentType != null) + { + var objectResult = context.Result as ObjectResult; + objectResult.ContentTypes.Clear(); + objectResult.ContentTypes.Add(contentType); + } + else + { + throw new InvalidOperationException("No formatter exists for format:" + format); + } + } + } + + public void OnResultExecuted([NotNull] ResultExecutedContext context) + { + + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs index 619be72e83..10fb86df8c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs @@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.ApplicationModels; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.HeaderValueAbstractions; namespace Microsoft.AspNet.Mvc { @@ -17,6 +18,7 @@ namespace Microsoft.AspNet.Mvc { private AntiForgeryOptions _antiForgeryOptions = new AntiForgeryOptions(); private int _maxModelStateErrors = ModelStateDictionary.DefaultMaxAllowedErrors; + //private OutputFormatterOptions _outputFormatterOptions = new OutputFormatterOptions(); public MvcOptions() { @@ -27,6 +29,7 @@ namespace Microsoft.AspNet.Mvc OutputFormatters = new List(); InputFormatters = new List(); Filters = new List(); + OutputFormatterOptions = new OutputFormatterOptions(); } /// @@ -52,6 +55,8 @@ namespace Microsoft.AspNet.Mvc } } + public OutputFormatterOptions OutputFormatterOptions { get; } + /// /// Gets a list of which are used to construct filters that /// apply to all actions. @@ -64,6 +69,16 @@ namespace Microsoft.AspNet.Mvc /// public List OutputFormatters { get; private set; } + /// + /// Sets the mapping for output format specified in URL (extension) and content type + /// + /// URL extension for output format + /// Content type mapping to the format + public void AddFormatMapping(string format, MediaTypeHeaderValue contentType) + { + OutputFormatterOptions.AddFormatMapping(format, contentType); + } + /// /// Gets a list of the which are used to construct /// a list of by . diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs index 4482412b15..c8ee5d8f56 100644 --- a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs +++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs @@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Razor; using Microsoft.Framework.OptionsModel; using Newtonsoft.Json.Linq; +using Microsoft.AspNet.Mvc.HeaderValueAbstractions; namespace Microsoft.AspNet.Mvc { @@ -45,6 +46,10 @@ namespace Microsoft.AspNet.Mvc options.OutputFormatters.Add(new StringOutputFormatter()); options.OutputFormatters.Add(new JsonOutputFormatter()); + // Set up default mapping for xml and json extensions to content type + options.AddFormatMapping("json", MediaTypeHeaderValue.Parse("application/json")); + options.AddFormatMapping("xml", MediaTypeHeaderValue.Parse("application/xml")); + // Set up default input formatters. options.InputFormatters.Add(new JsonInputFormatter());