-
Notifications
You must be signed in to change notification settings - Fork 709
/
Copy pathStartup.cs
193 lines (168 loc) · 8.48 KB
/
Startup.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
namespace ApiVersioning.Examples;
using Asp.Versioning.Conventions;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.Extensions.Primitives;
using Microsoft.OData;
using Newtonsoft.Json.Serialization;
using Owin;
using Swashbuckle.Application;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web.Http;
using System.Web.Http.Description;
using static Microsoft.AspNet.OData.Query.AllowedQueryOptions;
/// <summary>
/// Represents the startup process for the application.
/// </summary>
public partial class Startup
{
/// <summary>
/// Configures the application using the provided builder.
/// </summary>
/// <param name="builder">The current application builder.</param>
public void Configuration( IAppBuilder builder )
{
var configuration = new HttpConfiguration();
var httpServer = new HttpServer( configuration );
// note: this example application intentionally only illustrates the
// bare minimum configuration for OpenAPI with partial OData support.
// see the OpenAPI or OData OpenAPI examples for additional options.
configuration.EnableDependencyInjection();
configuration.Select();
configuration.AddApiVersioning();
// note: this is required to make the default swagger json
// settings match the odata conventions applied by EnableLowerCamelCase()
configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
// NOTE: when you mix OData and non-Data controllers in Web API, it's RECOMMENDED to only use
// convention-based routing. using attribute routing may not work as expected due to limitations
// in the underlying routing system. the order of route registration is important as well.
//
// for example:
//
// configuration.MapVersionedODataRoute( "odata", "api", modelBuilder );
// configuration.Routes.MapHttpRoute( "Default", "api/{controller}/{id}", new { id = RouteParameter.Optional } );
//
// for more information see the advanced OData example
configuration.MapHttpAttributeRoutes();
// add the versioned IApiExplorer and capture the strongly-typed implementation (e.g. ODataApiExplorer vs IApiExplorer)
// note: the specified format code will format the version as "'v'major[.minor][-status]"
var apiExplorer = configuration.AddODataApiExplorer(
options =>
{
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]"
options.GroupNameFormat = "'v'VVV";
// configure query options (which cannot otherwise be configured by OData conventions)
options.QueryOptions.Controller<BooksController>()
.Action( c => c.Get( default ) )
.Allow( Skip | Count )
.AllowTop( 100 )
.AllowOrderBy( "title", "published" );
// applies model bound settings implicitly using an ad hoc EDM. alternatively, you can create your own
// IModelConfiguration + IODataQueryOptionsConvention for full control over what goes in the ad hoc EDM.
options.AdHocModelBuilder.ModelConfigurations.Add( new ImplicitModelBoundSettingsConvention() );
} );
configuration.EnableSwagger(
"{apiVersion}/swagger",
swagger =>
{
// build a swagger document and endpoint for each discovered API version
swagger.MultipleApiVersions(
( apiDescription, version ) => apiDescription.GetGroupName() == version,
info =>
{
foreach ( var group in apiExplorer.ApiDescriptions )
{
var description = new StringBuilder( "A sample application with some OData, OpenAPI, Swashbuckle, and API versioning." );
if ( group.IsDeprecated )
{
description.Append( " This API version has been deprecated." );
}
if ( group.SunsetPolicy is { } policy )
{
if ( policy.Date is { } when )
{
description.Append( " The API will be sunset on " )
.Append( when.Date.ToShortDateString() )
.Append( '.' );
}
if ( policy.HasLinks )
{
description.AppendLine();
var rendered = false;
for ( var i = 0; i < policy.Links.Count; i++ )
{
var link = policy.Links[i];
if ( link.Type == "text/html" )
{
if ( !rendered )
{
description.AppendLine();
description.Append( "**Links**" );
description.AppendLine();
rendered = true;
}
if ( StringSegment.IsNullOrEmpty( link.Title ) )
{
if ( link.LinkTarget.IsAbsoluteUri )
{
description.AppendLine( $"- {link.LinkTarget.OriginalString}" );
}
else
{
description.AppendFormat( "- <a href=\"{0}\">{0}</a>", link.LinkTarget.OriginalString );
description.AppendLine();
}
}
else
{
description.AppendLine( $"- [{link.Title}]({link.LinkTarget.OriginalString})" );
}
}
}
}
}
description.AppendLine();
description.AppendLine( "**Additional Information**" );
info.Version( group.Name, $"Sample API {group.ApiVersion}" )
.Contact( c => c.Name( "Bill Mei" ).Email( "[email protected]" ) )
.Description( description.ToString() )
.License( l => l.Name( "MIT" ).Url( "https://opensource.org/licenses/MIT" ) )
.TermsOfService( "Shareware" );
}
} );
// add a custom operation filter which documents the implicit API version parameter
swagger.OperationFilter<SwaggerDefaultValues>();
// integrate xml comments
swagger.IncludeXmlComments( XmlCommentsFilePath );
} )
.EnableSwaggerUi( swagger => swagger.EnableDiscoveryUrlSelector() );
builder.UseWebApi( httpServer );
}
/// <summary>
/// Get the root content path.
/// </summary>
/// <value>The root content path of the application.</value>
public static string ContentRootPath
{
get
{
var app = AppDomain.CurrentDomain;
if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
{
return app.BaseDirectory;
}
return app.RelativeSearchPath;
}
}
private static string XmlCommentsFilePath
{
get
{
var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
return Path.Combine( ContentRootPath, fileName );
}
}
}