{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/23200696","id":23200696,"diff_hunk":"@@ -0,0 +1,139 @@\n+﻿// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\n+\n+using System;\n+using System.Diagnostics;\n+using System.Linq;\n+using Microsoft.AspNet.Mvc.Description;\n+using Microsoft.Framework.DependencyInjection;\n+using Microsoft.Framework.OptionsModel;\n+using Microsoft.Net.Http.Headers;\n+using System.Collections.Generic;\n+\n+namespace Microsoft.AspNet.Mvc\n+{\n+    /// <summary>\n+    /// This will look at the format parameter if present in the route data or query data and sets the content type in \n+    /// ObjectResult corresponding to the format value.\n+    /// </summary>\n+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]\n+    public class FormatFilterAttribute : Attribute, IFormatFilter, IResourceFilter, IResultFilter\n+    {\n+        /// <summary>\n+        /// As a resourceFilter, this filter looks at the request and rejects it\n+        /// before going ahead if\n+        /// 1. The format in the request doesnt match any format in the map.\n+        /// 2. If there is a conflicting producesFilter.\n+        /// </summary>\n+        /// <param name=\"context\"></param>\n+        public void OnResourceExecuting([NotNull] ResourceExecutingContext context)\n+        {\n+            var format = GetFormat(context);\n+\n+            if (!string.IsNullOrEmpty(format))\n+            {\n+                var formatContentType = GetContentType(format, context);\n+                if (formatContentType == null)\n+                {\n+                    // no contentType exists for the format, return 404\n+                    context.Result = new HttpNotFoundResult();\n+                }\n+                else\n+                {\n+                    var responseTypeFilters = context.Filters.OfType<IApiResponseMetadataProvider>();\n+                    if (responseTypeFilters.Count() != 0)\n+                    {\n+                        var contentTypes = new List<MediaTypeHeaderValue>();\n+\n+                        foreach (var filter in responseTypeFilters)\n+                        {\n+                            filter.SetContentTypes(contentTypes);\n+                        }\n+\n+                        if (!contentTypes.Any(c => c.IsSubsetOf(formatContentType)))\n+                        {\n+                            context.Result = new HttpNotFoundResult();\n+                        }\n+                    }    \n+                }\n+            }\n+        }\n+\n+        /// <inheritdoc />\n+        public void OnResourceExecuted([NotNull] ResourceExecutedContext context)\n+        {\n+\n+        }\n+\n+        /// <summary>\n+        /// This method looks at the format that request has and sets it in the context\n+        /// </summary>\n+        public void OnResultExecuting([NotNull] ResultExecutingContext context)\n+        {\n+            var format = GetFormat(context);\n+            if (format != null)\n+            {\n+                var contentType = GetContentType(format, context);\n+                Debug.Assert(contentType != null);\n+\n+                var objectResult = context.Result as ObjectResult;\n+                if (objectResult != null)\n+                {\n+                    objectResult.ContentTypes.Clear();\n+                    objectResult.ContentTypes.Add(contentType);\n+                }\n+            }\n+        }\n+        \n+        /// <inheritdoc />     \n+        public void OnResultExecuted([NotNull] ResultExecutedContext context)\n+        {\n+\n+        }\n+\n+        /// <summary>\n+        /// Looks at the current request for the format parameter. If it contains format, it returns the content type \n+        /// for it.\n+        /// </summary>","path":"src/Microsoft.AspNet.Mvc.Core/Filters/FormatFilterAttribute.cs","position":97,"original_position":97,"commit_id":"f28235164c4bffd8bb06c7775f4d68cb1e3c9145","original_commit_id":"f28235164c4bffd8bb06c7775f4d68cb1e3c9145","user":{"login":"rynowak","id":1430011,"avatar_url":"https://avatars.githubusercontent.com/u/1430011?v=3","gravatar_id":"","url":"https://api.github.com/users/rynowak","html_url":"https://github.com/rynowak","followers_url":"https://api.github.com/users/rynowak/followers","following_url":"https://api.github.com/users/rynowak/following{/other_user}","gists_url":"https://api.github.com/users/rynowak/gists{/gist_id}","starred_url":"https://api.github.com/users/rynowak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rynowak/subscriptions","organizations_url":"https://api.github.com/users/rynowak/orgs","repos_url":"https://api.github.com/users/rynowak/repos","events_url":"https://api.github.com/users/rynowak/events{/privacy}","received_events_url":"https://api.github.com/users/rynowak/received_events","type":"User","site_admin":false},"body":"Try make this doc-comment a little simpler based on the feedback above.","created_at":"2015-01-20T03:09:04Z","updated_at":"2015-01-20T03:09:04Z","html_url":"https://github.com/aspnet/Mvc/pull/1817#discussion_r23200696","pull_request_url":"https://api.github.com/repos/aspnet/Mvc/pulls/1817","_links":{"self":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/23200696"},"html":{"href":"https://github.com/aspnet/Mvc/pull/1817#discussion_r23200696"},"pull_request":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/1817"}}},"pull_request":{"url":"https://api.github.com/repos/aspnet/Mvc/pulls/1817","id":27403183,"html_url":"https://github.com/aspnet/Mvc/pull/1817","diff_url":"https://github.com/aspnet/Mvc/pull/1817.diff","patch_url":"https://github.com/aspnet/Mvc/pull/1817.patch","issue_url":"https://api.github.com/repos/aspnet/Mvc/issues/1817","number":1817,"state":"open","locked":false,"title":"Url extensions1673","user":{"login":"kulmugdha","id":6642439,"avatar_url":"https://avatars.githubusercontent.com/u/6642439?v=3","gravatar_id":"","url":"https://api.github.com/users/kulmugdha","html_url":"https://github.com/kulmugdha","followers_url":"https://api.github.com/users/kulmugdha/followers","following_url":"https://api.github.com/users/kulmugdha/following{/other_user}","gists_url":"https://api.github.com/users/kulmugdha/gists{/gist_id}","starred_url":"https://api.github.com/users/kulmugdha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kulmugdha/subscriptions","organizations_url":"https://api.github.com/users/kulmugdha/orgs","repos_url":"https://api.github.com/users/kulmugdha/repos","events_url":"https://api.github.com/users/kulmugdha/events{/privacy}","received_events_url":"https://api.github.com/users/kulmugdha/received_events","type":"User","site_admin":false},"body":"This is MVC part of feature URL Extensions. It does following:\r\n1. Creates a filter called FormatFilter. This will look at the format parameter if present\r\n   in the route data or query data and sets the content type in ObjectResult\r\n2. It adds new options called FormatterOptions, that contains the map of format to content tyepe\r\n3. A method in MVC options to add the formatter mapping","created_at":"2015-01-15T03:05:18Z","updated_at":"2015-01-20T03:09:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0a3668551a9b5aef213a15c4fb329c6d0928ca5a","assignee":null,"milestone":{"url":"https://api.github.com/repos/aspnet/Mvc/milestones/14","labels_url":"https://api.github.com/repos/aspnet/Mvc/milestones/14/labels","id":929400,"number":14,"title":"6.0.0-rc1","description":"","creator":{"login":"danroth27","id":1874516,"avatar_url":"https://avatars.githubusercontent.com/u/1874516?v=3","gravatar_id":"","url":"https://api.github.com/users/danroth27","html_url":"https://github.com/danroth27","followers_url":"https://api.github.com/users/danroth27/followers","following_url":"https://api.github.com/users/danroth27/following{/other_user}","gists_url":"https://api.github.com/users/danroth27/gists{/gist_id}","starred_url":"https://api.github.com/users/danroth27/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danroth27/subscriptions","organizations_url":"https://api.github.com/users/danroth27/orgs","repos_url":"https://api.github.com/users/danroth27/repos","events_url":"https://api.github.com/users/danroth27/events{/privacy}","received_events_url":"https://api.github.com/users/danroth27/received_events","type":"User","site_admin":false},"open_issues":174,"closed_issues":2,"state":"open","created_at":"2015-01-09T23:08:53Z","updated_at":"2015-01-20T02:02:11Z","due_on":"2015-03-23T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/aspnet/Mvc/pulls/1817/commits","review_comments_url":"https://api.github.com/repos/aspnet/Mvc/pulls/1817/comments","review_comment_url":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/{number}","comments_url":"https://api.github.com/repos/aspnet/Mvc/issues/1817/comments","statuses_url":"https://api.github.com/repos/aspnet/Mvc/statuses/f28235164c4bffd8bb06c7775f4d68cb1e3c9145","head":{"label":"aspnet:UrlExtensions1673","ref":"UrlExtensions1673","sha":"f28235164c4bffd8bb06c7775f4d68cb1e3c9145","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":15126429,"name":"Mvc","full_name":"aspnet/Mvc","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Mvc","description":"Model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor.","fork":false,"url":"https://api.github.com/repos/aspnet/Mvc","forks_url":"https://api.github.com/repos/aspnet/Mvc/forks","keys_url":"https://api.github.com/repos/aspnet/Mvc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Mvc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Mvc/teams","hooks_url":"https://api.github.com/repos/aspnet/Mvc/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Mvc/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Mvc/events","assignees_url":"https://api.github.com/repos/aspnet/Mvc/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Mvc/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Mvc/tags","blobs_url":"https://api.github.com/repos/aspnet/Mvc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Mvc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Mvc/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Mvc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Mvc/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Mvc/languages","stargazers_url":"https://api.github.com/repos/aspnet/Mvc/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Mvc/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Mvc/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Mvc/subscription","commits_url":"https://api.github.com/repos/aspnet/Mvc/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Mvc/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Mvc/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Mvc/issues/comments/{number}","contents_url":"https://api.github.com/repos/aspnet/Mvc/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Mvc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Mvc/merges","archive_url":"https://api.github.com/repos/aspnet/Mvc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Mvc/downloads","issues_url":"https://api.github.com/repos/aspnet/Mvc/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Mvc/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Mvc/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Mvc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Mvc/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Mvc/releases{/id}","created_at":"2013-12-12T03:54:00Z","updated_at":"2015-01-20T02:00:13Z","pushed_at":"2015-01-20T02:45:34Z","git_url":"git://github.com/aspnet/Mvc.git","ssh_url":"git@github.com:aspnet/Mvc.git","clone_url":"https://github.com/aspnet/Mvc.git","svn_url":"https://github.com/aspnet/Mvc","homepage":"","size":56762,"stargazers_count":1243,"watchers_count":1243,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":347,"mirror_url":null,"open_issues_count":257,"forks":347,"open_issues":257,"watchers":1243,"default_branch":"dev"}},"base":{"label":"aspnet:dev","ref":"dev","sha":"67b078862ee36a846af1b81088e3f2f73f5de3e2","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":15126429,"name":"Mvc","full_name":"aspnet/Mvc","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Mvc","description":"Model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor.","fork":false,"url":"https://api.github.com/repos/aspnet/Mvc","forks_url":"https://api.github.com/repos/aspnet/Mvc/forks","keys_url":"https://api.github.com/repos/aspnet/Mvc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Mvc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Mvc/teams","hooks_url":"https://api.github.com/repos/aspnet/Mvc/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Mvc/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Mvc/events","assignees_url":"https://api.github.com/repos/aspnet/Mvc/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Mvc/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Mvc/tags","blobs_url":"https://api.github.com/repos/aspnet/Mvc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Mvc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Mvc/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Mvc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Mvc/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Mvc/languages","stargazers_url":"https://api.github.com/repos/aspnet/Mvc/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Mvc/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Mvc/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Mvc/subscription","commits_url":"https://api.github.com/repos/aspnet/Mvc/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Mvc/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Mvc/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Mvc/issues/comments/{number}","contents_url":"https://api.github.com/repos/aspnet/Mvc/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Mvc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Mvc/merges","archive_url":"https://api.github.com/repos/aspnet/Mvc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Mvc/downloads","issues_url":"https://api.github.com/repos/aspnet/Mvc/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Mvc/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Mvc/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Mvc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Mvc/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Mvc/releases{/id}","created_at":"2013-12-12T03:54:00Z","updated_at":"2015-01-20T02:00:13Z","pushed_at":"2015-01-20T02:45:34Z","git_url":"git://github.com/aspnet/Mvc.git","ssh_url":"git@github.com:aspnet/Mvc.git","clone_url":"https://github.com/aspnet/Mvc.git","svn_url":"https://github.com/aspnet/Mvc","homepage":"","size":56762,"stargazers_count":1243,"watchers_count":1243,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":347,"mirror_url":null,"open_issues_count":257,"forks":347,"open_issues":257,"watchers":1243,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/1817"},"html":{"href":"https://github.com/aspnet/Mvc/pull/1817"},"issue":{"href":"https://api.github.com/repos/aspnet/Mvc/issues/1817"},"comments":{"href":"https://api.github.com/repos/aspnet/Mvc/issues/1817/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/1817/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/1817/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet/Mvc/statuses/f28235164c4bffd8bb06c7775f4d68cb1e3c9145"}}}}