/articles/app-service-api/app-service-api-dotnet-swashbuckle-customize.md
Markdown | 251 lines | 178 code | 73 blank | 0 comment | 0 complexity | 9547d30cda1607e78530148b16089f82 MD5 | raw file
1
2<properties
3 pageTitle="Customize Swashbuckle-generated API definitions"
4 description="Learn how to customize Swagger API definitions that are generated by Swashbuckle for an API app in Azure App Service."
5 services="app-service\api"
6 documentationCenter=".net"
7 authors="bradygaster"
8 manager="wpickett"
9 editor="jimbe"/>
10
11<tags
12 ms.service="app-service-api"
13 ms.workload="web"
14 ms.tgt_pltfrm="dotnet"
15 ms.devlang="na"
16 ms.topic="article"
17 ms.date="02/22/2016"
18 ms.author="rachelap"/>
19
20# Customize Swashbuckle-generated API definitions
21
22## Overview
23
24This article explains how to customize Swashbuckle to handle common scenarios where you may want to alter the default behavior:
25
26* Swashbuckle generates duplicate operation identifiers for overloads of controller methods
27* Swashbuckle assumes that the only valid response from a method is HTTP 200 (OK)
28
29## Customize operation identifier generation
30
31Swashbuckle 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.
32
33For example, the following controller code causes Swashbuckle to generate three Contact_Get operation ids.
34
35
36
37
38
39You can solve the problem manually by giving the methods unique names, such as the following for this example:
40
41* Get
42* GetById
43* GetPage
44
45The alternative is to extend Swashbuckle to make it automatically generate unique operation ids.
46
47The 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.
48
491. Create a custom `IOperationFilter` implementation
50
51 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.
52
53 using Swashbuckle.Swagger;
54 using System.Web.Http.Description;
55
56 namespace ContactsList
57 {
58 public class MultipleOperationsWithSameVerbFilter : IOperationFilter
59 {
60 public void Apply(
61 Operation operation,
62 SchemaRegistry schemaRegistry,
63 ApiDescription apiDescription)
64 {
65 if (operation.parameters != null)
66 {
67 operation.operationId += "By";
68 foreach (var parm in operation.parameters)
69 {
70 operation.operationId += string.Format("{0}",parm.name);
71 }
72 }
73 }
74 }
75 }
76
772. In *App_Start\SwaggerConfig.cs* file, call the `OperationFilter` method to cause Swashbuckle to use the new `IOperationFilter` implementation.
78
79 c.OperationFilter<MultipleOperationsWithSameVerbFilter>();
80
81 
82
83 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.
84
85 After you make this change, your `IOperationFilter` implementation is used and causes unique operation ids to be generated.
86
87 
88
89<a id="multiple-response-codes" name="multiple-response-codes"></a>
90
91## Allow response codes other than 200
92
93By 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.
94
95 [ResponseType(typeof(Contact))]
96 public HttpResponseMessage Get(int id)
97 {
98 var contacts = GetContacts();
99
100 var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
101
102 if (requestedContact == null)
103 {
104 return Request.CreateResponse(HttpStatusCode.NotFound);
105 }
106 else
107 {
108 return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
109 }
110 }
111
112In this scenario, the Swagger that Swashbuckle generates by default specifies only one legitimate HTTP status code, HTTP 200.
113
114
115
116Since 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.
117
118 if (statusCode != HttpStatusCode.OK)
119 {
120 HttpOperationException<object> ex = new HttpOperationException<object>();
121 ex.Request = httpRequest;
122 ex.Response = httpResponse;
123 ex.Body = null;
124 if (shouldTrace)
125 {
126 ServiceClientTracing.Error(invocationId, ex);
127 }
128 throw ex;
129 }
130
131Swashbuckle 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.
132
133### Customize expected response codes using XML comments
134
135Use this method to specify response codes if your Swashbuckle version is earlier than 5.1.5.
136
1371. 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.
138
139 /// <summary>
140 /// Returns the specified contact.
141 /// </summary>
142 /// <param name="id">The ID of the contact.</param>
143 /// <returns>A contact record with an HTTP 200, or null with an HTTP 404.</returns>
144 /// <response code="200">OK</response>
145 /// <response code="404">Not Found</response>
146 [ResponseType(typeof(Contact))]
147 public HttpResponseMessage Get(int id)
148 {
149 var contacts = GetContacts();
150
151 var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
152
153 if (requestedContact == null)
154 {
155 return Request.CreateResponse(HttpStatusCode.NotFound);
156 }
157 else
158 {
159 return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
160 }
161 }
162
1631. Add instructions in the *SwaggerConfig.cs* file to direct Swashbuckle to make use of the XML documentation file.
164
165 * Open *SwaggerConfig.cs* and create a method on the *SwaggerConfig* class to specify the path to the documentation XML file.
166
167 private static string GetXmlCommentsPath()
168 {
169 return string.Format(@"{0}\XmlComments.xml",
170 System.AppDomain.CurrentDomain.BaseDirectory);
171 }
172
173 * Scroll down in the *SwaggerConfig.cs* file until you see the commented-out line of code resembling the screen shot below.
174
175 
176
177 * Uncomment the line to enable the XML comments processing during Swagger generation.
178
179 
180
1811. 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.
182
183 
184
185Once 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.
186
187
188
189When 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.
190
191 if (statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.NotFound)
192 {
193 HttpOperationException<object> ex = new HttpOperationException<object>();
194 ex.Request = httpRequest;
195 ex.Response = httpResponse;
196 ex.Body = null;
197 if (shouldTrace)
198 {
199 ServiceClientTracing.Error(invocationId, ex);
200 }
201 throw ex;
202 }
203
204The 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.
205
206### Customize expected response codes using the SwaggerResponse attribute
207
208The [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.
209
2101. In **Solution Explorer**, right-click your Web API project and click **Manage NuGet Packages**.
211
212 
213
2141. Click the *Update* button next to the *Swashbuckle* NuGet package.
215
216 
217
2181. Add the *SwaggerResponse* attributes to the Web API action methods for which you want to specify valid HTTP response codes.
219
220 [SwaggerResponse(HttpStatusCode.OK)]
221 [SwaggerResponse(HttpStatusCode.NotFound)]
222 [ResponseType(typeof(Contact))]
223 public HttpResponseMessage Get(int id)
224 {
225 var contacts = GetContacts();
226
227 var requestedContact = contacts.FirstOrDefault(x => x.Id == id);
228 if (requestedContact == null)
229 {
230 return Request.CreateResponse(HttpStatusCode.NotFound);
231 }
232 else
233 {
234 return Request.CreateResponse<Contact>(HttpStatusCode.OK, requestedContact);
235 }
236 }
237
2382. Add a `using` statement for the attribute's namespace:
239
240 using Swashbuckle.Swagger.Annotations;
241
2421. Browse to the */swagger/docs/v1* URL of your project and the various HTTP response codes will be visible in the Swagger JSON.
243
244 
245
246The 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.
247
248## Next steps
249
250This 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).
251