{"id":71661,"date":"2022-06-23T08:00:23","date_gmt":"2022-06-23T06:00:23","guid":{"rendered":"https:\/\/drafts.code-maze.com\/?p=71661"},"modified":"2024-01-31T15:16:59","modified_gmt":"2024-01-31T14:16:59","slug":"apicontroller-attribute-in-asp-net-core-web-api","status":"publish","type":"post","link":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/","title":{"rendered":"ApiController Attribute in ASP.NET Core Web API"},"content":{"rendered":"<p>In this article, we will learn about the ApiController attribute and the features it brings to our Web API controllers.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/aspnetcore-webapi\/ApiControllerAttributeInWebApi\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository<\/a>.<\/div>\n<p>Let&#8217;s get started.<\/p>\n<h2>Why We Should Use ApiController Attribute<\/h2>\n<p>By annotating our API controllers with <code>ApiController<\/code>, we get features and behaviors that are focused on improving developer experience by <strong>reducing the amount of boilerplate code in our controllers<\/strong>.<\/p>\n<p>These features include the requirement for attribute routing, automatic model validation, and new binding parameter inference rules.<\/p>\n<h2>How to Use ApiController Attribute?<\/h2>\n<p>We can apply the <code>ApiController<\/code> attribute directly to individual controllers:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[ApiController]\r\n[Route(\"[controller]\")]\r\npublic class CustomersController : ControllerBase<\/pre>\n<p>We can also apply it to a custom controller base class. Then, all its subclasses will inherit <code>ApiController<\/code> behavior.<\/p>\n<p>Lastly, we can apply the <code>ApiController<\/code> attribute at the assembly level by adding it to any project file, usually in <code>Program.cs<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">using Microsoft.AspNetCore.Mvc;\r\n\r\n[assembly: ApiController]<\/pre>\n<h2>Attribute Routing Requirement<\/h2>\n<p>Once we add the <code>ApiController<\/code> attribute to our Web API controllers, routes defined as <strong>conventional routes won&#8217;t be able to reach our actions<\/strong>. We must use <a href=\"https:\/\/code-maze.com\/routing-asp-net-core-mvc\/#attributerouting\" target=\"_blank\" rel=\"noopener\">attribute routing<\/a> instead.<\/p>\n<h2>Automatic Model Validation and HTTP 400 Responses<\/h2>\n<p><code>ApiController<\/code> automatically checks the model state and returns <code>HTTP 400<\/code> responses in case of model validation errors. Therefore, <strong>we don&#8217;t have to check <\/strong><code>ModelState.IsValid<\/code><strong> explicitly<\/strong> <strong>in our actions<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">if (!ModelState.IsValid)   \/\/ We don't need to do this check\r\n{\r\n    return BadRequest(ModelState);\r\n}<\/pre>\n<p>Furthermore, <code>ApiController<\/code> introduces the <code>ValidationProblem<\/code> format for <code>HTTP 400<\/code> responses. It is a machine-readable RFC 7807 compliant format:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n  \"type\": \"https:\/\/tools.ietf.org\/html\/rfc7231#section-6.5.1\",\r\n  \"title\": \"One or more validation errors occurred.\",\r\n  \"status\": 400,\r\n  \"traceId\": \"|7fb5e16a-4c8f23bbfc974667.\",\r\n  \"errors\": {\r\n    \"Name\": [\r\n      \"The Name field is required.\"\r\n    ]\r\n  }\r\n}<\/pre>\n<p><strong>When we perform custom validations, we can<\/strong> <strong>use <\/strong><code>ValidationProblem()<\/code><strong> instead of <\/strong><code>BadRequest()<\/code> to keep all our <code>HTTP 400<\/code> responses consistent:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpGet(\"{id}\")]\r\npublic IActionResult GetCustomersById(int id)\r\n{\r\n    var customer = new Customer();\r\n\r\n    if (!customer.IsActive)\r\n        return ValidationProblem(); \/\/ Do not use BadRequest()\r\n\r\n    return Ok(customer);\r\n}<\/pre>\n<h2>Invalid Model Response Customization<\/h2>\n<p><strong>We can fully customize our validation problem responses as well<\/strong>. To do that, we provide our own implementation of the <code>InvalidModelStateResponseFactory<\/code> delegate in the <code>ConfigureApiBehaviorOptions()<\/code> extension method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddControllers()\r\n    .ConfigureApiBehaviorOptions(options =&gt;\r\n    {\r\n        options.InvalidModelStateResponseFactory = context =&gt;\r\n        {\r\n            \/\/ Build your custom bad request response here\r\n        };\r\n    });<\/pre>\n<p>Let&#8217;s imagine that we want to replace the default validation problem response format. Specifically, we want our API users to be able to see the request path and method, and exactly which controller action handled it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"8-11\">builder.Services.AddControllers()\r\n    .ConfigureApiBehaviorOptions(opt =&gt;\r\n    {\r\n        opt.InvalidModelStateResponseFactory = context =&gt;\r\n        {\r\n            var responseObj = new\r\n            {\r\n                path = context.HttpContext.Request.Path.ToString(),\r\n                method = context.HttpContext.Request.Method,\r\n                controller = (context.ActionDescriptor as ControllerActionDescriptor)?.ControllerName,\r\n                action = (context.ActionDescriptor as ControllerActionDescriptor)?.ActionName,\r\n                errors = context.ModelState.Keys.Select(k =&gt;\r\n                {\r\n                    return new\r\n                    {\r\n                        field = k,\r\n                        Messages = context.ModelState[k]?.Errors.Select(e =&gt; e.ErrorMessage)\r\n                    };\r\n                })\r\n            };\r\n\r\n            return new BadRequestObjectResult(responseObj);\r\n        };\r\n    });<\/pre>\n<p>Here, we create a new delegate to replace the default <code>InvalidModelStateResponseFactory<\/code>. It receives an <code>ActionContext<\/code> (context) parameter from which we get the data we need to include in the response.<\/p>\n<p>The new delegate must return an implementation of <code>IActionResult<\/code>. In our case, an instance of <code>BadRequestObjectResult<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n    \"path\": \"\/customers\",\r\n    \"method\": \"POST\",\r\n    \"controller\": \"Customers\",\r\n    \"action\": \"PostCustomer\",\r\n    \"errors\": [{\r\n                  \"field\": \"Name\",\r\n                  \"messages\": [\"The Name field is required.\"]\r\n     \t\t  }]\r\n}<\/pre>\n<p>We can even <strong>disable the automatic responses altogether<\/strong> by setting the <code>SuppressModelStateInvalidFilter<\/code> property of the <code>ApiBehaviorOptions<\/code> object to <code>false<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddControllers()\r\n    .ConfigureApiBehaviorOptions(options =&gt;\r\n    {\r\n        options.SuppressModelStateInvalidFilter = true;\r\n    });<\/pre>\n<h2>Source Binding Inference Rules<\/h2>\n<p><code>ApiController<\/code> will try to <strong>infer the source of some action parameters without us having to use binding attributes<\/strong> like <code>[FromBody]<\/code> or <code>[FromQuery]<\/code>. For this purpose, <code>ApiController<\/code> applies a set of inference rules:<\/p>\n\n<table id=\"tablepress-39\" class=\"tablepress tablepress-id-39\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Binding Attribute<\/th><th class=\"column-2\">Inference Rule<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">[FromBody]<\/td><td class=\"column-2\">Inferred for any complex type<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">[FromForm]<\/td><td class=\"column-2\">Inferred for any parameters of type IFormFile or IFormFileCollection<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">[FromRoute]<\/td><td class=\"column-2\">Inferred for any action parameter whose name matches a parameter in the route template<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">[FromQuery]<\/td><td class=\"column-2\">Inferred for all the other action parameters<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">[FromHeader]<\/td><td class=\"column-2\">No rule for header binding<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-39 from cache -->\n<p>Additionally, <strong>we can disable all the rules<\/strong> by setting the <code>SuppressInferBindingSourcesForParameters<\/code> option to <code>true<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddControllers()\r\n    .ConfigureApiBehaviorOptions(options =&gt;\r\n    {\r\n        options.SuppressInferBindingSourcesForParameters = true;\r\n    });<\/pre>\n<h2>Conclusion<\/h2>\n<p>In this article, we&#8217;ve learned what the <code>ApiController<\/code> attribute does for us how to use it to add common behavior to our Web API controllers.<\/p>\n<p>We&#8217;ve learned about the automatic <code>HTTP 400<\/code> responses generated by the <code>ModelStateInvalidFilter<\/code> and how to customize them.<\/p>\n<p>Finally, we&#8217;ve reviewed <code>ApiController<\/code>&#8216;s source binding inference rules and how they save us from explicitly using binding attributes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will learn about the ApiController attribute and the features it brings to our Web API controllers. Let&#8217;s get started. Why We Should Use ApiController Attribute By annotating our API controllers with ApiController, we get features and behaviors that are focused on improving developer experience by reducing the amount of boilerplate code [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":62187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[12,2079],"tags":[1314,586,1315,1316],"class_list":["post-71661","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-csharp","category-web-api","tag-apicontroller","tag-asp-net-core-web-api","tag-atrribute","tag-controller","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ApiController Attribute in ASP.NET Core Web API - Code Maze<\/title>\n<meta name=\"description\" content=\"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ApiController Attribute in ASP.NET Core Web API - Code Maze\" \/>\n<meta property=\"og:description\" content=\"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-23T06:00:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-31T14:16:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Code Maze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Code Maze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\"},\"author\":{\"name\":\"Code Maze\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\"},\"headline\":\"ApiController Attribute in ASP.NET Core Web API\",\"datePublished\":\"2022-06-23T06:00:23+00:00\",\"dateModified\":\"2024-01-31T14:16:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\"},\"wordCount\":470,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"keywords\":[\"ApiController\",\"asp.net core web api\",\"Atrribute\",\"Controller\"],\"articleSection\":[\"C#\",\"Web API\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\",\"url\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\",\"name\":\"ApiController Attribute in ASP.NET Core Web API - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"datePublished\":\"2022-06-23T06:00:23+00:00\",\"dateModified\":\"2024-01-31T14:16:59+00:00\",\"description\":\"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"width\":1100,\"height\":620,\"caption\":\"ASP.NET Core\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ApiController Attribute in ASP.NET Core Web API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\",\"name\":\"Code Maze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"caption\":\"Code Maze\"},\"description\":\"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/codemaze\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/codemazecontributor\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ApiController Attribute in ASP.NET Core Web API - Code Maze","description":"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/","og_locale":"en_US","og_type":"article","og_title":"ApiController Attribute in ASP.NET Core Web API - Code Maze","og_description":"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.","og_url":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/","og_site_name":"Code Maze","article_published_time":"2022-06-23T06:00:23+00:00","article_modified_time":"2024-01-31T14:16:59+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","type":"image\/png"}],"author":"Code Maze","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Code Maze","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/"},"author":{"name":"Code Maze","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04"},"headline":"ApiController Attribute in ASP.NET Core Web API","datePublished":"2022-06-23T06:00:23+00:00","dateModified":"2024-01-31T14:16:59+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/"},"wordCount":470,"commentCount":2,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","keywords":["ApiController","asp.net core web api","Atrribute","Controller"],"articleSection":["C#","Web API"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/","url":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/","name":"ApiController Attribute in ASP.NET Core Web API - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","datePublished":"2022-06-23T06:00:23+00:00","dateModified":"2024-01-31T14:16:59+00:00","description":"By annotating API controllers with the ApiController attribute, we get features that are focused on improving the developer experience.","breadcrumb":{"@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","width":1100,"height":620,"caption":"ASP.NET Core"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/apicontroller-attribute-in-asp-net-core-web-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"ApiController Attribute in ASP.NET Core Web API"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04","name":"Code Maze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","caption":"Code Maze"},"description":"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.","sameAs":["https:\/\/www.linkedin.com\/company\/codemaze\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/codemazecontributor\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/71661","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=71661"}],"version-history":[{"count":5,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/71661\/revisions"}],"predecessor-version":[{"id":72035,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/71661\/revisions\/72035"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62187"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=71661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=71661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=71661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}