PageRenderTime 134ms CodeModel.GetById 47ms RepoModel.GetById 2ms app.codeStats 0ms

/articles/app-service-api/app-service-api-dotnet-swashbuckle-customize.md

https://gitlab.com/yeah568/azure-content
Markdown | 251 lines | 178 code | 73 blank | 0 comment | 0 complexity | 9547d30cda1607e78530148b16089f82 MD5 | raw file
  1. <properties
  2. pageTitle="Customize Swashbuckle-generated API definitions"
  3. description="Learn how to customize Swagger API definitions that are generated by Swashbuckle for an API app in Azure App Service."
  4. services="app-service\api"
  5. documentationCenter=".net"
  6. authors="bradygaster"
  7. manager="wpickett"
  8. editor="jimbe"/>
  9. <tags
  10. ms.service="app-service-api"
  11. ms.workload="web"
  12. ms.tgt_pltfrm="dotnet"
  13. ms.devlang="na"
  14. ms.topic="article"
  15. ms.date="02/22/2016"
  16. ms.author="rachelap"/>
  17. # Customize Swashbuckle-generated API definitions
  18. ## Overview
  19. This article explains how to customize Swashbuckle to handle common scenarios where you may want to alter the default behavior:
  20. * Swashbuckle generates duplicate operation identifiers for overloads of controller methods
  21. * Swashbuckle assumes that the only valid response from a method is HTTP 200 (OK)
  22. ## Customize operation identifier generation
  23. Swashbuckle generates Swagger operation identifiers by concatenating controller name and method name. This pattern creates a problem when you have multiple overloads of a method: Swashbuckle generates duplicate operation ids, which is invalid Swagger JSON.
  24. For example, the following controller code causes Swashbuckle to generate three Contact_Get operation ids.
  25. ![](./media/app-service-api-dotnet-swashbuckle-customize/multiplegetsincode.png)
  26. ![](./media/app-service-api-dotnet-swashbuckle-customize/multiplegetsinjson.png)
  27. You can solve the problem manually by giving the methods unique names, such as the following for this example:
  28. * Get
  29. * GetById
  30. * GetPage
  31. The alternative is to extend Swashbuckle to make it automatically generate unique operation ids.
  32. The following steps show how to customize Swashbuckle by using the *SwaggerConfig.cs* file that is included in the project by the Visual Studio API Apps Preview project template. You can also customize Swashbuckle in a Web API project that you configure for deployment as an API app.
  33. 1. Create a custom `IOperationFilter` implementation
  34. The `IOperationFilter` interface provides an extensibility point for Swashbuckle users who want to customize various aspects of the Swagger metadata process. The following code demonstrates one method of changing the operation-id-generation behavior. The code appends parameter names to the operation id name.
  35. using Swashbuckle.Swagger;
  36. using System.Web.Http.Description;
  37. namespace ContactsList
  38. {
  39. public class MultipleOperationsWithSameVerbFilter : IOperationFilter
  40. {
  41. public void Apply(
  42. Operation operation,
  43. SchemaRegistry schemaRegistry,
  44. ApiDescription apiDescription)
  45. {
  46. if (operation.parameters != null)
  47. {
  48. operation.operationId += "By";
  49. foreach (var parm in operation.parameters)
  50. {
  51. operation.operationId += string.Format("{0}",parm.name);
  52. }
  53. }
  54. }
  55. }
  56. }
  57. 2. In *App_Start\SwaggerConfig.cs* file, call the `OperationFilter` method to cause Swashbuckle to use the new `IOperationFilter` implementation.
  58. c.OperationFilter<MultipleOperationsWithSameVerbFilter>();
  59. ![](./media/app-service-api-dotnet-swashbuckle-customize/usefilter.png)
  60. The *SwaggerConfig.cs* file that is dropped in by the Swashbuckle NuGet package contains many commented-out examples of extensibility points. The additional comments are not shown here.
  61. After you make this change, your `IOperationFilter` implementation is used and causes unique operation ids to be generated.
  62. ![](./media/app-service-api-dotnet-swashbuckle-customize/uniqueids.png)
  63. <a id="multiple-response-codes" name="multiple-response-codes"></a>
  64. ## Allow response codes other than 200
  65. By default, Swashbuckle assumes that an HTTP 200 (OK) response is the *only* legitimate response from a Web API method. In some cases, you may want to return other response codes without causing the client to raise an exception. For example, the following Web API code demonstrates a scenario in which you would want the client to accept either a 200 or a 404 as valid responses.
  66. [ResponseType(typeof(Contact))]
  67. public HttpResponseMessage Get(int id)
  68. {
  69. var contacts = GetContacts();
  70. var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
  71. if (requestedContact == null)
  72. {
  73. return Request.CreateResponse(HttpStatusCode.NotFound);
  74. }
  75. else
  76. {
  77. return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
  78. }
  79. }
  80. In this scenario, the Swagger that Swashbuckle generates by default specifies only one legitimate HTTP status code, HTTP 200.
  81. ![](./media/app-service-api-dotnet-swashbuckle-customize/http-200-output-only.png)
  82. Since Visual Studio uses the Swagger API definition to generate code for the client, it creates client code that raises an exception for any response other than an HTTP 200. The code below is from a C# client generated for this sample Web API method.
  83. if (statusCode != HttpStatusCode.OK)
  84. {
  85. HttpOperationException<object> ex = new HttpOperationException<object>();
  86. ex.Request = httpRequest;
  87. ex.Response = httpResponse;
  88. ex.Body = null;
  89. if (shouldTrace)
  90. {
  91. ServiceClientTracing.Error(invocationId, ex);
  92. }
  93. throw ex;
  94. }
  95. Swashbuckle provides two ways of customizing the list of expected HTTP response codes that it generates, using XML comments or the `SwaggerResponse` attribute. The attribute is easier, but it is only available in Swashbuckle 5.1.5 or later. The API Apps preview new-project template in Visual Studio 2013 includes Swashbuckle version 5.0.0, so if you used the template and don't want to update Swashbuckle, your only option is to use XML comments.
  96. ### Customize expected response codes using XML comments
  97. Use this method to specify response codes if your Swashbuckle version is earlier than 5.1.5.
  98. 1. First, add XML documentation comments over the methods you wish to specify HTTP response codes for. Taking the sample Web API action shown above and applying the XML documentation to it would result in code like the following example.
  99. /// <summary>
  100. /// Returns the specified contact.
  101. /// </summary>
  102. /// <param name="id">The ID of the contact.</param>
  103. /// <returns>A contact record with an HTTP 200, or null with an HTTP 404.</returns>
  104. /// <response code="200">OK</response>
  105. /// <response code="404">Not Found</response>
  106. [ResponseType(typeof(Contact))]
  107. public HttpResponseMessage Get(int id)
  108. {
  109. var contacts = GetContacts();
  110. var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
  111. if (requestedContact == null)
  112. {
  113. return Request.CreateResponse(HttpStatusCode.NotFound);
  114. }
  115. else
  116. {
  117. return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
  118. }
  119. }
  120. 1. Add instructions in the *SwaggerConfig.cs* file to direct Swashbuckle to make use of the XML documentation file.
  121. * Open *SwaggerConfig.cs* and create a method on the *SwaggerConfig* class to specify the path to the documentation XML file.
  122. private static string GetXmlCommentsPath()
  123. {
  124. return string.Format(@"{0}\XmlComments.xml",
  125. System.AppDomain.CurrentDomain.BaseDirectory);
  126. }
  127. * Scroll down in the *SwaggerConfig.cs* file until you see the commented-out line of code resembling the screen shot below.
  128. ![](./media/app-service-api-dotnet-swashbuckle-customize/xml-comments-commented-out.png)
  129. * Uncomment the line to enable the XML comments processing during Swagger generation.
  130. ![](./media/app-service-api-dotnet-swashbuckle-customize/xml-comments-uncommented.png)
  131. 1. In order to generate the XML documentation file, go into the project's properties and enable the XML documentation file as shown in the screenshot below.
  132. ![](./media/app-service-api-dotnet-swashbuckle-customize/enable-xml-documentation-file.png)
  133. Once you perform these steps, the Swagger JSON generated by Swashbuckle will reflect the HTTP response codes that you specified in the XML comments. The screenshot below demonstrates this new JSON payload.
  134. ![](./media/app-service-api-dotnet-swashbuckle-customize/swagger-multiple-responses.png)
  135. When you use Visual Studio to regenerate the client code for your REST API, the C# code accepts both the HTTP OK and Not Found status codes without raising an exception, allowing your consuming code to make decisions on how to handle the return of a null Contact record.
  136. if (statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.NotFound)
  137. {
  138. HttpOperationException<object> ex = new HttpOperationException<object>();
  139. ex.Request = httpRequest;
  140. ex.Response = httpResponse;
  141. ex.Body = null;
  142. if (shouldTrace)
  143. {
  144. ServiceClientTracing.Error(invocationId, ex);
  145. }
  146. throw ex;
  147. }
  148. The code for this demonstration can be found in [this GitHub repository](https://github.com/Azure-Samples/app-service-api-dotnet-swashbuckle-swaggerresponse). Along with the Web API project marked up with XML documentation comments is a Console Application project that contains a generated client for this API.
  149. ### Customize expected response codes using the SwaggerResponse attribute
  150. The [SwaggerResponse](https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Core/Swagger/Annotations/SwaggerResponseAttribute.cs) attribute is available in Swashbuckle 5.1.5 and later. In case you have an earlier version in your project, this section starts by explaining how to update the Swashbuckle NuGet package so that you can use this attribute.
  151. 1. In **Solution Explorer**, right-click your Web API project and click **Manage NuGet Packages**.
  152. ![](./media/app-service-api-dotnet-swashbuckle-customize/manage-nuget-packages.png)
  153. 1. Click the *Update* button next to the *Swashbuckle* NuGet package.
  154. ![](./media/app-service-api-dotnet-swashbuckle-customize/update-nuget-dialog.png)
  155. 1. Add the *SwaggerResponse* attributes to the Web API action methods for which you want to specify valid HTTP response codes.
  156. [SwaggerResponse(HttpStatusCode.OK)]
  157. [SwaggerResponse(HttpStatusCode.NotFound)]
  158. [ResponseType(typeof(Contact))]
  159. public HttpResponseMessage Get(int id)
  160. {
  161. var contacts = GetContacts();
  162. var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
  163. if (requestedContact == null)
  164. {
  165. return Request.CreateResponse(HttpStatusCode.NotFound);
  166. }
  167. else
  168. {
  169. return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
  170. }
  171. }
  172. 2. Add a `using` statement for the attribute's namespace:
  173. using Swashbuckle.Swagger.Annotations;
  174. 1. Browse to the */swagger/docs/v1* URL of your project and the various HTTP response codes will be visible in the Swagger JSON.
  175. ![](./media/app-service-api-dotnet-swashbuckle-customize/multiple-responses-post-attributes.png)
  176. The code for this demonstration can be found in [this GitHub repository](https://github.com/Azure-Samples/API-Apps-DotNet-Swashbuckle-Customization-MultipleResponseCodes-With-Attributes). Along with the Web API project decorated with the *SwaggerResponse* attribute is a Console Application project that contains a generated client for this API.
  177. ## Next steps
  178. This article has shown how to customize the way Swashbuckle generates operation ids and valid response codes. For more information, see [Swashbuckle on GitHub](https://github.com/domaindrivendev/Swashbuckle).