From 207421a038ea21efc1cec120ed12d01e73d8d9cd Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Mon, 5 Dec 2016 22:34:25 -0500 Subject: [PATCH] Add project files. --- PortlandiaQuotes.sln | 22 ++ PortlandiaQuotes/App_Start/SwaggerConfig.cs | 244 ++++++++++++++++++ PortlandiaQuotes/App_Start/WebApiConfig.cs | 24 ++ .../Controllers/ValuesController.cs | 39 +++ PortlandiaQuotes/Global.asax | 1 + PortlandiaQuotes/Global.asax.cs | 17 ++ PortlandiaQuotes/PortlandiaQuotes.csproj | 147 +++++++++++ PortlandiaQuotes/Project_Readme.html | 137 ++++++++++ PortlandiaQuotes/Properties/AssemblyInfo.cs | 35 +++ PortlandiaQuotes/Web.Debug.config | 30 +++ PortlandiaQuotes/Web.Release.config | 31 +++ PortlandiaQuotes/Web.config | 37 +++ PortlandiaQuotes/packages.config | 13 + 13 files changed, 777 insertions(+) create mode 100644 PortlandiaQuotes.sln create mode 100644 PortlandiaQuotes/App_Start/SwaggerConfig.cs create mode 100644 PortlandiaQuotes/App_Start/WebApiConfig.cs create mode 100644 PortlandiaQuotes/Controllers/ValuesController.cs create mode 100644 PortlandiaQuotes/Global.asax create mode 100644 PortlandiaQuotes/Global.asax.cs create mode 100644 PortlandiaQuotes/PortlandiaQuotes.csproj create mode 100644 PortlandiaQuotes/Project_Readme.html create mode 100644 PortlandiaQuotes/Properties/AssemblyInfo.cs create mode 100644 PortlandiaQuotes/Web.Debug.config create mode 100644 PortlandiaQuotes/Web.Release.config create mode 100644 PortlandiaQuotes/Web.config create mode 100644 PortlandiaQuotes/packages.config diff --git a/PortlandiaQuotes.sln b/PortlandiaQuotes.sln new file mode 100644 index 0000000..ca60bc1 --- /dev/null +++ b/PortlandiaQuotes.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PortlandiaQuotes", "PortlandiaQuotes\PortlandiaQuotes.csproj", "{3E229DCC-2FFD-4909-BC1F-8534544E94D1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E229DCC-2FFD-4909-BC1F-8534544E94D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E229DCC-2FFD-4909-BC1F-8534544E94D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E229DCC-2FFD-4909-BC1F-8534544E94D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E229DCC-2FFD-4909-BC1F-8534544E94D1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PortlandiaQuotes/App_Start/SwaggerConfig.cs b/PortlandiaQuotes/App_Start/SwaggerConfig.cs new file mode 100644 index 0000000..bc610be --- /dev/null +++ b/PortlandiaQuotes/App_Start/SwaggerConfig.cs @@ -0,0 +1,244 @@ +using System.Globalization; +using System.Linq; +using System.Web.Http; +using System.Web.Http.Description; +using Swashbuckle.Application; +using Swashbuckle.Swagger; +using WebActivatorEx; +using PortlandiaQuotes; + +[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] + +namespace PortlandiaQuotes +{ + public class SwaggerConfig + { + public static void Register() + { + var thisAssembly = typeof(SwaggerConfig).Assembly; + + GlobalConfiguration.Configuration + .EnableSwagger(c => + { + // By default, the service root url is inferred from the request used to access the docs. + // However, there may be situations (e.g. proxy and load-balanced environments) where this does not + // resolve correctly. You can workaround this by providing your own code to determine the root URL. + // + //c.RootUrl(req => GetRootUrlFromAppConfig()); + + // If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access + // the docs is taken as the default. If your API supports multiple schemes and you want to be explicit + // about them, you can use the "Schemes" option as shown below. + // + //c.Schemes(new[] { "http", "https" }); + + // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to + // hold additional metadata for an API. Version and title are required but you can also provide + // additional fields by chaining methods off SingleApiVersion. + // + c.SingleApiVersion("v1", "PortlandiaQuotes"); + + // If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion". + // In this case, you must provide a lambda that tells Swashbuckle which actions should be + // included in the docs for a given API version. Like "SingleApiVersion", each call to "Version" + // returns an "Info" builder so you can provide additional metadata per API version. + // + //c.MultipleApiVersions( + // (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), + // (vc) => + // { + // vc.Version("v2", "Swashbuckle Dummy API V2"); + // vc.Version("v1", "Swashbuckle Dummy API V1"); + // }); + + // You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API. + // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. + // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property + // at the document or operation level to indicate which schemes are required for an operation. To do this, + // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties + // according to your specific authorization implementation + // + //c.BasicAuth("basic") + // .Description("Basic HTTP Authentication"); + // + //c.ApiKey("apiKey") + // .Description("API Key Authentication") + // .Name("apiKey") + // .In("header"); + // + //c.OAuth2("oauth2") + // .Description("OAuth2 Implicit Grant") + // .Flow("implicit") + // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog") + // //.TokenUrl("https://tempuri.org/token") + // .Scopes(scopes => + // { + // scopes.Add("read", "Read access to protected resources"); + // scopes.Add("write", "Write access to protected resources"); + // }); + + // Set this flag to omit descriptions for any actions decorated with the Obsolete attribute + //c.IgnoreObsoleteActions(); + + // Each operation be assigned one or more tags which are then used by consumers for various reasons. + // For example, the swagger-ui groups operations according to the first tag of each operation. + // By default, this will be controller name but you can use the "GroupActionsBy" option to + // override with any value. + // + //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString()); + + // You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate + // the order in which operations are listed. For example, if the default grouping is in place + // (controller name) and you specify a descending alphabetic sort order, then actions from a + // ProductsController will be listed before those from a CustomersController. This is typically + // used to customize the order of groupings in the swagger-ui. + // + //c.OrderActionGroupsBy(new DescendingAlphabeticComparer()); + + // Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types + // exposed in your API. However, there may be occasions when more control of the output is needed. + // This is supported through the "MapType" and "SchemaFilter" options: + // + // Use the "MapType" option to override the Schema generation for a specific type. + // It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. + // While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. + // It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only + // use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a + // complex Schema, use a Schema filter. + // + //c.MapType(() => new Schema { type = "integer", format = "int32" }); + // + // If you want to post-modify "complex" Schemas once they've been generated, across the board or for a + // specific type, you can wire up one or more Schema filters. + // + //c.SchemaFilter(); + + // Set this flag to omit schema property descriptions for any type properties decorated with the + // Obsolete attribute + //c.IgnoreObsoleteProperties(); + + // In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique + // Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this + // works well because it prevents the "implementation detail" of type namespaces from leaking into your + // Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll + // need to opt out of this behavior to avoid Schema Id conflicts. + // + //c.UseFullTypeNameInSchemaIds(); + + // In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. + // You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given + // enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different + // approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings. + // + //c.DescribeAllEnumsAsStrings(); + + // Similar to Schema filters, Swashbuckle also supports Operation and Document filters: + // + // Post-modify Operation descriptions once they've been generated by wiring up one or more + // Operation filters. + // + //c.OperationFilter(); + // + // If you've defined an OAuth2 flow as described above, you could use a custom filter + // to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required + // to execute the operation + // + //c.OperationFilter(); + // + // Set filter to eliminate duplicate operation ids from being generated + // when there are multiple operations with the same verb in the API. + // + c.OperationFilter(); + + // Post-modify the entire Swagger document by wiring up one or more Document filters. + // This gives full control to modify the final SwaggerDocument. You should have a good understanding of + // the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // before using this option. + // + //c.DocumentFilter(); + + // If you annonate Controllers and API Types with + // Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate + // those comments into the generated docs and UI. You can enable this by providing the path to one or + // more Xml comment files. + // + //c.IncludeXmlComments(GetXmlCommentsPath()); + + // In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL + // to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions + // with the same path (sans query string) and HTTP method. You can workaround this by providing a + // custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs + // + //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); + // ***** Uncomment the following to enable the swagger UI ***** + /* + }) + .EnableSwaggerUi(c => + { + */ + // Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets. + // The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown below. + // + //c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css"); + + // Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui + // has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown above. + // + //c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js"); + + // The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false" + // strings as the possible choices. You can use this option to change these to something else, + // for example 0 and 1. + // + //c.BooleanValues(new[] { "0", "1" }); + + // Use this option to control how the Operation listing is displayed. + // It can be set to "None" (default), "List" (shows operations for each resource), + // or "Full" (fully expanded: shows operations and their details). + // + //c.DocExpansion(DocExpansion.List); + + // Use the CustomAsset option to provide your own version of assets used in the swagger-ui. + // It's typically used to instruct Swashbuckle to return your version instead of the default + // when a request is made for "index.html". As with all custom content, the file must be included + // in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to + // the method as shown below. + // + //c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html"); + + // If your API has multiple versions and you've applied the MultipleApiVersions setting + // as described above, you can also enable a select box in the swagger-ui, that displays + // a discovery URL for each version. This provides a convenient way for users to browse documentation + // for different API versions. + // + //c.EnableDiscoveryUrlSelector(); + + // If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to + // the Swagger 2.0 specification, you can enable UI support as shown below. + // + //c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI"); + }); + } + } + + internal class IncludeParameterNamesInOperationIdFilter : IOperationFilter + { + public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) + { + if(operation.parameters != null) + { + // Select the capitalized parameter names + var parameters = operation.parameters.Select( + p => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(p.name)); + + // Set the operation id to match the format "OperationByParam1AndParam2" + operation.operationId = string.Format( + "{0}By{1}", + operation.operationId, + string.Join("And", parameters)); + } + } + } +} \ No newline at end of file diff --git a/PortlandiaQuotes/App_Start/WebApiConfig.cs b/PortlandiaQuotes/App_Start/WebApiConfig.cs new file mode 100644 index 0000000..a198ea7 --- /dev/null +++ b/PortlandiaQuotes/App_Start/WebApiConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; + +namespace PortlandiaQuotes +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API configuration and services + + // Web API routes + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/PortlandiaQuotes/Controllers/ValuesController.cs b/PortlandiaQuotes/Controllers/ValuesController.cs new file mode 100644 index 0000000..23f7077 --- /dev/null +++ b/PortlandiaQuotes/Controllers/ValuesController.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http; + +namespace PortlandiaQuotes.Controllers +{ + public class ValuesController : ApiController + { + // GET api/values + public IEnumerable Get() + { + return new string[] { "value1", "value2" }; + } + + // GET api/values/5 + public string Get(int id) + { + return "value"; + } + + // POST api/values + public void Post([FromBody]string value) + { + } + + // PUT api/values/5 + public void Put(int id, [FromBody]string value) + { + } + + // DELETE api/values/5 + public void Delete(int id) + { + } + } +} diff --git a/PortlandiaQuotes/Global.asax b/PortlandiaQuotes/Global.asax new file mode 100644 index 0000000..401ae4f --- /dev/null +++ b/PortlandiaQuotes/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="PortlandiaQuotes.WebApiApplication" Language="C#" %> diff --git a/PortlandiaQuotes/Global.asax.cs b/PortlandiaQuotes/Global.asax.cs new file mode 100644 index 0000000..8b9134e --- /dev/null +++ b/PortlandiaQuotes/Global.asax.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Routing; + +namespace PortlandiaQuotes +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/PortlandiaQuotes/PortlandiaQuotes.csproj b/PortlandiaQuotes/PortlandiaQuotes.csproj new file mode 100644 index 0000000..d338bf9 --- /dev/null +++ b/PortlandiaQuotes/PortlandiaQuotes.csproj @@ -0,0 +1,147 @@ + + + + + Debug + AnyCPU + + 2.0 + {3E229DCC-2FFD-4909-BC1F-8534544E94D1} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + PortlandiaQuotes + PortlandiaQuotes + v4.5.2 + true + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Swashbuckle.Core.5.0.0\lib\net40\Swashbuckle.Core.dll + + + ..\packages\System.IdentityModel.Tokens.Jwt.4.0.0\lib\net45\System.IdentityModel.Tokens.Jwt.dll + + + + + + + + + + + + + + + + + + + + + + + + + + ..\packages\WebActivatorEx.2.0.6\lib\net40\WebActivatorEx.dll + + + ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + + + + Global.asax + + + + + + Web.config + + + Web.config + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 61749 + / + http://localhost:61749/ + False + False + + + False + + + + + + \ No newline at end of file diff --git a/PortlandiaQuotes/Project_Readme.html b/PortlandiaQuotes/Project_Readme.html new file mode 100644 index 0000000..e3f44b4 --- /dev/null +++ b/PortlandiaQuotes/Project_Readme.html @@ -0,0 +1,137 @@ + + + + + Azure API Apps + + + + + + +
+ +
+

This application consists of:

+
    +
  • NuGet packages used to create an ASP.NET Web API
  • +
  • Swagger metadata generation by Swashbuckle
  • +
  • Metadata files used by the Azure Marketplace during API App Marketplace packaging
  • +
+
+ + + + + +
+ +
+
+ + + \ No newline at end of file diff --git a/PortlandiaQuotes/Properties/AssemblyInfo.cs b/PortlandiaQuotes/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..849022e --- /dev/null +++ b/PortlandiaQuotes/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PortlandiaQuotes")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PortlandiaQuotes")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d42ae827-2501-4092-aee0-fd28d38d261f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PortlandiaQuotes/Web.Debug.config b/PortlandiaQuotes/Web.Debug.config new file mode 100644 index 0000000..f7c5612 --- /dev/null +++ b/PortlandiaQuotes/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/PortlandiaQuotes/Web.Release.config b/PortlandiaQuotes/Web.Release.config new file mode 100644 index 0000000..52c6bbe --- /dev/null +++ b/PortlandiaQuotes/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/PortlandiaQuotes/Web.config b/PortlandiaQuotes/Web.config new file mode 100644 index 0000000..9b973f7 --- /dev/null +++ b/PortlandiaQuotes/Web.config @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PortlandiaQuotes/packages.config b/PortlandiaQuotes/packages.config new file mode 100644 index 0000000..0cc51ec --- /dev/null +++ b/PortlandiaQuotes/packages.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file