{"id":71395,"date":"2017-06-20T16:30:21","date_gmt":"2017-06-20T16:30:21","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=71395"},"modified":"2021-06-03T16:47:01","modified_gmt":"2021-06-03T16:47:01","slug":"visual-studio-2017-swagger-building-documenting-web-apis","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/visual-studio-2017-swagger-building-documenting-web-apis\/","title":{"rendered":"Visual Studio 2017 and Swagger: Building and Documenting Web APIs"},"content":{"rendered":"<p><strong>Swagger<\/strong> is a technology-agnostic standard that allows the discovery of REST APIs, providing a way for any software to identify the features of a REST API.<\/p>\n<p>This is more important than it seems: It\u2019s a game changing technology, in the same way that <strong>WSDL (Web Service Description Language)<\/strong> has been for web services.<\/p>\n<p><strong>WSDL<\/strong> has been the fundamental technology that made it possible for tools and IDEs such as <strong>Visual Studio<\/strong> to understand web services and to create proxy classes. This feature turns the consumption of web services into a high-level task, encapsulating all protocol details.<\/p>\n<p>That&#8217;s the importance of <strong>Swagger<\/strong>: It\u2019s able to do for REST APIs what WSDL has already done for web services, by allowing the creation of proxies and by making the use of web APIs much easier.<\/p>\n<p><strong>VS 2017<\/strong> includes support for REST API proxy creation using Swagger protocol. It&#8217;s still in an early stage and lacking some features, however this is a great step towards the broader adoption of Swagger.<\/p>\n<p>We\u2019ll create an example of how we can use Swagger with <strong>VS 2017<\/strong> in order to analyze the advantages and the missing features.<\/p>\n<p>As well as VS 2017, we will also need IIS (Internet Information Server) installed in the development machine for our example.<\/p>\n<h2>Development Environment<\/h2>\n<p>You can enable IIS as a Windows feature or server role depending if you are using a client operating system or a server one.<\/p>\n<h2>Starting Application<\/h2>\n<p>Before we can use Swagger, we need a demo solution with a web API project. Let&#8217;s build this starting solution before we go on to implement Swagger.<\/p>\n<ol>\n<li>Create an ASP.NET Web API project\n<ol type=\"a\">\n<li>Inside Visual Studio, select <em>\u2018File\u2019<\/em> -&gt; <em>\u2018New Project\u2019<\/em> menu<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, inside the left side tree view, select <em>\u2018Installed\u2019<\/em> -&gt; <em>\u2018Templates\u2019<\/em> -&gt; <em>\u2018Visual C#\u2019<\/em> -&gt; <em>\u2018Web\u2019<\/em> tree items.<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, in the right side, select <em>\u2018ASP.NET Web Application (.NET Framework)\u2019<\/em><\/li>\n<li>In the <em>\u2018Name\u2019<\/em> textbox, type <em>\u2018webDemo\u2019<\/em>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1176\" height=\"814\" class=\"wp-image-71396\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-33.png\" \/><\/p>\n<\/li>\n<li>In the <em>\u2018Solution Name\u2019<\/em> textbox, type <em>\u2018slDemo\u2019<\/em> and click the \u2018Ok\u2019 button<\/li>\n<li>In the <em>\u2018New ASP.NET Web Application\u2019<\/em> window, below <em>\u2018ASP.NET 4.5.2 Templates\u2019<\/em>, select <em>\u2018Web API\u2019<\/em> and click the \u2018Ok\u2019 button\n<p><img loading=\"lazy\" decoding=\"async\" width=\"983\" height=\"642\" class=\"wp-image-71397\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-34.png\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>Configure the Web API project to use the local <strong>IIS<\/strong>\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click on <em>\u2018webDemo\u2019<\/em> project and click the <em>\u2018Properties\u2019<\/em> menu item.<\/li>\n<li>In the right side of <em>\u2018webDemo\u2019<\/em> properties window, click <em>\u2018Web\u2019<\/em> page<\/li>\n<li>In the combobox below <em>\u2018Servers\u2019<\/em>, select <em>\u2018Local IIS\u2019<\/em>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1195\" height=\"824\" class=\"wp-image-71398\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-35.png\" \/><\/p>\n<\/li>\n<li>Click the <em>\u2018Create Virtual Directory\u2019<\/em> button<\/li>\n<li>Close the <em>\u2018webDemo\u2019<\/em> properties page<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>This project already has a sample web API controller developed, but we need to make some changes. Let&#8217;s examine the details of the existing controller and make those changes.<\/p>\n<ol>\n<li>Analyzing and changing the existing API Controller\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, inside <em>\u2018webDemo\u2019<\/em> project, open the <em>\u2018Controllers\u2019<\/em> folder and check the existing controllers.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"349\" height=\"440\" class=\"wp-image-71399\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-36.png\" \/><\/p>\n<\/li>\n<li>Double-click the <em>\u2018ValuesController.cs\u2019<\/em> file and check the existing actions. This is the only web API controller in the project.<\/li>\n<li>Change the <em>\u2018ValuesController\u2019<\/em> class for the code below. We are completing the <strong>PUT<\/strong> action and storing the list inside Application memory area.\n<pre class=\"theme:vs2012 lang:c# decode:true\">    public class ValuesController : ApiController\r\n      {\r\n          private string[] lista\r\n          {\r\n              get\r\n              {\r\n                  if (System.Web.HttpContext.Current.Application[<em>\"lista\"<\/em>]==null)\r\n                  {\r\n                      System.Web.HttpContext.Current.Application[<em>\"lista\"<\/em>] = \r\n                          new string[] { <em>\"value1\"<\/em>, <em>\"value2\"<\/em> };\r\n                  }\r\n                  return \r\n                      (string[])System.Web.HttpContext.Current.Application[<em>\"lista\"<\/em>];\r\n              }\r\n          }\r\n          public IEnumerable&lt;string&gt; Get()\r\n          {\r\n              return lista;\r\n          }\r\n          public string Get(int id)\r\n          {\r\n              return lista[id];\r\n          }\r\n          public void Post([FromBody]string value)\r\n          {\r\n          }\r\n          public void Put(int id, [FromBody]string value)\r\n          {\r\n              lista[id] = value;\r\n          }\r\n          public void Delete(int id)\r\n          {\r\n          }\r\n      }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>Execute the application and analyze the result<\/li>\n<li>\n<ol type=\"a\">\n<li>Click <em>\u2018Start\u2019<\/em> button in the toolbar to execute the application<\/li>\n<li>On the web page just opened, click <em>\u2018API\u2019<\/em> link in the top menu. You will notice the API operations, basically a CRUD with two <strong>GET&#8217;s<\/strong>, one <strong>POST<\/strong>, <strong>PUT<\/strong> and <strong>DELETE<\/strong>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1088\" height=\"728\" class=\"wp-image-71400\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-37.png\" \/><\/p>\n<\/li>\n<li>In the browser navigation bar, type a new URL: <em>http:\/\/localhost\/webDemo\/API\/Values<\/em> . As a result, a <strong>JSON<\/strong> file will be downloaded, therefore the web API is working fine.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1256\" height=\"128\" class=\"wp-image-71401\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-38.png\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Including Swagger in our project<\/h2>\n<p><strong>Swagger<\/strong> is a technology agnostic protocol. For each technology, we need some tool to implement the protocol. <strong>SwashBuckle<\/strong> is the name of the tool for .NET. There is a version for .NET before 4.5 and another version for .NET after 4.5.<\/p>\n<p>Let&#8217;s do a step-by-step walkthrough to implement Swagger using <strong>SwashBuckle<\/strong>:<\/p>\n<ol>\n<li>Include <strong>SwashBuckle<\/strong> nugget package in the web API project\n<ol type=\"a\">\n<li>In the \u2018<em>Solution Explorer\u2019<\/em> window, right-click the <em>\u2018webDemo\u2019<\/em> project and click <em>\u2018Manage nuget packet\u2019<\/em> menu item.<\/li>\n<li>In the <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018Browse\u2019<\/em><\/li>\n<li>In the textbox inside <em>\u2018Nuget Package Manager\u2019<\/em> window, type <em>\u2018SwashBuckle\u2019<\/em>.<\/li>\n<li>In the left side of <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018SwashBuckle.Net45\u2019<\/em> package\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1402\" height=\"852\" class=\"wp-image-71402\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-39.png\" \/><\/p>\n<\/li>\n<li>In the right side of the <em>\u2018Nuget Package Manager\u2019<\/em> window, click the <em>\u2018Install\u2019<\/em> button.<\/li>\n<li>In the <em>\u2018Review Changes\u2019<\/em> window, click the \u2018Ok\u2019 button.<\/li>\n<li>In the <em>\u2018License Acceptance\u2019<\/em> window, click <em>\u2018I Accept\u2019<\/em> button.<\/li>\n<li>Close the <em>\u2018Nuget Package Manager\u2019<\/em> window<\/li>\n<\/ol>\n<\/li>\n<li>Configure the XML documentation. <strong>SwashBuckle<\/strong> will use the XML documentation to describe the WEB APIs actions.\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the <em>\u2018webDemo\u2019<\/em> project and click the <em>\u2018Properties\u2019<\/em> menu item.<\/li>\n<li>In the <em>\u2018webDemo\u2019<\/em> window, click <em>\u2018Build\u2019<\/em> page<\/li>\n<li>In the <em>\u2018webDemo\u2019<\/em> window, below <em>\u2018Output\u2019<\/em>, click <em>\u2018Xml Document File\u2019<\/em> checkbox. In the textbox at right you will see the path <em>\u2018bin\\webDemo.xml\u2019<\/em>.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1234\" height=\"740\" class=\"wp-image-71403\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-40.png\" \/><\/p>\n<\/li>\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, inside <em>\u2018webDemo\u2019<\/em> project, open the <em>\u2018Controllers\u2019<\/em> folder and double click <em>\u2018ValuesController.cs\u2019<\/em> file.<\/li>\n<li>Let&#8217;s create an XML documentation for each action and the controller. Over each action and also over the controller declaration, type <em>\u2018\/\/\/\u2019<\/em> and describe the action and the controller.\n<pre class=\"theme:vs2012 lang:c# decode:true\">        \/\/\/ &lt;summary&gt;\r\n          \/\/\/ Retrieves the list of values\r\n          \/\/\/ &lt;\/summary&gt;\r\n          \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n          public IEnumerable&lt;string&gt; Get()\r\n          {\r\n              return lista;\r\n          }\r\n          \/\/\/ &lt;summary&gt;\r\n          \/\/\/ Retrieves one value from the list of values\r\n          \/\/\/ &lt;\/summary&gt;\r\n          \/\/\/ &lt;param name=<em>\"id\"<\/em>&gt;The id of the item to be retrieved&lt;\/param&gt;\r\n          \/\/\/ &lt;returns&gt;&lt;\/returns&gt;\r\n          public string Get(int id)\r\n          {\r\n              return lista[id];\r\n          }\r\n          \/\/\/ &lt;summary&gt;\r\n          \/\/\/ Insert a new value in the list\r\n          \/\/\/ &lt;\/summary&gt;\r\n          \/\/\/ &lt;param name=<em>\"value\"<\/em>&gt;New value to be inserted&lt;\/param&gt;\r\n          public void Post([FromBody]string value)\r\n          {\r\n          }\r\n          \/\/\/ &lt;summary&gt;\r\n          \/\/\/ Change a single value in the list\r\n          \/\/\/ &lt;\/summary&gt;\r\n          \/\/\/ &lt;param name=<em>\"id\"<\/em>&gt;The id of the value to be changed&lt;\/param&gt;\r\n          \/\/\/ &lt;param name=<em>\"value\"<\/em>&gt;The new value&lt;\/param&gt;\r\n          public void Put(int id, [FromBody]string value)\r\n          {\r\n              lista[id] = value;\r\n          }\r\n          \/\/\/ &lt;summary&gt;\r\n          \/\/\/ Delete an item from the list\r\n          \/\/\/ &lt;\/summary&gt;\r\n          \/\/\/ &lt;param name=<em>\"id\"<\/em>&gt;id of the item to be deleted&lt;\/param&gt;\r\n          public void Delete(int id)\r\n          {\r\n          }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>Configure <strong>SwashBuckle<\/strong>. For now, the only configuration we need to do is the path of the XML documentation.\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019 <\/em>window, inside <em>\u2018webDemo\u2019<\/em> project, open the <em>\u2018App_Start\u2019<\/em> folder and double click <em>\u2018SwaggerConfig.cs\u2019<\/em> file. This file was included in the project by the <em>\u2018SwashBuckle.Net45\u2019 <\/em>nuget package.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"330\" height=\"341\" class=\"wp-image-71404\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-41.png\" \/><\/p>\n<p>The <em>\u2018Register\u2019<\/em> method of the <em>\u2018SwaggerConfig\u2019<\/em> class is configured to be executed as a <em>\u2018PreApplicationStartMethod\u2019<\/em>.<\/p>\n<\/li>\n<li>Include the following method inside <em>\u2018SwaggerConfig\u2019<\/em> class:\n<pre class=\"theme:vs2012 lang:c# decode:true\">        protected static string GetXmlCommentsPath()\r\n          {\r\n              return System.String.Format(@\"{0}\\bin\\webDemo.XML\", \r\n                  System.AppDomain.CurrentDomain.BaseDirectory);\r\n          }<\/pre>\n<\/li>\n<li>Uncomment the following block of code inside the <em>&#8220;Register&#8221;<\/em> method:\n<pre class=\"theme:vs2012 lang:c# decode:true\">                        c.IncludeXmlComments(GetXmlCommentsPath());<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>Execute and test the application\n<ol type=\"a\">\n<li>Execute the application, click the <em>\u2018Start\u2019<\/em> button in the toolbar.<\/li>\n<li>Type the following URL in the browser address bar: <em>http:\/\/localhost\/webDemo\/Swagger\/ui\/index<\/em><\/li>\n<li>On the Swagger documentation page, click <em>\u2018Values\u2019,<\/em> the name of the controller.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1493\" height=\"634\" class=\"wp-image-71405\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-42.png\" \/><\/p>\n<\/li>\n<li>Click each operation to see the documentation. You may notice that Swagger is using the XML documentation description for each operation.<\/li>\n<li>Type the following URL in the browser address bar: <em>http:\/\/localhost\/webDemo\/Swagger\/docs\/v1<\/em> . This time we are looking for the <strong>JSON<\/strong> document describing the web API, the core result of <strong>SwashBuckle<\/strong><\/li>\n<li>In the question that will appear, click the <em>\u2018Save\u2019<\/em> button (I\u2019m using Chrome, this can be a bit different with other browsers)<\/li>\n<li>In the message that will appear, click <em>\u2018Open Folder\u2019<\/em> button. (I\u2019m using Chrome, this can be a bit different with other browsers)<\/li>\n<li>Open the <strong>v1.json<\/strong> file with Notepad. The file won&#8217;t be well formatted, the content, however, is a description of the web API, such as you can see in the image below. If you would like so, you can open the file in Visual Studio to see a well-formatted version of the file.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"920\" height=\"846\" class=\"wp-image-71406\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-43.png\" \/><\/p>\n<\/li>\n<li>Stop the execution in Visual Studio<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Creating the Client Project<\/h2>\n<p>Now it&#8217;s time to create a client to consume our web API and illustrate how this consumption will be a lot easier.<\/p>\n<ol>\n<li>Add a new Windows Desktop project to the solution\n<ol type=\"a\">\n<li>In Visual Studio, click <em>\u2018File\u2019<\/em> -&gt; <em>\u2018Add\u2019<\/em> -&gt; <em>\u2018New Project\u2019<\/em> in the menu<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, inside the left side tree view, select <em>\u2018Installed\u2019<\/em>-&gt; <em>\u2018Templates\u2019<\/em> -&gt; <em>\u2018Visual C#\u2019<\/em> -&gt; <em>\u2018Windows Classic Desktop\u2019<\/em> tree items.<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, in the right side, select <em>\u2018Windows Forms App (.NET Framework)\u2019<\/em><\/li>\n<li>In the <em>\u2018Name\u2019<\/em> textbox, type <em>\u2018winClient\u2019<\/em> and click the \u2018Ok\u2019 button<\/li>\n<\/ol>\n<\/li>\n<li>Add a reference to the web API and create the proxy\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the <em>\u2018winClient\u2019<\/em> project, click <em>\u2018Add\u2019<\/em> -&gt; <em>\u2018REST API Client\u2019<\/em> menu item.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"763\" height=\"775\" class=\"wp-image-71407\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-44.png\" \/><\/p>\n<\/li>\n<li>In the <em>\u2018Add REST API Client\u2019<\/em> window, <em>\u2018Swagger Url\u2019<\/em> textbox, type <em>http:\/\/localhost\/webDemo\/Swagger\/docs\/v1<\/em> .<\/li>\n<li>In the <em>\u2018Client Namespace\u2019<\/em> textbox, type <em>\u2018SvcRest\u2019<\/em> and click the \u2018Ok\u2019 button.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"736\" height=\"461\" class=\"wp-image-71408\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-45.png\" \/><\/p>\n<p>It seems that nothing happened. Inside <em>\u2018Web Publish Activity\u2019<\/em> window you will be able to see what happened and an error message: <em>\u2018Found operation object with duplicate OperationId &#8216;Values_Get&#8217;. OperationId must be unique among all operations described in the API\u2019<\/em>.<\/p>\n<p>The client tool doesn\u2019t support a REST API with operation overload, and our demo API has two GET methods. We need to resolve this problem before we proceed.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Support for operation overload<\/h2>\n<p>This lack of support for operation overload is a big flaw, since even the demo web API application, as you may be noticing, uses operation overloads, it has two <strong>GET<\/strong> actions, with and without a parameter.<\/p>\n<p>There are two possible solutions:<\/p>\n<ul>\n<li>Change the actions name to avoid an overload<\/li>\n<li>Implement an operation filter that will intercept the JSON file creation and avoid the overload inside the JSON file.<\/li>\n<\/ul>\n<p>Let&#8217;s implement an operation filter in a step-by-step walkthrough:<\/p>\n<ol>\n<li>Add a new Class Library to the solution\n<ol type=\"a\">\n<li>In the \u2018<em>Solution Explorer\u2019<\/em> window, right-click the solution, click <em>\u2018Add\u2019<\/em>-&gt;<em>\u2018New Project\u2019<\/em> context menu item<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, inside the left side tree view, select <em>\u2018Installed\u2019<\/em>-&gt;<em>\u2018Templates\u2019<\/em>-&gt;<em>\u2018Visual C#\u2019<\/em> -&gt;<em>\u2018Windows Classic Desktop\u2019<\/em> tree items.<\/li>\n<li>In the <em>\u2018New Project\u2019<\/em> dialog box, in the right side, select <em>\u2018Class Library (.NET Framework)\u2019<\/em><\/li>\n<li>In the <em>\u2018Name\u2019<\/em> textbox, type <em>\u2018libTools\u2019<\/em> and click the \u2018Ok\u2019 button\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1181\" height=\"820\" class=\"wp-image-71409\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-46.png\" \/><\/p>\n<\/li>\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click <em>\u2018Class1.cs\u2019<\/em> file, below <em>\u2018libTools\u2019<\/em> project, and click <em>\u2018Delete\u2019<\/em> menu item.<\/li>\n<\/ol>\n<\/li>\n<li>Install the package <em>\u2018SwashBuckle.Core.Net45\u2019 <\/em>in the new Class Library project. I\u2019m installing only the core of <strong>SwashBuckle<\/strong>, not all the libraries.\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the <em>\u2018libTools\u2019<\/em> project and click <em>\u2018Manage nuget packet\u2019<\/em> menu item.<\/li>\n<li>In the <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018Browse\u2019<\/em><\/li>\n<li>In the textbox inside <em>\u2018Nuget Package Manager\u2019<\/em> window, type <em>\u2018SwashBuckle\u2019<\/em>.<\/li>\n<li>In the left side of <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018SwashBuckle.Core.Net45\u2019<\/em> package<\/li>\n<li>In the right side of <em>\u2018Nuget Package Manager\u2019<\/em> window, click <em>\u2018Install\u2019<\/em> button.<\/li>\n<li>In the <em>\u2018Review Changes\u2019<\/em> window, click the \u2018Ok\u2019 button.<\/li>\n<li>In the <em>\u2018License Acceptance\u2019<\/em> window, click <em>\u2018I Accept\u2019<\/em> button.<\/li>\n<\/ol>\n<\/li>\n<li>Implement the operation filter\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click <em>\u2018libTools\u2019<\/em> project, click <em>\u2018Add\u2019<\/em>-&gt; <em>\u2018Class&#8230;\u2019<\/em> context menu item<\/li>\n<li>In the <em>\u2018Add New Item\u2019<\/em> window, type <em>\u2018MultipleOperationsWithSameVerbFilter.cs\u2019<\/em> in the <em>\u2018Name\u2019<\/em> textbox.\n<p><img loading=\"lazy\" decoding=\"async\" width=\"989\" height=\"559\" class=\"wp-image-71410\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-47.png\" \/><\/p>\n<\/li>\n<li>Copy the code below and paste inside the new file, replacing the empty class:\n<pre class=\"theme:vs2012 lang:c# decode:true\">    using Swashbuckle.Swagger;\r\n      using System.Web.Http.Description;\r\n      public class MultipleOperationsWithSameVerbFilter : IOperationFilter\r\n      {\r\n          public void Apply(\r\n              Operation operation,\r\n              SchemaRegistry schemaRegistry,\r\n              ApiDescription apiDescription)\r\n          {\r\n              if (operation.parameters != null)\r\n              {\r\n                  operation.operationId += \"By\";\r\n                  foreach (var parm in operation.parameters)\r\n                  {\r\n                      operation.operationId += string.Format(\"{0}\",\r\n                          parm.name);\r\n                  }\r\n              }\r\n          }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>In the <em>\u2018webDemo\u2019<\/em> project, add a reference to the <em>\u2018libTools\u2019<\/em> project\n<ol type=\"a\">\n<li>In <em>\u2018Solution Explorer\u2019<\/em> window, right-click <em>\u2018webDemo\u2019<\/em> project, click <em>\u2018Add\u2019<\/em>-&gt; <em>\u2018Reference\u2019<\/em> context menu item<\/li>\n<li>Inside <em>\u2018Reference Manager\u2019<\/em> window, on the left side, select <em>\u2018Projects\u2019<\/em> -&gt; <em>\u2018Solution\u2019<\/em> item<\/li>\n<li>Inside <em>\u2018Reference Manager\u2019<\/em> window, on the right side, check the box besides <em>\u2018libTools\u2019<\/em> and click the \u2018Ok\u2019 button\n<p><img loading=\"lazy\" decoding=\"async\" width=\"982\" height=\"682\" class=\"wp-image-71411\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-48.png\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>Change <strong>Swagger <\/strong>configuration to use the new operation filter\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, inside <em>\u2018webDemo\u2019<\/em> project, open the <em>\u2018App_Start\u2019<\/em> folder and double click <em>\u2018SwaggerConfig.cs\u2019<\/em> file.<\/li>\n<li>At the top of <em>\u2018SwaggerConfig.cs\u2019<\/em> file, add the following line:\n<pre class=\"theme:vs2012 lang:c# decode:true\">using libTools;<\/pre>\n<\/li>\n<li>Inside the <em>\u2018Register\u2019<\/em> method, inside the following block:\n<pre class=\"theme:vs2012 lang:c# decode:true\">            GlobalConfiguration.Configuration \r\n                  .EnableSwagger(c =&gt;\r\n                      {<\/pre>\n<p>Add the following line of code:<\/p>\n<pre class=\"theme:vs2012 lang:c# decode:true\">                        c.OperationFilter&lt;MultipleOperationsWithSameVerbFilter&gt;();<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the solution and click <em>\u2018Rebuild Solution\u2019<\/em> menu item\n<p><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"758\" class=\"wp-image-71412\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-49.png\" \/><\/p>\n<\/li>\n<li>Repeat the step 2 of the client proxy creation, this time it will work.<\/li>\n<\/ol>\n<h2>Using the proxy in the Client Application<\/h2>\n<p>Now the web API proxy is built inside the client project, it\u2019s time to use it to access the web API. However, the proxy needs an additional class to control authentication. Another flaw in this feature is the fact it doesn&#8217;t deal well with anonymous authentication, but we can overcome this problem with a quick fix.<\/p>\n<ol>\n<li>Install the <em>\u2018Microsoft.Rest.ClientRuntime\u2019<\/em> package in the <em>\u2018libTools\u2019<\/em> project. This package is needed for our fix.\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the <em>\u2018libTools\u2019<\/em> project and click <em>\u2018Manage nuget packet\u2019<\/em> menu item.<\/li>\n<li>In the <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018Browse\u2019<\/em><\/li>\n<li>In the textbox inside <em>\u2018Nuget Package Manager\u2019<\/em> window, type <em>\u2018Microsoft.Rest.ClientRuntime\u2019<\/em>.<\/li>\n<li>In the left side of <em>\u2018Nuget Package Manager\u2019<\/em> window, select <em>\u2018Microsoft.Rest.ClientRuntime\u2019<\/em> package<\/li>\n<li>In the right side of <em>\u2018Nuget Package Manager\u2019<\/em> window, click <em>\u2018Install\u2019<\/em> button.<\/li>\n<li>In the <em>\u2018Review Changes\u2019<\/em> window, click the \u2018Ok\u2019 button.<\/li>\n<li>In the <em>\u2018License Acceptance\u2019<\/em> window, click <em>\u2018I Accept\u2019<\/em> button.<\/li>\n<\/ol>\n<\/li>\n<li>Implement the <strong>AnonymousCredential<\/strong> class. It will sove the anonymous authentication problem.\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click <em>\u2018libTools\u2019<\/em> project and click <em>\u2018Add\u2019<\/em>-&gt; <em>\u2018Class\u2019<\/em> context menu item.<\/li>\n<li>In the <em>\u2018Add new item\u2019<\/em> dialog box, type <em>\u2018AnonymousCredential.cs\u2019<\/em> in <em>\u2018Name\u2019<\/em> textbox and click the \u2018Ok\u2019 button<\/li>\n<li>In the top of the new file, add the following statement:\n<pre class=\"theme:vs2012 lang:c# decode:true\">using Microsoft.Rest;<\/pre>\n<\/li>\n<li>Use the following code for this class. Yes, nothing is needed but the inheritance.\n<pre class=\"theme:vs2012 lang:c# decode:true\">public class AnonymousCredential : ServiceClientCredentials\r\n  {\r\n  }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>3) Build the client Windows form to access the API\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, below <em>\u2018winClient\u2019<\/em> project, double-click <em>\u2018Form1.cs\u2019<\/em> file.<\/li>\n<li>From the <em>\u2018Toolbox\u2019<\/em> window, add three buttons inside the form.<\/li>\n<li>Change the button properties according to the following:\n<p>Name: cmdAllValues <br \/>\n Text: All Values<\/p>\n<p>Name: cmdValue <br \/>\n Text: Single Value<\/p>\n<p>Name: cmdUpdate <br \/>\n Text: Update<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"966\" height=\"580\" class=\"wp-image-71413\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/06\/word-image-50.png\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>In the Windows project, add a reference to the <em>\u2018libTools\u2019<\/em> project\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click <em>\u2018winClient\u2019<\/em> project, click <em>\u2018Add\u2019<\/em>-&gt; <em>\u2018Reference\u2019<\/em> context menu item<\/li>\n<li>Inside <em>\u2018Reference Manager\u2019<\/em> window, on the left side, select <em>\u2018Projects\u2019<\/em> -&gt; <em>\u2018Solution\u2019<\/em> item<\/li>\n<li>Inside <em>\u2018Reference Manager\u2019<\/em> window, on the right side, check the box besides <em>\u2018libTools\u2019<\/em> and click the \u2018Ok\u2019 button<\/li>\n<\/ol>\n<\/li>\n<li>Add the code for the <em>\u2018All Values\u2019<\/em> button\n<ol type=\"a\">\n<li>Select the <em>\u2018Form1.cs (design)\u2019<\/em> page<\/li>\n<li>Double click the <em>\u2018All Values\u2019<\/em> button, this will create a click event for the button.<\/li>\n<li>In the top of the <em>\u2018Form1.cs\u2019<\/em> file (already opened by the previous task), add the following statements:\n<pre class=\"theme:vs2012 lang:c# decode:true\">using libTools;\r\n  using svcRest;<\/pre>\n<\/li>\n<li>Change the <em>\u2018cmdAllValues_Click\u2019<\/em> for the following code:\n<pre class=\"theme:vs2012 lang:c# decode:true\">        private async void cmdAllValues_Click(object sender, EventArgs e)\r\n          {\r\n              SvcRestClient client = \r\n                  new SvcRestClient(new Uri(\"http:\/\/localhost\/webDemo\"),\r\n                      new AnonymousCredential());\r\n              var result = client.Values.Get();\r\n          \r\n              foreach(var x in result)\r\n              {\r\n                  MessageBox.Show(x);\r\n              }\r\n          }<\/pre>\n<p>It&#8217;s important to notice the following details:<\/p>\n<ul>\n<li>There are both, synchronous and asynchronous methods in the proxy. The code is illustrating the synchronous call.<\/li>\n<li>Most methods are extension methods: due to that, we need the <em>\u2018Using svcRest\u2019<\/em> statement.<\/li>\n<li>You don&#8217;t need to deal with the protocol details to call the API. That&#8217;s the advantage of the proxy. We have this advantage for webservices ever since .NET was created; now we can work in this way also with web APIs.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<li>Add the code for the <em>\u2018Single Value\u2019<\/em> button\n<ol type=\"a\">\n<li>Select the <em>\u2018Form1.cs (design)\u2019<\/em> page<\/li>\n<li>Double click the <em>\u2018Single Value\u2019<\/em> button, this will create a click event for the button.<\/li>\n<li>Change the <em>\u2018cmdValue_Click\u2019<\/em> for the following code:\n<pre class=\"theme:vs2012 lang:c# decode:true\">        private async void cmdValue_Click(object sender, EventArgs e)\r\n          {\r\n              SvcRestClient client = \r\n                  new SvcRestClient(new Uri(\"http:\/\/localhost\/webDemo\"),\r\n                    new AnonymousCredential());\r\n              var result = client.Values.GetByid(1);\r\n              MessageBox.Show(result);\r\n          }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>Add the code for the <em>\u2018Update\u2019<\/em> button\n<ol type=\"a\">\n<li>Select the <em>\u2018Form1.cs (design)\u2019<\/em> page<\/li>\n<li>Double click the <em>\u2018Update\u2019<\/em> button, this will create a click event for the button.<\/li>\n<li>Change the <em>\u2018cmdUpdate_Click\u2019<\/em> for the following code:\n<pre class=\"theme:vs2012 lang:c# decode:true\">        private async void cmdUpdate_Click(object sender, EventArgs e)\r\n          {\r\n              SvcRestClient client = \r\n                  new SvcRestClient(new Uri(\"http:\/\/localhost\/webDemo\"),\r\n                    new AnonymousCredential());\r\n              client.Values.PutByidvalue(1, \"New Value\");\r\n                  \r\n              MessageBox.Show(\"Change Completed!\");\r\n          }<\/pre>\n<\/li>\n<\/ol>\n<\/li>\n<li>Execute and test the application\n<ol type=\"a\">\n<li>In the <em>\u2018Solution Explorer\u2019<\/em> window, right-click the <em>\u2018winClient\u2019<\/em> project and click <em>\u2018Set as Startup Project\u2019<\/em><\/li>\n<li>Click <em>\u2018Start\u2019<\/em> button in the toolbox to run the application<\/li>\n<li>Click the <em>\u2018All Values\u2019<\/em> button, the <em>\u2018Single Value\u2019<\/em> button, <em>\u2018Update\u2019<\/em> button and <em>\u2018Single Value\u2019<\/em> button again, in sequence and click the \u2018Ok\u2019 button when needed, to check the result. The API calls will be working well.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Conclusion<\/h2>\n<p>These new features are really game-changing, improving the way that we use web APIs. This is just the beginning, because there are much more about these features that are coming.<\/p>\n<p>You may have noticed some flaws; for example, the client only creates a C# proxy: However, it\u2019s very common nowadays to require a <strong>Javascript<\/strong> proxy, particularly for the consumption of web APIs in <strong>AngularJS<\/strong> applications. It\u2019s important to remember that the core of this technology is the JSON format that describes the web API. Anyone can build a new Visual Studio Add-In that is capable of reading this JSON description and creating a <strong>Javascript<\/strong> proxy. We will, for sure, see improvements in a short while.<\/p>\n<p><strong>Swagger<\/strong> deserves more advanced articles than this, to be sure, but for now I will give you some links for further reading:<\/p>\n<ul>\n<li>How to customize <strong>SwashBuckle<\/strong> documentation interface: <em><a href=\"https:\/\/stackoverflow.com\/questions\/31647635\/replace-swashbuckle-ui-completely\">https:\/\/stackoverflow.com\/questions\/31647635\/replace-swashbuckle-ui-completely<\/a><\/em><\/li>\n<li><strong>SwashBuckle<\/strong> documentation, including authentication management, hosting management and several other customizations possible: <em><a href=\"https:\/\/github.com\/domaindrivendev\/Swashbuckle\">https:\/\/github.com\/domaindrivendev\/Swashbuckle<\/a><\/em><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The OpenAPI \u2018Swagger\u2019 Specification defines a protocol that allows applications to discover, and generate documentation of methods, parameters and models of REST APIs, This provides a way for any software to identify the features of a REST API. It does for REST APIs what WSDL (Web Service Description Language) did for web services. Visual Studio now provides  it to support proxy creation for REST APIs, as Dennes Torres explains.&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[],"coauthors":[6810],"class_list":["post-71395","post","type-post","status-publish","format-standard","hentry","category-dotnet-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71395","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=71395"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71395\/revisions"}],"predecessor-version":[{"id":71845,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71395\/revisions\/71845"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=71395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=71395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=71395"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=71395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}