{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/28835833","id":28835833,"diff_hunk":"@@ -51,8 +51,13 @@ public BodyModelBinder()\n             {\n                 var model = await formatter.ReadAsync(formatterContext);\n \n-                // key is empty to ensure that the model name is not used as a prefix for validation.\n-                return new ModelBindingResult(model, key: string.Empty, isModelSet: true);\n+                var isTopLevelObject = bindingContext.ModelMetadata.ContainerType == null;\n+\n+                // For compatibility with MVC 5.0 for top level object we want to consider an empty key instead of \n+                // the parameter name/a custom name. In all other cases (like when binding body to a property) we","path":"src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs","position":9,"original_position":9,"commit_id":"49b2eb9a8345d74cdfd40da091191ff835260ac0","original_commit_id":"49b2eb9a8345d74cdfd40da091191ff835260ac0","user":{"login":"harshgMSFT","id":6729943,"avatar_url":"https://avatars.githubusercontent.com/u/6729943?v=3","gravatar_id":"","url":"https://api.github.com/users/harshgMSFT","html_url":"https://github.com/harshgMSFT","followers_url":"https://api.github.com/users/harshgMSFT/followers","following_url":"https://api.github.com/users/harshgMSFT/following{/other_user}","gists_url":"https://api.github.com/users/harshgMSFT/gists{/gist_id}","starred_url":"https://api.github.com/users/harshgMSFT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/harshgMSFT/subscriptions","organizations_url":"https://api.github.com/users/harshgMSFT/orgs","repos_url":"https://api.github.com/users/harshgMSFT/repos","events_url":"https://api.github.com/users/harshgMSFT/events{/privacy}","received_events_url":"https://api.github.com/users/harshgMSFT/received_events","type":"User","site_admin":false},"body":"remove extra a in comment.","created_at":"2015-04-22T00:29:50Z","updated_at":"2015-04-22T00:29:50Z","html_url":"https://github.com/aspnet/Mvc/pull/2396#discussion_r28835833","pull_request_url":"https://api.github.com/repos/aspnet/Mvc/pulls/2396","_links":{"self":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/comments/28835833"},"html":{"href":"https://github.com/aspnet/Mvc/pull/2396#discussion_r28835833"},"pull_request":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/2396"}}},"pull_request":{"url":"https://api.github.com/repos/aspnet/Mvc/pulls/2396","id":33506735,"html_url":"https://github.com/aspnet/Mvc/pull/2396","diff_url":"https://github.com/aspnet/Mvc/pull/2396.diff","patch_url":"https://github.com/aspnet/Mvc/pull/2396.patch","issue_url":"https://api.github.com/repos/aspnet/Mvc/issues/2396","number":2396,"state":"open","locked":false,"title":"Creating correct model state keys when body model binding for missing properties or body. Also adds integration tests","user":{"login":"harshgMSFT","id":6729943,"avatar_url":"https://avatars.githubusercontent.com/u/6729943?v=3","gravatar_id":"","url":"https://api.github.com/users/harshgMSFT","html_url":"https://github.com/harshgMSFT","followers_url":"https://api.github.com/users/harshgMSFT/followers","following_url":"https://api.github.com/users/harshgMSFT/following{/other_user}","gists_url":"https://api.github.com/users/harshgMSFT/gists{/gist_id}","starred_url":"https://api.github.com/users/harshgMSFT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/harshgMSFT/subscriptions","organizations_url":"https://api.github.com/users/harshgMSFT/orgs","repos_url":"https://api.github.com/users/harshgMSFT/repos","events_url":"https://api.github.com/users/harshgMSFT/events{/privacy}","received_events_url":"https://api.github.com/users/harshgMSFT/received_events","type":"User","site_admin":false},"body":"The model state keys for body bound models which are bound at property will use the entire model name with this change for example\r\nConsider\r\n```c#\r\n        public class Person\r\n        {\r\n            [FromBody]\r\n            public Address Address { get; set; }\r\n        }\r\n\r\n        public class Address\r\n        {\r\n            [Required]\r\n            public string Street { get; set; }\r\n\r\n            public int Zip { get; set; }\r\n        }\r\n```\r\nRequest body { \"Zip\" : 12345 }\r\nIn this case the error key would be \"prefix.Address.Street\" (assuming there is a prefix because of additional metadata/positioning for/of the Person model).\r\n\r\n```c#\r\npublic class Person\r\n{\r\n       [Required]\r\n       public string Name { get; set; }\r\n}\r\n\r\npublic void Action([FromBody]Person p)\r\n{\r\n}\r\n```\r\nRequest body { }\r\nIn this case the prefix gets ignored and the error key is Name.\r\nPlease note this is so that we are compatible with MVC 5.0\r\n\r\n\r\n```c#\r\npublic class Person\r\n{\r\n       [Required]\r\n       public string Name { get; set; }\r\n}\r\n\r\npublic void Action([FromBody][ModelBinder(Name = \"prefix\")] Person p)\r\n{\r\n}\r\n\r\npublic void Action2([FromBody][Bind(Name = \"prefix\")] Person p)\r\n{\r\n}\r\n```\r\nRequest body { }\r\nIn both these cases (Action and Action2) the prefix gets ignored and the error key is Name.\r\nThis is a slight improvement from mvc, as in MVC the action parameter would be null. \r\n\r\nThe followup for this would be to fix #2416 - \r\nThis PR ignores the validation assuming that #2416 will address the issues and update the test.\r\n\r\nNOTE: previous versions of mvc did not have property binding and hence there is no precedence in this case. For MVC and Web API it was possible to body bind an action parameter which used an empty prefix instead of a parameter name for adding errors to model state (In case of MVC if a custom prefix was provided, it failed binding from body i.e the parameter was null).","created_at":"2015-04-17T00:58:30Z","updated_at":"2015-04-22T00:29:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"138e007e88a01913233a50302194ced4b151d22b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/aspnet/Mvc/pulls/2396/commits","review_comments_url":"https://api.github.com/repos/aspnet/Mvc/pulls/2396/comments","review_comment_url":"https://api.github.com/repos/aspnet/Mvc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aspnet/Mvc/issues/2396/comments","statuses_url":"https://api.github.com/repos/aspnet/Mvc/statuses/49b2eb9a8345d74cdfd40da091191ff835260ac0","head":{"label":"aspnet:BodyValidationFix","ref":"BodyValidationFix","sha":"49b2eb9a8345d74cdfd40da091191ff835260ac0","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-04-21T21:58:12Z","pushed_at":"2015-04-22T00:17:37Z","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":112387,"stargazers_count":1627,"watchers_count":1627,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":537,"mirror_url":null,"open_issues_count":226,"forks":537,"open_issues":226,"watchers":1627,"default_branch":"dev"}},"base":{"label":"aspnet:dev","ref":"dev","sha":"064c01cf2b022e365f82e5729a616e17b7f54d9a","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-04-21T21:58:12Z","pushed_at":"2015-04-22T00:17:37Z","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":112387,"stargazers_count":1627,"watchers_count":1627,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":537,"mirror_url":null,"open_issues_count":226,"forks":537,"open_issues":226,"watchers":1627,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/2396"},"html":{"href":"https://github.com/aspnet/Mvc/pull/2396"},"issue":{"href":"https://api.github.com/repos/aspnet/Mvc/issues/2396"},"comments":{"href":"https://api.github.com/repos/aspnet/Mvc/issues/2396/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/2396/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aspnet/Mvc/pulls/2396/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet/Mvc/statuses/49b2eb9a8345d74cdfd40da091191ff835260ac0"}}}}