diff --git a/ApiVersioning.sln b/ApiVersioning.sln
index 393bcbf9..b9a903ef 100644
--- a/ApiVersioning.sln
+++ b/ApiVersioning.sln
@@ -28,12 +28,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{2957BAF3-9
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{915BB224-B1D0-4E27-A348-67FCC77AAA44}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webapi", "webapi", "{F446ED94-368F-4F67-913B-16E82CA80DFC}"
ProjectSection(SolutionItems) = preProject
- samples\webapi\directory.build.targets = samples\webapi\directory.build.targets
+ samples\directory.build.props = samples\directory.build.props
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webapi", "webapi", "{F446ED94-368F-4F67-913B-16E82CA80DFC}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspnetcore", "aspnetcore", "{900DD210-8500-4D89-A05D-C9526935A719}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicSample", "samples\aspnetcore\BasicSample\BasicSample.csproj", "{59389B47-8280-411E-B840-D097AA1DCDEE}"
diff --git a/build/code-analysis.props b/build/code-analysis.props
index c1e73db8..a50752bb 100644
--- a/build/code-analysis.props
+++ b/build/code-analysis.props
@@ -17,7 +17,7 @@
-
+
\ No newline at end of file
diff --git a/samples/aspnetcore/BasicSample/BasicSample.csproj b/samples/aspnetcore/BasicSample/BasicSample.csproj
index 0f0062bb..4ae09dda 100644
--- a/samples/aspnetcore/BasicSample/BasicSample.csproj
+++ b/samples/aspnetcore/BasicSample/BasicSample.csproj
@@ -1,25 +1,18 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
+ Microsoft.Examples
-
- PreserveNewest
-
+
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/aspnetcore/BasicSample/Controllers/HelloWorldController.cs b/samples/aspnetcore/BasicSample/Controllers/HelloWorldController.cs
index cb760e65..18ef0a81 100644
--- a/samples/aspnetcore/BasicSample/Controllers/HelloWorldController.cs
+++ b/samples/aspnetcore/BasicSample/Controllers/HelloWorldController.cs
@@ -1,17 +1,12 @@
namespace Microsoft.Examples.Controllers
{
- using AspNetCore.Mvc.Routing;
using AspNetCore.Routing;
- using Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[ApiVersion( "1.0" )]
[Route( "api/v{version:apiVersion}/[controller]" )]
- public class HelloWorldController : Controller
+ public class HelloWorldController : ControllerBase
{
// GET api/v{version}/helloworld
[HttpGet]
diff --git a/samples/aspnetcore/BasicSample/Controllers/Values2Controller.cs b/samples/aspnetcore/BasicSample/Controllers/Values2Controller.cs
index d28dfc02..ff430ab3 100644
--- a/samples/aspnetcore/BasicSample/Controllers/Values2Controller.cs
+++ b/samples/aspnetcore/BasicSample/Controllers/Values2Controller.cs
@@ -1,17 +1,14 @@
namespace Microsoft.Examples.Controllers
{
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[ApiVersion( "2.0" )]
[Route( "api/values" )]
- public class Values2Controller : Controller
+ public class Values2Controller : ControllerBase
{
// GET api/values?api-version=2.0
[HttpGet]
- public string Get() => $"Controller = {GetType().Name}\nVersion = {HttpContext.GetRequestedApiVersion()}";
+ public string Get( ApiVersion apiVersion ) => $"Controller = {GetType().Name}\nVersion = {apiVersion}";
}
-}
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/BasicSample/Controllers/ValuesController.cs b/samples/aspnetcore/BasicSample/Controllers/ValuesController.cs
index ef7f5472..7115910a 100644
--- a/samples/aspnetcore/BasicSample/Controllers/ValuesController.cs
+++ b/samples/aspnetcore/BasicSample/Controllers/ValuesController.cs
@@ -1,14 +1,11 @@
namespace Microsoft.Examples.Controllers
{
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[ApiVersion( "1.0" )]
[Route( "api/[controller]" )]
- public class ValuesController : Controller
+ public class ValuesController : ControllerBase
{
// GET api/values?api-version=1.0
[HttpGet]
diff --git a/samples/aspnetcore/BasicSample/Program.cs b/samples/aspnetcore/BasicSample/Program.cs
index 915cc391..3ef6eb9c 100644
--- a/samples/aspnetcore/BasicSample/Program.cs
+++ b/samples/aspnetcore/BasicSample/Program.cs
@@ -1,25 +1,16 @@
namespace Microsoft.Examples
{
+ using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
- public class Program
+ public static class Program
{
- public static void Main(string[] args)
- {
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseContentRoot(Directory.GetCurrentDirectory())
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
- host.Run();
- }
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
+ WebHost.CreateDefaultBuilder( args )
+ .UseStartup();
}
-}
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/BasicSample/Startup.cs b/samples/aspnetcore/BasicSample/Startup.cs
index 35c2bfbf..aa6567ee 100644
--- a/samples/aspnetcore/BasicSample/Startup.cs
+++ b/samples/aspnetcore/BasicSample/Startup.cs
@@ -4,41 +4,34 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-
- using Microsoft.AspNetCore.Mvc.Routing;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
public class Startup
{
- public Startup( IHostingEnvironment env )
+ public Startup( IConfiguration configuration )
{
- var builder = new ConfigurationBuilder()
- .SetBasePath( env.ContentRootPath )
- .AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true )
- .AddJsonFile( $"appsettings.{env.EnvironmentName}.json", optional: true )
- .AddEnvironmentVariables();
- Configuration = builder.Build();
+ Configuration = configuration;
}
- public IConfigurationRoot Configuration { get; }
+ public IConfiguration Configuration { get; }
+ // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices( IServiceCollection services )
{
- services.AddMvc();
-
- // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- services.AddApiVersioning( o => o.ReportApiVersions = true );
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, if you need legacy style routing via IRouter, change it to false
+ services.AddMvc( options => options.EnableEndpointRouting = true ).SetCompatibilityVersion( Latest );
+ services.AddApiVersioning(
+ options =>
+ {
+ // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
+ options.ReportApiVersions = true;
+ } );
}
- public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory )
+ public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
- loggerFactory.AddConsole( Configuration.GetSection( "Logging" ) );
- loggerFactory.AddDebug();
app.UseMvc();
}
}
-}
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/BasicSample/appsettings.json b/samples/aspnetcore/BasicSample/appsettings.json
index fa8ce71a..d713e815 100644
--- a/samples/aspnetcore/BasicSample/appsettings.json
+++ b/samples/aspnetcore/BasicSample/appsettings.json
@@ -1,10 +1,8 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Warning"
}
- }
-}
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/ByNamespaceSample/ByNamespaceSample.csproj b/samples/aspnetcore/ByNamespaceSample/ByNamespaceSample.csproj
index 0f0062bb..4ae09dda 100644
--- a/samples/aspnetcore/ByNamespaceSample/ByNamespaceSample.csproj
+++ b/samples/aspnetcore/ByNamespaceSample/ByNamespaceSample.csproj
@@ -1,25 +1,18 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
+ Microsoft.Examples
-
- PreserveNewest
-
+
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/aspnetcore/ByNamespaceSample/Program.cs b/samples/aspnetcore/ByNamespaceSample/Program.cs
index ce02b86a..3ef6eb9c 100644
--- a/samples/aspnetcore/ByNamespaceSample/Program.cs
+++ b/samples/aspnetcore/ByNamespaceSample/Program.cs
@@ -1,24 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Hosting;
-
-namespace Microsoft.Examples
+namespace Microsoft.Examples
{
- public class Program
+ using Microsoft.AspNetCore;
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Hosting;
+
+ public static class Program
{
- public static void Main( string[] args )
- {
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseContentRoot( Directory.GetCurrentDirectory() )
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
- host.Run();
- }
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
+ WebHost.CreateDefaultBuilder( args )
+ .UseStartup();
}
}
\ No newline at end of file
diff --git a/samples/aspnetcore/ByNamespaceSample/Startup.cs b/samples/aspnetcore/ByNamespaceSample/Startup.cs
index bf99dedb..26a9a9f6 100644
--- a/samples/aspnetcore/ByNamespaceSample/Startup.cs
+++ b/samples/aspnetcore/ByNamespaceSample/Startup.cs
@@ -1,18 +1,27 @@
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Mvc.Versioning.Conventions;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-
-namespace Microsoft.Examples
+namespace Microsoft.Examples
{
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Mvc.Versioning.Conventions;
+ using Microsoft.Extensions.Configuration;
+ using Microsoft.Extensions.DependencyInjection;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
+
public class Startup
{
+ public Startup( IConfiguration configuration )
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
// This method gets called by the runtime. Use this method to add services to the container.
- // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices( IServiceCollection services )
{
- services.AddMvc();
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, if you need legacy style routing via IRouter, change it to false
+ services.AddMvc( options => options.EnableEndpointRouting = true ).SetCompatibilityVersion( Latest );
services.AddApiVersioning(
options =>
{
@@ -25,15 +34,8 @@ public void ConfigureServices( IServiceCollection services )
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory )
+ public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
- loggerFactory.AddConsole();
-
- if ( env.IsDevelopment() )
- {
- app.UseDeveloperExceptionPage();
- }
-
app.UseMvc();
}
}
diff --git a/samples/aspnetcore/ByNamespaceSample/V1/Controllers/AgreementsController.cs b/samples/aspnetcore/ByNamespaceSample/V1/Controllers/AgreementsController.cs
index f18b4cf3..b6b6dec8 100644
--- a/samples/aspnetcore/ByNamespaceSample/V1/Controllers/AgreementsController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V1/Controllers/AgreementsController.cs
@@ -3,9 +3,10 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class AgreementsController : Controller
+ public class AgreementsController : ControllerBase
{
// GET ~/v1/agreements/{accountId}
// GET ~/agreements/{accountId}?api-version=1.0
diff --git a/samples/aspnetcore/ByNamespaceSample/V1/Controllers/OrdersController.cs b/samples/aspnetcore/ByNamespaceSample/V1/Controllers/OrdersController.cs
index a918e3de..15581485 100644
--- a/samples/aspnetcore/ByNamespaceSample/V1/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V1/Controllers/OrdersController.cs
@@ -3,9 +3,10 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
// GET ~/v1/orders/{accountId}
// GET ~/orders/{accountId}?api-version=1.0
diff --git a/samples/aspnetcore/ByNamespaceSample/V2/Controllers/AgreementsController.cs b/samples/aspnetcore/ByNamespaceSample/V2/Controllers/AgreementsController.cs
index daedce1f..bc53c767 100644
--- a/samples/aspnetcore/ByNamespaceSample/V2/Controllers/AgreementsController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V2/Controllers/AgreementsController.cs
@@ -3,9 +3,10 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class AgreementsController : Controller
+ public class AgreementsController : ControllerBase
{
// GET ~/v2/agreements/{accountId}
// GET ~/agreements/{accountId}?api-version=2.0
diff --git a/samples/aspnetcore/ByNamespaceSample/V2/Controllers/OrdersController.cs b/samples/aspnetcore/ByNamespaceSample/V2/Controllers/OrdersController.cs
index d8cd6e48..05d7da3b 100644
--- a/samples/aspnetcore/ByNamespaceSample/V2/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V2/Controllers/OrdersController.cs
@@ -3,9 +3,10 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
// GET ~/v2/orders/{accountId}
// GET ~/orders/{accountId}?api-version=2.0
diff --git a/samples/aspnetcore/ByNamespaceSample/V3/Controllers/AgreementsController.cs b/samples/aspnetcore/ByNamespaceSample/V3/Controllers/AgreementsController.cs
index 7eca09c2..5aceb53f 100644
--- a/samples/aspnetcore/ByNamespaceSample/V3/Controllers/AgreementsController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V3/Controllers/AgreementsController.cs
@@ -3,9 +3,10 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class AgreementsController : Controller
+ public class AgreementsController : ControllerBase
{
// GET ~/v3/agreements/{accountId}
// GET ~/agreements/{accountId}?api-version=3.0
diff --git a/samples/aspnetcore/ByNamespaceSample/V3/Controllers/OrdersController.cs b/samples/aspnetcore/ByNamespaceSample/V3/Controllers/OrdersController.cs
index 17a33e8b..a1460d4d 100644
--- a/samples/aspnetcore/ByNamespaceSample/V3/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/ByNamespaceSample/V3/Controllers/OrdersController.cs
@@ -3,13 +3,14 @@
using Microsoft.AspNetCore.Mvc;
using Models;
+ [ApiController]
[Route( "[controller]" )]
[Route( "v{version:apiVersion}/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
// GET ~/v3/orders/{accountId}
// GET ~/orders/{accountId}?api-version=3.0
[HttpGet( "{accountId}" )]
public IActionResult Get( string accountId, ApiVersion apiVersion ) => Ok( new Order( GetType().FullName, accountId, apiVersion.ToString() ) );
}
-}
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/ByNamespaceSample/appsettings.json b/samples/aspnetcore/ByNamespaceSample/appsettings.json
index fa8ce71a..d713e815 100644
--- a/samples/aspnetcore/ByNamespaceSample/appsettings.json
+++ b/samples/aspnetcore/ByNamespaceSample/appsettings.json
@@ -1,10 +1,8 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Warning"
}
- }
-}
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/ConventionsSample/Controllers/HelloWorldController.cs b/samples/aspnetcore/ConventionsSample/Controllers/HelloWorldController.cs
index 8bd298c9..b6719178 100644
--- a/samples/aspnetcore/ConventionsSample/Controllers/HelloWorldController.cs
+++ b/samples/aspnetcore/ConventionsSample/Controllers/HelloWorldController.cs
@@ -1,13 +1,10 @@
namespace Microsoft.Examples.Controllers
{
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[Route( "api/v{version:apiVersion}/[controller]" )]
- public class HelloWorldController : Controller
+ public class HelloWorldController : ControllerBase
{
// GET api/v{version}/helloworld
[HttpGet]
diff --git a/samples/aspnetcore/ConventionsSample/Controllers/Values2Controller.cs b/samples/aspnetcore/ConventionsSample/Controllers/Values2Controller.cs
index 7cb2d6fa..03774d76 100644
--- a/samples/aspnetcore/ConventionsSample/Controllers/Values2Controller.cs
+++ b/samples/aspnetcore/ConventionsSample/Controllers/Values2Controller.cs
@@ -1,28 +1,25 @@
namespace Microsoft.Examples.Controllers
{
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[Route( "api/values" )]
- public class Values2Controller : Controller
+ public class Values2Controller : ControllerBase
{
// GET api/values?api-version=2.0
[HttpGet]
- public string Get() => $"Controller = {GetType().Name}\nVersion = {HttpContext.GetRequestedApiVersion()}";
+ public string Get( ApiVersion apiVersion ) => $"Controller = {GetType().Name}\nVersion = {apiVersion}";
// GET api/values/{id}?api-version=2.0
[HttpGet( "{id:int}" )]
- public string Get( int id ) => $"Controller = {GetType().Name}\nId = {id}\nVersion = {HttpContext.GetRequestedApiVersion()}";
+ public string Get( int id, ApiVersion apiVersion ) => $"Controller = {GetType().Name}\nId = {id}\nVersion = {apiVersion}";
// GET api/values?api-version=3.0
[HttpGet]
- public string GetV3() => $"Controller = {GetType().Name}\nVersion = {HttpContext.GetRequestedApiVersion()}";
+ public string GetV3( ApiVersion apiVersion ) => $"Controller = {GetType().Name}\nVersion = {apiVersion}";
// GET api/values/{id}?api-version=3.0
[HttpGet( "{id:int}" )]
- public string GetV3( int id ) => $"Controller = {GetType().Name}\nId = {id}\nVersion = {HttpContext.GetRequestedApiVersion()}";
+ public string GetV3( int id, ApiVersion apiVersion ) => $"Controller = {GetType().Name}\nId = {id}\nVersion = {apiVersion}";
}
}
\ No newline at end of file
diff --git a/samples/aspnetcore/ConventionsSample/Controllers/ValuesController.cs b/samples/aspnetcore/ConventionsSample/Controllers/ValuesController.cs
index c80463ed..3f631b96 100644
--- a/samples/aspnetcore/ConventionsSample/Controllers/ValuesController.cs
+++ b/samples/aspnetcore/ConventionsSample/Controllers/ValuesController.cs
@@ -1,13 +1,10 @@
namespace Microsoft.Examples.Controllers
{
using Microsoft.AspNetCore.Mvc;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ [ApiController]
[Route( "api/[controller]" )]
- public class ValuesController : Controller
+ public class ValuesController : ControllerBase
{
// GET api/values?api-version=1.0
[HttpGet]
diff --git a/samples/aspnetcore/ConventionsSample/ConventionsSample.csproj b/samples/aspnetcore/ConventionsSample/ConventionsSample.csproj
index 0f0062bb..458c8aa3 100644
--- a/samples/aspnetcore/ConventionsSample/ConventionsSample.csproj
+++ b/samples/aspnetcore/ConventionsSample/ConventionsSample.csproj
@@ -1,25 +1,18 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
+ Microsoft.Examples
-
- PreserveNewest
-
+
+
-
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/aspnetcore/ConventionsSample/Program.cs b/samples/aspnetcore/ConventionsSample/Program.cs
index 06c6a4ae..3ef6eb9c 100644
--- a/samples/aspnetcore/ConventionsSample/Program.cs
+++ b/samples/aspnetcore/ConventionsSample/Program.cs
@@ -1,25 +1,16 @@
namespace Microsoft.Examples
{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Hosting;
- public class Program
+ public static class Program
{
- public static void Main(string[] args)
- {
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseContentRoot(Directory.GetCurrentDirectory())
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
- host.Run();
- }
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
+ WebHost.CreateDefaultBuilder( args )
+ .UseStartup();
}
}
\ No newline at end of file
diff --git a/samples/aspnetcore/ConventionsSample/Startup.cs b/samples/aspnetcore/ConventionsSample/Startup.cs
index 7c1871b7..f09315eb 100644
--- a/samples/aspnetcore/ConventionsSample/Startup.cs
+++ b/samples/aspnetcore/ConventionsSample/Startup.cs
@@ -3,45 +3,41 @@
using Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Versioning.Conventions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
public class Startup
{
- public Startup( IHostingEnvironment env )
+ public Startup( IConfiguration configuration )
{
- var builder = new ConfigurationBuilder()
- .SetBasePath( env.ContentRootPath )
- .AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true )
- .AddJsonFile( $"appsettings.{env.EnvironmentName}.json", optional: true )
- .AddEnvironmentVariables();
- Configuration = builder.Build();
+ Configuration = configuration;
}
- public IConfigurationRoot Configuration { get; }
+ public IConfiguration Configuration { get; }
+ // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices( IServiceCollection services )
{
- services.AddMvc();
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, if you need legacy style routing via IRouter, change it to false
+ services.AddMvc( options => options.EnableEndpointRouting = true ).SetCompatibilityVersion( Latest );
services.AddApiVersioning(
options =>
{
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
options.ReportApiVersions = true;
- // apply api versions using conventions rather than attributes
options.Conventions.Controller().HasApiVersion( 1, 0 );
+
options.Conventions.Controller()
.HasApiVersion( 2, 0 )
.HasApiVersion( 3, 0 )
- .Action( c => c.GetV3() ).MapToApiVersion( 3, 0 )
- .Action( c => c.GetV3( default( int ) ) ).MapToApiVersion( 3, 0 );
+ .Action( c => c.GetV3( default ) ).MapToApiVersion( 3, 0 )
+ .Action( c => c.GetV3( default, default ) ).MapToApiVersion( 3, 0 );
+
options.Conventions.Controller()
.HasApiVersion( 1, 0 )
.HasApiVersion( 2, 0 )
@@ -49,10 +45,9 @@ public void ConfigureServices( IServiceCollection services )
} );
}
- public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory )
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
- loggerFactory.AddConsole( Configuration.GetSection( "Logging" ) );
- loggerFactory.AddDebug();
app.UseMvc();
}
}
diff --git a/samples/aspnetcore/ConventionsSample/appsettings.json b/samples/aspnetcore/ConventionsSample/appsettings.json
index fa8ce71a..d713e815 100644
--- a/samples/aspnetcore/ConventionsSample/appsettings.json
+++ b/samples/aspnetcore/ConventionsSample/appsettings.json
@@ -1,10 +1,8 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Warning"
}
- }
-}
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/ODataBasicSample/ODataBasicSample.csproj b/samples/aspnetcore/ODataBasicSample/ODataBasicSample.csproj
index b7f3c012..269a2a67 100644
--- a/samples/aspnetcore/ODataBasicSample/ODataBasicSample.csproj
+++ b/samples/aspnetcore/ODataBasicSample/ODataBasicSample.csproj
@@ -1,25 +1,18 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
+ Microsoft.Examples
-
- PreserveNewest
-
+
+
-
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/aspnetcore/ODataBasicSample/Program.cs b/samples/aspnetcore/ODataBasicSample/Program.cs
index 915cc391..3ef6eb9c 100644
--- a/samples/aspnetcore/ODataBasicSample/Program.cs
+++ b/samples/aspnetcore/ODataBasicSample/Program.cs
@@ -1,25 +1,16 @@
namespace Microsoft.Examples
{
+ using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
- public class Program
+ public static class Program
{
- public static void Main(string[] args)
- {
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseContentRoot(Directory.GetCurrentDirectory())
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
- host.Run();
- }
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
+ WebHost.CreateDefaultBuilder( args )
+ .UseStartup();
}
-}
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/ODataBasicSample/Startup.cs b/samples/aspnetcore/ODataBasicSample/Startup.cs
index 1daf56e0..af1d6744 100644
--- a/samples/aspnetcore/ODataBasicSample/Startup.cs
+++ b/samples/aspnetcore/ODataBasicSample/Startup.cs
@@ -6,35 +6,35 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
public class Startup
{
- public Startup( IHostingEnvironment env )
+ public Startup( IConfiguration configuration )
{
- var builder = new ConfigurationBuilder()
- .SetBasePath( env.ContentRootPath )
- .AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true )
- .AddJsonFile( $"appsettings.{env.EnvironmentName}.json", optional: true )
- .AddEnvironmentVariables();
- Configuration = builder.Build();
+ Configuration = configuration;
}
- public IConfigurationRoot Configuration { get; }
+ public IConfiguration Configuration { get; }
+ // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices( IServiceCollection services )
{
- services.AddMvc();
-
- // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- services.AddApiVersioning( options => options.ReportApiVersions = true );
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, it is unsupported by OData and MUST be false
+ services.AddMvc( options => options.EnableEndpointRouting = false ).SetCompatibilityVersion( Latest );
+ services.AddApiVersioning(
+ options =>
+ {
+ // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
+ options.ReportApiVersions = true;
+ } );
services.AddOData().EnableApiVersioning();
}
- public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, VersionedODataModelBuilder modelBuilder )
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure( IApplicationBuilder app, IHostingEnvironment env, VersionedODataModelBuilder modelBuilder )
{
- loggerFactory.AddConsole( Configuration.GetSection( "Logging" ) );
- loggerFactory.AddDebug();
app.UseMvc(
routeBuilder =>
{
diff --git a/samples/aspnetcore/ODataBasicSample/appsettings.json b/samples/aspnetcore/ODataBasicSample/appsettings.json
index fa8ce71a..d713e815 100644
--- a/samples/aspnetcore/ODataBasicSample/appsettings.json
+++ b/samples/aspnetcore/ODataBasicSample/appsettings.json
@@ -1,10 +1,8 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Warning"
}
- }
-}
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/SwaggerODataSample/Program.cs b/samples/aspnetcore/SwaggerODataSample/Program.cs
index db17b9b5..9012829f 100644
--- a/samples/aspnetcore/SwaggerODataSample/Program.cs
+++ b/samples/aspnetcore/SwaggerODataSample/Program.cs
@@ -6,22 +6,22 @@
///
/// Represents the current application.
///
- public class Program
+ public static class Program
{
///
/// The main entry point to the application.
///
/// The arguments provides at start-up, if any.
- public static void Main( string[] args ) => BuildWebHost( args ).Run();
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
///
/// Builds a new web host for the application.
///
/// The command-line arguments, if any.
- /// A newly constructed web host.
- public static IWebHost BuildWebHost( string[] args ) =>
+ /// A new web host builder.
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
WebHost.CreateDefaultBuilder( args )
- .UseStartup()
- .Build();
+ .UseStartup();
}
}
\ No newline at end of file
diff --git a/samples/aspnetcore/SwaggerODataSample/Startup.cs b/samples/aspnetcore/SwaggerODataSample/Startup.cs
index 94a566bc..2d25f399 100644
--- a/samples/aspnetcore/SwaggerODataSample/Startup.cs
+++ b/samples/aspnetcore/SwaggerODataSample/Startup.cs
@@ -13,6 +13,7 @@
using System.IO;
using System.Reflection;
using static Microsoft.AspNet.OData.Query.AllowedQueryOptions;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
///
/// Represents the startup process for the application.
@@ -25,7 +26,9 @@ public class Startup
/// The collection of services to configure the application with.
public void ConfigureServices( IServiceCollection services )
{
- services.AddMvc();
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, it is unsupported by OData and MUST be false
+ services.AddMvc( options => options.EnableEndpointRouting = false ).SetCompatibilityVersion( Latest );
services.AddApiVersioning( options => options.ReportApiVersions = true );
services.AddOData().EnableApiVersioning();
services.AddODataApiExplorer(
@@ -41,10 +44,10 @@ public void ConfigureServices( IServiceCollection services )
// configure query options (which cannot otherwise be configured by OData conventions)
options.QueryOptions.Controller()
- .Action( c => c.Get( default( ODataQueryOptions ) ) ).Allow( Skip | Count ).AllowTop( 100 );
+ .Action( c => c.Get( default ) ).Allow( Skip | Count ).AllowTop( 100 );
options.QueryOptions.Controller()
- .Action( c => c.Get( default( ODataQueryOptions ) ) ).Allow( Skip | Count ).AllowTop( 100 );
+ .Action( c => c.Get( default ) ).Allow( Skip | Count ).AllowTop( 100 );
} );
services.AddSwaggerGen(
options =>
@@ -107,7 +110,7 @@ static Info CreateInfoForApiVersion( ApiVersionDescription description )
{
var info = new Info()
{
- Title = $"Sample API {description.ApiVersion}",
+ Title = "Sample API",
Version = description.ApiVersion.ToString(),
Description = "A sample application with Swagger, Swashbuckle, and API versioning.",
Contact = new Contact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
diff --git a/samples/aspnetcore/SwaggerODataSample/SwaggerDefaultValues.cs b/samples/aspnetcore/SwaggerODataSample/SwaggerDefaultValues.cs
index 65ff33f7..fc3e8e04 100644
--- a/samples/aspnetcore/SwaggerODataSample/SwaggerDefaultValues.cs
+++ b/samples/aspnetcore/SwaggerODataSample/SwaggerDefaultValues.cs
@@ -28,24 +28,18 @@ public void Apply( Operation operation, OperationFilterContext context )
foreach ( var parameter in operation.Parameters.OfType() )
{
var description = context.ApiDescription.ParameterDescriptions.First( p => p.Name == parameter.Name );
- var routeInfo = description.RouteInfo;
if ( parameter.Description == null )
{
parameter.Description = description.ModelMetadata?.Description;
}
- if ( routeInfo == null )
- {
- continue;
- }
-
if ( parameter.Default == null )
{
- parameter.Default = routeInfo.DefaultValue;
+ parameter.Default = description.DefaultValue;
}
- parameter.Required |= !routeInfo.IsOptional;
+ parameter.Required |= description.IsRequired;
}
}
}
diff --git a/samples/aspnetcore/SwaggerODataSample/SwaggerODataSample.csproj b/samples/aspnetcore/SwaggerODataSample/SwaggerODataSample.csproj
index ca929c95..eed4cc1d 100644
--- a/samples/aspnetcore/SwaggerODataSample/SwaggerODataSample.csproj
+++ b/samples/aspnetcore/SwaggerODataSample/SwaggerODataSample.csproj
@@ -1,23 +1,21 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
Microsoft.Examples
bin\$(Configuration)\$(TargetFramework)\$(MSBuildThisFileName).xml
-
-
+
+
+
+
-
+
-
-
-
-
-
-
+
-
+
diff --git a/samples/aspnetcore/SwaggerODataSample/V2/PeopleController.cs b/samples/aspnetcore/SwaggerODataSample/V2/PeopleController.cs
index 10929dc9..f1ed2974 100644
--- a/samples/aspnetcore/SwaggerODataSample/V2/PeopleController.cs
+++ b/samples/aspnetcore/SwaggerODataSample/V2/PeopleController.cs
@@ -3,8 +3,8 @@
using Microsoft.AspNet.OData;
using Microsoft.AspNet.OData.Query;
using Microsoft.AspNetCore.Mvc;
- using Microsoft.Data.OData;
using Microsoft.Examples.Models;
+ using Microsoft.OData;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/samples/aspnetcore/SwaggerODataSample/V3/PeopleController.cs b/samples/aspnetcore/SwaggerODataSample/V3/PeopleController.cs
index 5531ae12..c77c7782 100644
--- a/samples/aspnetcore/SwaggerODataSample/V3/PeopleController.cs
+++ b/samples/aspnetcore/SwaggerODataSample/V3/PeopleController.cs
@@ -3,7 +3,7 @@
using Microsoft.AspNet.OData;
using Microsoft.AspNet.OData.Query;
using Microsoft.AspNetCore.Mvc;
- using Microsoft.Data.OData;
+ using Microsoft.OData;
using Microsoft.Examples.Models;
using System;
using System.Collections.Generic;
diff --git a/samples/aspnetcore/SwaggerODataSample/appsettings.json b/samples/aspnetcore/SwaggerODataSample/appsettings.json
new file mode 100644
index 00000000..d713e815
--- /dev/null
+++ b/samples/aspnetcore/SwaggerODataSample/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/aspnetcore/SwaggerSample/Program.cs b/samples/aspnetcore/SwaggerSample/Program.cs
index d3f7ab74..fd733cbd 100644
--- a/samples/aspnetcore/SwaggerSample/Program.cs
+++ b/samples/aspnetcore/SwaggerSample/Program.cs
@@ -1,28 +1,27 @@
namespace Microsoft.Examples
{
- using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
- using System.IO;
///
/// Represents the current application.
///
- public class Program
+ public static class Program
{
///
/// The main entry point to the application.
///
- /// The arguments provides at start-up, if any.
- public static void Main( string[] args )
- {
- var host = new WebHostBuilder()
- .UseKestrel()
- .UseContentRoot( Directory.GetCurrentDirectory() )
- .UseIISIntegration()
- .UseStartup()
- .Build();
+ /// The arguments provided at start-up, if any.
+ public static void Main( string[] args ) =>
+ CreateWebHostBuilder( args ).Build().Run();
- host.Run();
- }
+ ///
+ /// Builds a new web host for the application.
+ ///
+ /// The command-line arguments, if any.
+ /// A new web host builder.
+ public static IWebHostBuilder CreateWebHostBuilder( string[] args ) =>
+ WebHost.CreateDefaultBuilder( args )
+ .UseStartup();
}
}
\ No newline at end of file
diff --git a/samples/aspnetcore/SwaggerSample/Startup.cs b/samples/aspnetcore/SwaggerSample/Startup.cs
index 78b7cb87..fbf784aa 100644
--- a/samples/aspnetcore/SwaggerSample/Startup.cs
+++ b/samples/aspnetcore/SwaggerSample/Startup.cs
@@ -5,11 +5,11 @@
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
using Microsoft.Extensions.PlatformAbstractions;
using Swashbuckle.AspNetCore.Swagger;
using System.IO;
using System.Reflection;
+ using static Microsoft.AspNetCore.Mvc.CompatibilityVersion;
///
/// Represents the startup process for the application.
@@ -19,23 +19,17 @@ public class Startup
///
/// Initializes a new instance of the class.
///
- /// The current hosting environment.
- public Startup( IHostingEnvironment env )
+ /// The current configuration.
+ public Startup( IConfiguration configuration )
{
- var builder = new ConfigurationBuilder()
- .SetBasePath( env.ContentRootPath )
- .AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true )
- .AddJsonFile( $"appsettings.{env.EnvironmentName}.json", optional: true )
- .AddEnvironmentVariables();
-
- Configuration = builder.Build();
+ Configuration = configuration;
}
///
/// Gets the current configuration.
///
/// The current application configuration.
- public IConfigurationRoot Configuration { get; }
+ public IConfiguration Configuration { get; }
///
/// Configures services for the application.
@@ -43,20 +37,26 @@ public Startup( IHostingEnvironment env )
/// The collection of services to configure the application with.
public void ConfigureServices( IServiceCollection services )
{
- // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
- // note: the specified format code will format the version as "'v'major[.minor][-status]"
+ // the sample application always uses the latest version, but you may want an explict version such as Version_2_2
+ // note: Endpoint Routing is enabled by default; however, if you need legacy style routing via IRouter, change it to false
+ services.AddMvc( options => options.EnableEndpointRouting = true ).SetCompatibilityVersion( Latest );
+ services.AddApiVersioning(
+ options =>
+ {
+ // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
+ options.ReportApiVersions = true;
+ } );
services.AddVersionedApiExplorer(
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";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
} );
-
- services.AddMvc();
- services.AddApiVersioning( options => options.ReportApiVersions = true );
services.AddSwaggerGen(
options =>
{
@@ -83,17 +83,13 @@ public void ConfigureServices( IServiceCollection services )
}
///
- /// Configures the application using the provided builder, hosting environment, and logging factory.
+ /// Configures the application using the provided builder, hosting environment, and API version description provider.
///
/// The current application builder.
/// The current hosting environment.
- /// The logging factory used for instrumentation.
/// The API version descriptor provider used to enumerate defined API versions.
- public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApiVersionDescriptionProvider provider )
+ public void Configure( IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider )
{
- loggerFactory.AddConsole( Configuration.GetSection( "Logging" ) );
- loggerFactory.AddDebug();
-
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(
@@ -121,7 +117,7 @@ static Info CreateInfoForApiVersion( ApiVersionDescription description )
{
var info = new Info()
{
- Title = $"Sample API {description.ApiVersion}",
+ Title = "Sample API",
Version = description.ApiVersion.ToString(),
Description = "A sample application with Swagger, Swashbuckle, and API versioning.",
Contact = new Contact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
diff --git a/samples/aspnetcore/SwaggerSample/SwaggerDefaultValues.cs b/samples/aspnetcore/SwaggerSample/SwaggerDefaultValues.cs
index 65ff33f7..fc3e8e04 100644
--- a/samples/aspnetcore/SwaggerSample/SwaggerDefaultValues.cs
+++ b/samples/aspnetcore/SwaggerSample/SwaggerDefaultValues.cs
@@ -28,24 +28,18 @@ public void Apply( Operation operation, OperationFilterContext context )
foreach ( var parameter in operation.Parameters.OfType() )
{
var description = context.ApiDescription.ParameterDescriptions.First( p => p.Name == parameter.Name );
- var routeInfo = description.RouteInfo;
if ( parameter.Description == null )
{
parameter.Description = description.ModelMetadata?.Description;
}
- if ( routeInfo == null )
- {
- continue;
- }
-
if ( parameter.Default == null )
{
- parameter.Default = routeInfo.DefaultValue;
+ parameter.Default = description.DefaultValue;
}
- parameter.Required |= !routeInfo.IsOptional;
+ parameter.Required |= description.IsRequired;
}
}
}
diff --git a/samples/aspnetcore/SwaggerSample/SwaggerSample.csproj b/samples/aspnetcore/SwaggerSample/SwaggerSample.csproj
index 4a603647..57313d98 100644
--- a/samples/aspnetcore/SwaggerSample/SwaggerSample.csproj
+++ b/samples/aspnetcore/SwaggerSample/SwaggerSample.csproj
@@ -1,29 +1,21 @@
- netcoreapp2.0
+ netcoreapp2.2
+ InProcess
Microsoft.Examples
bin\$(Configuration)\$(TargetFramework)\$(MSBuildThisFileName).xml
-
- PreserveNewest
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/aspnetcore/SwaggerSample/V1/Controllers/OrdersController.cs b/samples/aspnetcore/SwaggerSample/V1/Controllers/OrdersController.cs
index e2c6d70d..67f3a466 100644
--- a/samples/aspnetcore/SwaggerSample/V1/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/SwaggerSample/V1/Controllers/OrdersController.cs
@@ -6,10 +6,11 @@
///
/// Represents a RESTful service of orders.
///
+ [ApiController]
[ApiVersion( "1.0" )]
[ApiVersion( "0.9", Deprecated = true )]
[Route( "api/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
///
/// Gets a single order.
@@ -19,6 +20,7 @@ public class OrdersController : Controller
/// The order was successfully retrieved.
/// The order does not exist.
[HttpGet( "{id:int}", Name = "GetOrderById" )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 200 )]
[ProducesResponseType( 404 )]
public IActionResult Get( int id ) => Ok( new Order() { Id = id, Customer = "John Doe" } );
@@ -32,6 +34,7 @@ public class OrdersController : Controller
/// The order is invalid.
[HttpPost]
[MapToApiVersion( "1.0" )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 201 )]
[ProducesResponseType( 400 )]
public IActionResult Post( [FromBody] Order order )
diff --git a/samples/aspnetcore/SwaggerSample/V1/Controllers/PeopleController.cs b/samples/aspnetcore/SwaggerSample/V1/Controllers/PeopleController.cs
index 4fd48a17..0a20474b 100644
--- a/samples/aspnetcore/SwaggerSample/V1/Controllers/PeopleController.cs
+++ b/samples/aspnetcore/SwaggerSample/V1/Controllers/PeopleController.cs
@@ -7,10 +7,11 @@
///
/// Represents a RESTful people service.
///
+ [ApiController]
[ApiVersion( "1.0" )]
[ApiVersion( "0.9", Deprecated = true )]
[Route( "api/v{api-version:apiVersion}/[controller]" )]
- public class PeopleController : Controller
+ public class PeopleController : ControllerBase
{
///
/// Gets a single person.
@@ -20,6 +21,7 @@ public class PeopleController : Controller
/// The person was successfully retrieved.
/// The person does not exist.
[HttpGet( "{id:int}" )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Person ), 200 )]
[ProducesResponseType( 404 )]
public IActionResult Get( int id ) =>
diff --git a/samples/aspnetcore/SwaggerSample/V2/Controllers/OrdersController.cs b/samples/aspnetcore/SwaggerSample/V2/Controllers/OrdersController.cs
index 312cc223..9419770a 100644
--- a/samples/aspnetcore/SwaggerSample/V2/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/SwaggerSample/V2/Controllers/OrdersController.cs
@@ -8,9 +8,10 @@
///
/// Represents a RESTful service of orders.
///
+ [ApiController]
[ApiVersion( "2.0" )]
[Route( "api/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
const string ByIdRouteName = "GetOrderById-" + nameof( V2 );
@@ -20,6 +21,7 @@ public class OrdersController : Controller
/// All available orders.
/// The successfully retrieved orders.
[HttpGet]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( IEnumerable ), 200 )]
public IActionResult Get()
{
@@ -41,6 +43,7 @@ public IActionResult Get()
/// The order was successfully retrieved.
/// The order does not exist.
[HttpGet( "{id:int}", Name = ByIdRouteName )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 200 )]
[ProducesResponseType( 400 )]
[ProducesResponseType( 404 )]
@@ -54,6 +57,7 @@ public IActionResult Get()
/// The order was successfully placed.
/// The order is invalid.
[HttpPost]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 201 )]
[ProducesResponseType( 400 )]
public IActionResult Post( [FromBody] Order order )
diff --git a/samples/aspnetcore/SwaggerSample/V2/Controllers/PeopleController.cs b/samples/aspnetcore/SwaggerSample/V2/Controllers/PeopleController.cs
index 4ca147f4..2f587c08 100644
--- a/samples/aspnetcore/SwaggerSample/V2/Controllers/PeopleController.cs
+++ b/samples/aspnetcore/SwaggerSample/V2/Controllers/PeopleController.cs
@@ -8,9 +8,10 @@
///
/// Represents a RESTful people service.
///
+ [ApiController]
[ApiVersion( "2.0" )]
[Route( "api/v{api-version:apiVersion}/[controller]" )]
- public class PeopleController : Controller
+ public class PeopleController : ControllerBase
{
const string ByIdRouteName = "GetPersonById" + nameof( V2 );
@@ -20,6 +21,7 @@ public class PeopleController : Controller
/// All available people.
/// The successfully retrieved people.
[HttpGet]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( IEnumerable ), 200 )]
public IActionResult Get()
{
@@ -59,6 +61,7 @@ public IActionResult Get()
/// The person was successfully retrieved.
/// The person does not exist.
[HttpGet( "{id:int}", Name = ByIdRouteName )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Person ), 200 )]
[ProducesResponseType( 404 )]
public IActionResult Get( int id ) =>
diff --git a/samples/aspnetcore/SwaggerSample/V3/Controllers/OrdersController.cs b/samples/aspnetcore/SwaggerSample/V3/Controllers/OrdersController.cs
index ea67d0d4..6c1551a7 100644
--- a/samples/aspnetcore/SwaggerSample/V3/Controllers/OrdersController.cs
+++ b/samples/aspnetcore/SwaggerSample/V3/Controllers/OrdersController.cs
@@ -8,9 +8,10 @@
///
/// Represents a RESTful service of orders.
///
+ [ApiController]
[ApiVersion( "3.0" )]
[Route( "api/[controller]" )]
- public class OrdersController : Controller
+ public class OrdersController : ControllerBase
{
const string ByIdRouteName = "GetOrderById-" + nameof( V3 );
@@ -21,6 +22,7 @@ public class OrdersController : Controller
/// Orders successfully retrieved.
/// The order is invalid.
[HttpGet]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( IEnumerable ), 200 )]
[ProducesResponseType( 400 )]
public IActionResult Get()
@@ -43,6 +45,7 @@ public IActionResult Get()
/// The order was successfully retrieved.
/// The order does not exist.
[HttpGet( "{id:int}", Name = ByIdRouteName )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 200 )]
[ProducesResponseType( 400 )]
[ProducesResponseType( 404 )]
@@ -56,6 +59,7 @@ public IActionResult Get()
/// The order was successfully placed.
/// The order is invalid.
[HttpPost]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Order ), 201 )]
[ProducesResponseType( 400 )]
public IActionResult Post( [FromBody] Order order )
diff --git a/samples/aspnetcore/SwaggerSample/V3/Controllers/PeopleController.cs b/samples/aspnetcore/SwaggerSample/V3/Controllers/PeopleController.cs
index 3ed4ee93..c47550d5 100644
--- a/samples/aspnetcore/SwaggerSample/V3/Controllers/PeopleController.cs
+++ b/samples/aspnetcore/SwaggerSample/V3/Controllers/PeopleController.cs
@@ -8,9 +8,10 @@
///
/// Represents a RESTful people service.
///
+ [ApiController]
[ApiVersion( "3.0" )]
[Route( "api/v{api-version:apiVersion}/[controller]" )]
- public class PeopleController : Controller
+ public class PeopleController : ControllerBase
{
const string ByIdRouteName = "GetPersonById" + nameof( V3 );
@@ -20,6 +21,7 @@ public class PeopleController : Controller
/// All available people.
/// The successfully retrieved people.
[HttpGet]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( IEnumerable ), 200 )]
public IActionResult Get()
{
@@ -62,6 +64,7 @@ public IActionResult Get()
/// The person was successfully retrieved.
/// The person does not exist.
[HttpGet( "{id:int}", Name = ByIdRouteName )]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Person ), 200 )]
[ProducesResponseType( 404 )]
public IActionResult Get( int id ) =>
@@ -83,6 +86,7 @@ public IActionResult Get( int id ) =>
/// The person was successfully created.
/// The person was invalid.
[HttpPost]
+ [Produces( "application/json" )]
[ProducesResponseType( typeof( Person ), 201 )]
[ProducesResponseType( 400 )]
public IActionResult Post( [FromBody] Person person )
diff --git a/samples/aspnetcore/SwaggerSample/appsettings.json b/samples/aspnetcore/SwaggerSample/appsettings.json
index fa8ce71a..d713e815 100644
--- a/samples/aspnetcore/SwaggerSample/appsettings.json
+++ b/samples/aspnetcore/SwaggerSample/appsettings.json
@@ -1,10 +1,8 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Warning"
}
- }
-}
+ },
+ "AllowedHosts": "*"
+}
\ No newline at end of file
diff --git a/samples/directory.build.props b/samples/directory.build.props
new file mode 100644
index 00000000..4132bd00
--- /dev/null
+++ b/samples/directory.build.props
@@ -0,0 +1,8 @@
+
+
+
+
+ latest
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/AdvancedODataWebApiSample.csproj b/samples/webapi/AdvancedODataWebApiSample/AdvancedODataWebApiSample.csproj
index ef7dcc79..e1fec955 100644
--- a/samples/webapi/AdvancedODataWebApiSample/AdvancedODataWebApiSample.csproj
+++ b/samples/webapi/AdvancedODataWebApiSample/AdvancedODataWebApiSample.csproj
@@ -1,195 +1,23 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {E496EED0-F8C9-4FE9-83E6-75E47A3C41A1}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- AdvancedODataWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.AspNet.OData.7.0.1\lib\net45\Microsoft.AspNet.OData.dll
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
-
-
- ..\..\..\packages\Microsoft.OData.Core.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll
-
-
- ..\..\..\packages\Microsoft.OData.Edm.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Microsoft.Spatial.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
- WebApi
-
-
- WebApi.OData
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {48a2b488-23ab-4c83-ae30-0b8b735c4562}
- Microsoft.AspNet.OData.Versioning
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 1044
- /
- http://localhost:1044/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/Program.cs b/samples/webapi/AdvancedODataWebApiSample/Program.cs
new file mode 100644
index 00000000..4435130e
--- /dev/null
+++ b/samples/webapi/AdvancedODataWebApiSample/Program.cs
@@ -0,0 +1,35 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9006/";
+ const string LaunchUrl = Url + "api";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/AdvancedODataWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index d2a17363..00000000
--- a/samples/webapi/AdvancedODataWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "AdvancedODataWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "AdvancedODataWebApiSample" )]
-[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( "e496eed0-f8c9-4fe9-83e6-75e47a3c41a1" )]
-
-// 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/samples/webapi/AdvancedODataWebApiSample/Startup.cs b/samples/webapi/AdvancedODataWebApiSample/Startup.cs
index 5237f5c8..708cd1fa 100644
--- a/samples/webapi/AdvancedODataWebApiSample/Startup.cs
+++ b/samples/webapi/AdvancedODataWebApiSample/Startup.cs
@@ -11,6 +11,7 @@ namespace Microsoft.Examples
using Microsoft.OData;
using Microsoft.OData.UriParser;
using Microsoft.Web.Http.Versioning;
+ using System;
using System.Web.Http;
using static Microsoft.OData.ODataUrlKeyDelimiter;
using static Microsoft.OData.ServiceLifetime;
@@ -24,11 +25,17 @@ public void Configuration( IAppBuilder appBuilder )
var httpServer = new HttpServer( configuration );
configuration.AddApiVersioning(
- o =>
+ options =>
{
- o.ReportApiVersions = true;
- o.AssumeDefaultVersionWhenUnspecified = true;
- o.ApiVersionReader = ApiVersionReader.Combine(
+ // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
+ options.ReportApiVersions = true;
+
+ // allows a client to make a request without specifying an api version. the value of
+ // options.DefaultApiVersion will be 'assumed'; this is meant to grandfather in legacy apis
+ options.AssumeDefaultVersionWhenUnspecified = true;
+
+ // allow multiple locations to request an api version
+ options.ApiVersionReader = ApiVersionReader.Combine(
new QueryStringApiVersionReader(),
new HeaderApiVersionReader( "api-version", "x-ms-version" ) );
} );
@@ -44,8 +51,14 @@ public void Configuration( IAppBuilder appBuilder )
var models = modelBuilder.GetEdmModels();
var batchHandler = new DefaultODataBatchHandler( httpServer );
+ // 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.
+ //
+ // DO NOT use configuration.MapHttpAttributeRoutes();
configuration.MapVersionedODataRoutes( "odata", "api", models, ConfigureContainer, batchHandler );
configuration.Routes.MapHttpRoute( "orders", "api/{controller}/{id}", new { id = Optional } );
+
appBuilder.UseWebApi( httpServer );
}
@@ -54,5 +67,20 @@ static void ConfigureContainer( IContainerBuilder builder )
builder.AddService( Singleton, sp => new DefaultODataPathHandler() { UrlKeyDelimiter = Parentheses } );
builder.AddService( Singleton, sp => new UnqualifiedCallAndEnumPrefixFreeResolver() { EnableCaseInsensitive = true } );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/Web.Debug.config b/samples/webapi/AdvancedODataWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/AdvancedODataWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/Web.Release.config b/samples/webapi/AdvancedODataWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/AdvancedODataWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/Web.config b/samples/webapi/AdvancedODataWebApiSample/Web.config
deleted file mode 100644
index 0eee3764..00000000
--- a/samples/webapi/AdvancedODataWebApiSample/Web.config
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/AdvancedODataWebApiSample/packages.config b/samples/webapi/AdvancedODataWebApiSample/packages.config
deleted file mode 100644
index 31a889a4..00000000
--- a/samples/webapi/AdvancedODataWebApiSample/packages.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/BasicODataWebApiSample.csproj b/samples/webapi/BasicODataWebApiSample/BasicODataWebApiSample.csproj
index 957610a6..e1fec955 100644
--- a/samples/webapi/BasicODataWebApiSample/BasicODataWebApiSample.csproj
+++ b/samples/webapi/BasicODataWebApiSample/BasicODataWebApiSample.csproj
@@ -1,190 +1,23 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {8C09CD67-5153-413C-B870-2FC7488C2D53}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- BasicODataWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- true
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.AspNet.OData.7.0.1\lib\net45\Microsoft.AspNet.OData.dll
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
-
-
- ..\..\..\packages\Microsoft.OData.Core.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll
-
-
- ..\..\..\packages\Microsoft.OData.Edm.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Microsoft.Spatial.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {48a2b488-23ab-4c83-ae30-0b8b735c4562}
- Microsoft.AspNet.OData.Versioning
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- False
- True
- 4129
- /
- http://localhost:4129/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/Program.cs b/samples/webapi/BasicODataWebApiSample/Program.cs
new file mode 100644
index 00000000..40dcc411
--- /dev/null
+++ b/samples/webapi/BasicODataWebApiSample/Program.cs
@@ -0,0 +1,37 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Diagnostics;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9004/";
+ const string LaunchUrl = Url + "api";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ Process.Start( LaunchUrl );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/BasicODataWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index c21c4bed..00000000
--- a/samples/webapi/BasicODataWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "BasicODataWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "BasicODataWebApiSample" )]
-[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( "8c09cd67-5153-413c-b870-2fc7488c2d53" )]
-
-// 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/samples/webapi/BasicODataWebApiSample/Startup.cs b/samples/webapi/BasicODataWebApiSample/Startup.cs
index a6fdcde5..42f4b164 100644
--- a/samples/webapi/BasicODataWebApiSample/Startup.cs
+++ b/samples/webapi/BasicODataWebApiSample/Startup.cs
@@ -10,6 +10,7 @@ namespace Microsoft.Examples
using Microsoft.Examples.Configuration;
using Microsoft.OData;
using Microsoft.OData.UriParser;
+ using System;
using System.Web.Http;
using static Microsoft.OData.ODataUrlKeyDelimiter;
using static Microsoft.OData.ServiceLifetime;
@@ -22,7 +23,7 @@ public void Configuration( IAppBuilder appBuilder )
var httpServer = new HttpServer( configuration );
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- configuration.AddApiVersioning( o => o.ReportApiVersions = true );
+ configuration.AddApiVersioning( options => options.ReportApiVersions = true );
var modelBuilder = new VersionedODataModelBuilder( configuration )
{
@@ -35,8 +36,12 @@ public void Configuration( IAppBuilder appBuilder )
var models = modelBuilder.GetEdmModels();
var batchHandler = new DefaultODataBatchHandler( httpServer );
+ // NOTE: you do NOT and should NOT use both the query string and url segment methods together.
+ // this configuration is merely illustrating that they can coexist and allows you to easily
+ // experiment with either configuration. one of these would be removed in a real application.
configuration.MapVersionedODataRoutes( "odata", "api", models, ConfigureContainer, batchHandler );
- configuration.MapVersionedODataRoutes( "odata-bypath", "v{apiVersion}", models, ConfigureContainer );
+ configuration.MapVersionedODataRoutes( "odata-bypath", "api/v{apiVersion}", models, ConfigureContainer );
+
appBuilder.UseWebApi( httpServer );
}
@@ -45,5 +50,20 @@ static void ConfigureContainer( IContainerBuilder builder )
builder.AddService( Singleton, sp => new DefaultODataPathHandler() { UrlKeyDelimiter = Parentheses } );
builder.AddService( Singleton, sp => new UnqualifiedCallAndEnumPrefixFreeResolver() { EnableCaseInsensitive = true } );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/Web.Debug.config b/samples/webapi/BasicODataWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/BasicODataWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/Web.Release.config b/samples/webapi/BasicODataWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/BasicODataWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/Web.config b/samples/webapi/BasicODataWebApiSample/Web.config
deleted file mode 100644
index 1e3e566e..00000000
--- a/samples/webapi/BasicODataWebApiSample/Web.config
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicODataWebApiSample/packages.config b/samples/webapi/BasicODataWebApiSample/packages.config
deleted file mode 100644
index 31a889a4..00000000
--- a/samples/webapi/BasicODataWebApiSample/packages.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/BasicWebApiSample.csproj b/samples/webapi/BasicWebApiSample/BasicWebApiSample.csproj
index 602f1f82..6d72d965 100644
--- a/samples/webapi/BasicWebApiSample/BasicWebApiSample.csproj
+++ b/samples/webapi/BasicWebApiSample/BasicWebApiSample.csproj
@@ -1,163 +1,22 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {D1DF9ECC-7D2F-4982-8E45-BD690EF80906}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- BasicWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 11008
- /
- http://localhost:25282/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/Program.cs b/samples/webapi/BasicWebApiSample/Program.cs
new file mode 100644
index 00000000..05dee1d5
--- /dev/null
+++ b/samples/webapi/BasicWebApiSample/Program.cs
@@ -0,0 +1,34 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9000/";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/BasicWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index 42477829..00000000
--- a/samples/webapi/BasicWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "BasicWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "BasicWebApiSample" )]
-[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( "d1df9ecc-7d2f-4982-8e45-bd690ef80906" )]
-
-// 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/samples/webapi/BasicWebApiSample/Startup.cs b/samples/webapi/BasicWebApiSample/Startup.cs
index f1803886..77632525 100644
--- a/samples/webapi/BasicWebApiSample/Startup.cs
+++ b/samples/webapi/BasicWebApiSample/Startup.cs
@@ -4,6 +4,7 @@ namespace Microsoft.Examples
{
using global::Owin;
using Microsoft.Web.Http.Routing;
+ using System;
using System.Web.Http;
using System.Web.Http.Routing;
@@ -17,9 +18,24 @@ public void Configuration( IAppBuilder builder )
var httpServer = new HttpServer( configuration );
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- configuration.AddApiVersioning( o => o.ReportApiVersions = true );
+ configuration.AddApiVersioning( options => options.ReportApiVersions = true );
configuration.MapHttpAttributeRoutes( constraintResolver );
builder.UseWebApi( httpServer );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/Web.Debug.config b/samples/webapi/BasicWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/BasicWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/Web.Release.config b/samples/webapi/BasicWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/BasicWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/Web.config b/samples/webapi/BasicWebApiSample/Web.config
deleted file mode 100644
index 693df44d..00000000
--- a/samples/webapi/BasicWebApiSample/Web.config
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/BasicWebApiSample/packages.config b/samples/webapi/BasicWebApiSample/packages.config
deleted file mode 100644
index 01cf5055..00000000
--- a/samples/webapi/BasicWebApiSample/packages.config
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/ByNamespaceWebApiSample.csproj b/samples/webapi/ByNamespaceWebApiSample/ByNamespaceWebApiSample.csproj
index 744c545b..6d72d965 100644
--- a/samples/webapi/ByNamespaceWebApiSample/ByNamespaceWebApiSample.csproj
+++ b/samples/webapi/ByNamespaceWebApiSample/ByNamespaceWebApiSample.csproj
@@ -1,170 +1,22 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {A02A4245-3AEB-4549-9037-D89DFDC7E74D}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- ByNamespaceWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 1676
- /
- http://localhost:1676/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/Program.cs b/samples/webapi/ByNamespaceWebApiSample/Program.cs
new file mode 100644
index 00000000..0f38534f
--- /dev/null
+++ b/samples/webapi/ByNamespaceWebApiSample/Program.cs
@@ -0,0 +1,34 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9002/";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/ByNamespaceWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index f27d3a87..00000000
--- a/samples/webapi/ByNamespaceWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "ByNamespaceWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "ByNamespaceWebApiSample" )]
-[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( "a02a4245-3aeb-4549-9037-d89dfdc7e74d" )]
-
-// 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/samples/webapi/ByNamespaceWebApiSample/Startup.cs b/samples/webapi/ByNamespaceWebApiSample/Startup.cs
index 9f2c9159..e4bfc6c7 100644
--- a/samples/webapi/ByNamespaceWebApiSample/Startup.cs
+++ b/samples/webapi/ByNamespaceWebApiSample/Startup.cs
@@ -5,8 +5,8 @@ namespace Microsoft.Examples
using global::Owin;
using Microsoft.Web.Http.Routing;
using Microsoft.Web.Http.Versioning.Conventions;
+ using System;
using System.Web.Http;
- using System.Web.Http.Routing;
public class Startup
{
@@ -25,6 +25,9 @@ public void Configuration( IAppBuilder builder )
options.Conventions.Add( new VersionByNamespaceConvention() );
} );
+ // NOTE: you do NOT and should NOT use both the query string and url segment methods together.
+ // this configuration is merely illustrating that they can coexist and allows you to easily
+ // experiment with either configuration. one of these would be removed in a real application.
configuration.Routes.MapHttpRoute(
"VersionedQueryString",
"api/{controller}/{accountId}",
@@ -38,5 +41,20 @@ public void Configuration( IAppBuilder builder )
builder.UseWebApi( httpServer );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/Web.Debug.config b/samples/webapi/ByNamespaceWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/ByNamespaceWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/Web.Release.config b/samples/webapi/ByNamespaceWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/ByNamespaceWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/Web.config b/samples/webapi/ByNamespaceWebApiSample/Web.config
deleted file mode 100644
index 8f8abb27..00000000
--- a/samples/webapi/ByNamespaceWebApiSample/Web.config
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ByNamespaceWebApiSample/packages.config b/samples/webapi/ByNamespaceWebApiSample/packages.config
deleted file mode 100644
index 01cf5055..00000000
--- a/samples/webapi/ByNamespaceWebApiSample/packages.config
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/ConventionsODataWebApiSample.csproj b/samples/webapi/ConventionsODataWebApiSample/ConventionsODataWebApiSample.csproj
index b45473a3..e1fec955 100644
--- a/samples/webapi/ConventionsODataWebApiSample/ConventionsODataWebApiSample.csproj
+++ b/samples/webapi/ConventionsODataWebApiSample/ConventionsODataWebApiSample.csproj
@@ -1,187 +1,23 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {9A22600C-7768-4D16-B67D-514F55942FAF}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- ConventionsODataWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.AspNet.OData.7.0.1\lib\net45\Microsoft.AspNet.OData.dll
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
-
-
- ..\..\..\packages\Microsoft.OData.Core.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll
-
-
- ..\..\..\packages\Microsoft.OData.Edm.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Microsoft.Spatial.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {48a2b488-23ab-4c83-ae30-0b8b735c4562}
- Microsoft.AspNet.OData.Versioning
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 3024
- /
- http://localhost:3024/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/Program.cs b/samples/webapi/ConventionsODataWebApiSample/Program.cs
new file mode 100644
index 00000000..26cd5953
--- /dev/null
+++ b/samples/webapi/ConventionsODataWebApiSample/Program.cs
@@ -0,0 +1,37 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Diagnostics;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9005/";
+ const string LaunchUrl = Url + "api";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ Process.Start( LaunchUrl );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/ConventionsODataWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index af4d7e73..00000000
--- a/samples/webapi/ConventionsODataWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "ConventionsODataWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "ConventionsODataWebApiSample" )]
-[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( "9a22600c-7768-4d16-b67d-514f55942faf" )]
-
-// 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/samples/webapi/ConventionsODataWebApiSample/Startup.cs b/samples/webapi/ConventionsODataWebApiSample/Startup.cs
index c228297f..191a7d1b 100644
--- a/samples/webapi/ConventionsODataWebApiSample/Startup.cs
+++ b/samples/webapi/ConventionsODataWebApiSample/Startup.cs
@@ -12,6 +12,7 @@ namespace Microsoft.Examples
using Microsoft.OData;
using Microsoft.OData.UriParser;
using Microsoft.Web.Http.Versioning.Conventions;
+ using System;
using System.Web.Http;
using static Microsoft.OData.ODataUrlKeyDelimiter;
using static Microsoft.OData.ServiceLifetime;
@@ -36,7 +37,7 @@ public void Configuration( IAppBuilder appBuilder )
options.Conventions.Controller()
.HasApiVersion( 1, 0 )
.HasApiVersion( 2, 0 )
- .Action( c => c.Patch( default( int ), null, null ) ).MapToApiVersion( 2, 0 );
+ .Action( c => c.Patch( default, default, default ) ).MapToApiVersion( 2, 0 );
options.Conventions.Controller()
.HasApiVersion( 3, 0 );
@@ -53,8 +54,12 @@ public void Configuration( IAppBuilder appBuilder )
var models = modelBuilder.GetEdmModels();
var batchHandler = new DefaultODataBatchHandler( httpServer );
+ // NOTE: you do NOT and should NOT use both the query string and url segment methods together.
+ // this configuration is merely illustrating that they can coexist and allows you to easily
+ // experiment with either configuration. one of these would be removed in a real application.
configuration.MapVersionedODataRoutes( "odata", "api", models, ConfigureContainer, batchHandler );
- configuration.MapVersionedODataRoutes( "odata-bypath", "v{apiVersion}", models, ConfigureContainer );
+ configuration.MapVersionedODataRoutes( "odata-bypath", "api/v{apiVersion}", models, ConfigureContainer );
+
appBuilder.UseWebApi( httpServer );
}
@@ -63,5 +68,20 @@ static void ConfigureContainer( IContainerBuilder builder )
builder.AddService( Singleton, sp => new DefaultODataPathHandler() { UrlKeyDelimiter = Parentheses } );
builder.AddService( Singleton, sp => new UnqualifiedCallAndEnumPrefixFreeResolver() { EnableCaseInsensitive = true } );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/Web.Debug.config b/samples/webapi/ConventionsODataWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/ConventionsODataWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/Web.Release.config b/samples/webapi/ConventionsODataWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/ConventionsODataWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/Web.config b/samples/webapi/ConventionsODataWebApiSample/Web.config
deleted file mode 100644
index 1e3e566e..00000000
--- a/samples/webapi/ConventionsODataWebApiSample/Web.config
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsODataWebApiSample/packages.config b/samples/webapi/ConventionsODataWebApiSample/packages.config
deleted file mode 100644
index 31a889a4..00000000
--- a/samples/webapi/ConventionsODataWebApiSample/packages.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/ConventionsWebApiSample.csproj b/samples/webapi/ConventionsWebApiSample/ConventionsWebApiSample.csproj
index b3192e5b..6d72d965 100644
--- a/samples/webapi/ConventionsWebApiSample/ConventionsWebApiSample.csproj
+++ b/samples/webapi/ConventionsWebApiSample/ConventionsWebApiSample.csproj
@@ -1,161 +1,22 @@
-
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {C1F89961-7134-4D97-BA3A-2693FD1CBF4E}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- ConventionsWebApiSample
- v4.5
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
-
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 12330
- /
- http://localhost:12330/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/Program.cs b/samples/webapi/ConventionsWebApiSample/Program.cs
new file mode 100644
index 00000000..99926a4a
--- /dev/null
+++ b/samples/webapi/ConventionsWebApiSample/Program.cs
@@ -0,0 +1,34 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Threading;
+
+ public class Program
+ {
+ const string Url = "http://localhost:9001/";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/ConventionsWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index b9dd0658..00000000
--- a/samples/webapi/ConventionsWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "ConventionsWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "ConventionsWebApiSample" )]
-[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( "c1f89961-7134-4d97-ba3a-2693fd1cbf4e" )]
-
-// 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/samples/webapi/ConventionsWebApiSample/Startup.cs b/samples/webapi/ConventionsWebApiSample/Startup.cs
index fca1972e..8d18deaf 100644
--- a/samples/webapi/ConventionsWebApiSample/Startup.cs
+++ b/samples/webapi/ConventionsWebApiSample/Startup.cs
@@ -6,6 +6,7 @@ namespace Microsoft.Examples
using global::Owin;
using Microsoft.Web.Http.Routing;
using Microsoft.Web.Http.Versioning.Conventions;
+ using System;
using System.Web.Http;
using System.Web.Http.Routing;
@@ -24,13 +25,14 @@ public void Configuration( IAppBuilder builder )
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
options.ReportApiVersions = true;
- // apply api versions using conventions rather than attributes
options.Conventions.Controller().HasApiVersion( 1, 0 );
+
options.Conventions.Controller()
.HasApiVersion( 2, 0 )
.HasApiVersion( 3, 0 )
.Action( c => c.GetV3() ).MapToApiVersion( 3, 0 )
- .Action( c => c.GetV3( default( int ) ) ).MapToApiVersion( 3, 0 );
+ .Action( c => c.GetV3( default ) ).MapToApiVersion( 3, 0 );
+
options.Conventions.Controller()
.HasApiVersion( 1, 0 )
.HasApiVersion( 2, 0 )
@@ -40,5 +42,20 @@ public void Configuration( IAppBuilder builder )
configuration.MapHttpAttributeRoutes( constraintResolver );
builder.UseWebApi( httpServer );
}
+
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/Web.Debug.config b/samples/webapi/ConventionsWebApiSample/Web.Debug.config
deleted file mode 100644
index 2e302f9f..00000000
--- a/samples/webapi/ConventionsWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/Web.Release.config b/samples/webapi/ConventionsWebApiSample/Web.Release.config
deleted file mode 100644
index c3584446..00000000
--- a/samples/webapi/ConventionsWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/Web.config b/samples/webapi/ConventionsWebApiSample/Web.config
deleted file mode 100644
index 693df44d..00000000
--- a/samples/webapi/ConventionsWebApiSample/Web.config
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/ConventionsWebApiSample/packages.config b/samples/webapi/ConventionsWebApiSample/packages.config
deleted file mode 100644
index 01cf5055..00000000
--- a/samples/webapi/ConventionsWebApiSample/packages.config
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/Program.cs b/samples/webapi/SwaggerODataWebApiSample/Program.cs
new file mode 100644
index 00000000..e35af21a
--- /dev/null
+++ b/samples/webapi/SwaggerODataWebApiSample/Program.cs
@@ -0,0 +1,44 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Diagnostics;
+ using System.Threading;
+
+ ///
+ /// Represents the current application.
+ ///
+ public class Program
+ {
+ const string Url = "http://localhost:9007/";
+ const string LaunchUrl = Url + "swagger";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ ///
+ /// The main entry point to the application.
+ ///
+ /// The arguments provided at start-up, if any.
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ Process.Start( LaunchUrl );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/SwaggerODataWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index 499130a9..00000000
--- a/samples/webapi/SwaggerODataWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "SwaggerODataWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "SwaggerODataWebApiSample" )]
-[assembly: AssemblyCopyright( "Copyright © 2017" )]
-[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( "f3986f7b-af76-43d1-a44f-303023a08cd3" )]
-
-// 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/samples/webapi/SwaggerODataWebApiSample/Startup.cs b/samples/webapi/SwaggerODataWebApiSample/Startup.cs
index 44400476..6261673b 100644
--- a/samples/webapi/SwaggerODataWebApiSample/Startup.cs
+++ b/samples/webapi/SwaggerODataWebApiSample/Startup.cs
@@ -33,12 +33,11 @@ public class Startup
/// The current application builder.
public void Configuration( IAppBuilder builder )
{
- const string routePrefix = default( string );
var configuration = new HttpConfiguration();
var httpServer = new HttpServer( configuration );
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- configuration.AddApiVersioning( o => o.ReportApiVersions = true );
+ configuration.AddApiVersioning( options => options.ReportApiVersions = true );
// 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();
@@ -57,10 +56,10 @@ public void Configuration( IAppBuilder builder )
// INFO: while you can use both, you should choose only ONE of the following; comment, uncomment, or remove as necessary
// WHEN VERSIONING BY: query string, header, or media type
- configuration.MapVersionedODataRoutes( "odata", routePrefix, models, ConfigureContainer );
+ configuration.MapVersionedODataRoutes( "odata", "api", models, ConfigureContainer );
// WHEN VERSIONING BY: url segment
- //configuration.MapVersionedODataRoutes( "odata-bypath", "api/v{apiVersion}", models, ConfigureContainer );
+ // configuration.MapVersionedODataRoutes( "odata-bypath", "api/v{apiVersion}", models, ConfigureContainer );
// 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]"
@@ -75,10 +74,10 @@ public void Configuration( IAppBuilder builder )
// configure query options (which cannot otherwise be configured by OData conventions)
options.QueryOptions.Controller()
- .Action( c => c.Get( default( ODataQueryOptions ) ) ).Allow( Skip | Count ).AllowTop( 100 );
+ .Action( c => c.Get( default ) ).Allow( Skip | Count ).AllowTop( 100 );
options.QueryOptions.Controller()
- .Action( c => c.Get( default( ODataQueryOptions ) ) ).Allow( Skip | Count ).AllowTop( 100 );
+ .Action( c => c.Get( default ) ).Allow( Skip | Count ).AllowTop( 100 );
} );
configuration.EnableSwagger(
@@ -118,13 +117,31 @@ public void Configuration( IAppBuilder builder )
builder.UseWebApi( httpServer );
}
+ ///
+ /// Get the root content path.
+ ///
+ /// The root content path of the application.
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
+
static string XmlCommentsFilePath
{
get
{
- var basePath = AppDomain.CurrentDomain.RelativeSearchPath;
var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
- return Path.Combine( basePath, fileName );
+ return Path.Combine( ContentRootPath, fileName );
}
}
diff --git a/samples/webapi/SwaggerODataWebApiSample/SwaggerODataWebApiSample.csproj b/samples/webapi/SwaggerODataWebApiSample/SwaggerODataWebApiSample.csproj
index 079b29f7..c8e666b0 100644
--- a/samples/webapi/SwaggerODataWebApiSample/SwaggerODataWebApiSample.csproj
+++ b/samples/webapi/SwaggerODataWebApiSample/SwaggerODataWebApiSample.csproj
@@ -1,205 +1,25 @@
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {F3986F7B-AF76-43D1-A44F-303023A08CD3}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- SwaggerODataWebApiSample
- v4.5.2
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
- bin\SwaggerODataWebApiSample.xml
-
-
- true
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
- bin\SwaggerODataWebApiSample.xml
-
-
-
- ..\..\..\packages\Microsoft.AspNet.OData.7.0.1\lib\net45\Microsoft.AspNet.OData.dll
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll
-
-
- ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
-
-
- ..\..\..\packages\Microsoft.OData.Core.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll
-
-
- ..\..\..\packages\Microsoft.OData.Edm.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
-
-
- ..\..\..\packages\Microsoft.Spatial.7.5.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
- ..\..\..\packages\Swashbuckle.Core.5.5.3\lib\net40\Swashbuckle.Core.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.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {1b255310-a2b7-437f-804f-6e1d8c940a17}
- Microsoft.AspNet.OData.Versioning.ApiExplorer
-
-
- {48a2b488-23ab-4c83-ae30-0b8b735c4562}
- Microsoft.AspNet.OData.Versioning
-
-
- {91e1f0b5-905d-446c-a2dd-4c1edabfaf6c}
- Microsoft.AspNet.WebApi.Versioning.ApiExplorer
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 1874
- /
- http://localhost:1874/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+ bin\$(Configuration)\$(TargetFramework)\$(MSBuildThisFileName).xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/Web.Debug.config b/samples/webapi/SwaggerODataWebApiSample/Web.Debug.config
deleted file mode 100644
index fae9cfef..00000000
--- a/samples/webapi/SwaggerODataWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/Web.Release.config b/samples/webapi/SwaggerODataWebApiSample/Web.Release.config
deleted file mode 100644
index da6e960b..00000000
--- a/samples/webapi/SwaggerODataWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/Web.config b/samples/webapi/SwaggerODataWebApiSample/Web.config
deleted file mode 100644
index bbd13666..00000000
--- a/samples/webapi/SwaggerODataWebApiSample/Web.config
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerODataWebApiSample/packages.config b/samples/webapi/SwaggerODataWebApiSample/packages.config
deleted file mode 100644
index 0675ce3f..00000000
--- a/samples/webapi/SwaggerODataWebApiSample/packages.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/Program.cs b/samples/webapi/SwaggerWebApiSample/Program.cs
new file mode 100644
index 00000000..e9845d81
--- /dev/null
+++ b/samples/webapi/SwaggerWebApiSample/Program.cs
@@ -0,0 +1,44 @@
+namespace Microsoft.Examples
+{
+ using Microsoft.Owin.Hosting;
+ using System;
+ using System.Diagnostics;
+ using System.Threading;
+
+ ///
+ /// Represents the current application.
+ ///
+ public class Program
+ {
+ const string Url = "http://localhost:9003/";
+ const string LaunchUrl = Url + "swagger";
+ static readonly ManualResetEvent resetEvent = new ManualResetEvent( false );
+
+ ///
+ /// The main entry point to the application.
+ ///
+ /// The arguments provided at start-up, if any.
+ public static void Main( string[] args )
+ {
+ Console.CancelKeyPress += OnCancel;
+
+ using ( WebApp.Start( Url ) )
+ {
+ Console.WriteLine( "Content root path: " + Startup.ContentRootPath );
+ Console.WriteLine( "Now listening on: " + Url );
+ Console.WriteLine( "Application started. Press Ctrl+C to shut down." );
+ Process.Start( LaunchUrl );
+ resetEvent.WaitOne();
+ }
+
+ Console.CancelKeyPress -= OnCancel;
+ }
+
+ static void OnCancel( object sender, ConsoleCancelEventArgs e )
+ {
+ Console.Write( "Application is shutting down..." );
+ e.Cancel = true;
+ resetEvent.Set();
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/Properties/AssemblyInfo.cs b/samples/webapi/SwaggerWebApiSample/Properties/AssemblyInfo.cs
deleted file mode 100644
index 2bbb1aa3..00000000
--- a/samples/webapi/SwaggerWebApiSample/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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( "SwaggerWebApiSample" )]
-[assembly: AssemblyDescription( "" )]
-[assembly: AssemblyConfiguration( "" )]
-[assembly: AssemblyCompany( "" )]
-[assembly: AssemblyProduct( "SwaggerWebApiSample" )]
-[assembly: AssemblyCopyright( "Copyright © 2017" )]
-[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( "6bede228-4be9-499e-b1e6-93b6b0ac62da" )]
-
-// 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/samples/webapi/SwaggerWebApiSample/Startup.cs b/samples/webapi/SwaggerWebApiSample/Startup.cs
index e4f6c36e..8f09ca9f 100644
--- a/samples/webapi/SwaggerWebApiSample/Startup.cs
+++ b/samples/webapi/SwaggerWebApiSample/Startup.cs
@@ -5,6 +5,7 @@ namespace Microsoft.Examples
using global::Owin;
using Microsoft.Web.Http.Routing;
using Swashbuckle.Application;
+ using System;
using System.IO;
using System.Reflection;
using System.Web.Http;
@@ -28,7 +29,7 @@ public void Configuration( IAppBuilder builder )
var httpServer = new HttpServer( configuration );
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
- configuration.AddApiVersioning( o => o.ReportApiVersions = true );
+ configuration.AddApiVersioning( options => options.ReportApiVersions = true );
configuration.MapHttpAttributeRoutes( constraintResolver );
// add the versioned IApiExplorer and capture the strongly-typed implementation (e.g. VersionedApiExplorer vs IApiExplorer)
@@ -80,13 +81,31 @@ public void Configuration( IAppBuilder builder )
builder.UseWebApi( httpServer );
}
+ ///
+ /// Get the root content path.
+ ///
+ /// The root content path of the application.
+ public static string ContentRootPath
+ {
+ get
+ {
+ var app = AppDomain.CurrentDomain;
+
+ if ( string.IsNullOrEmpty( app.RelativeSearchPath ) )
+ {
+ return app.BaseDirectory;
+ }
+
+ return app.RelativeSearchPath;
+ }
+ }
+
static string XmlCommentsFilePath
{
get
{
- var basePath = System.AppDomain.CurrentDomain.RelativeSearchPath;
var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
- return Path.Combine( basePath, fileName );
+ return Path.Combine( ContentRootPath, fileName );
}
}
}
diff --git a/samples/webapi/SwaggerWebApiSample/SwaggerWebApiSample.csproj b/samples/webapi/SwaggerWebApiSample/SwaggerWebApiSample.csproj
index 431aa3a3..0d8d019d 100644
--- a/samples/webapi/SwaggerWebApiSample/SwaggerWebApiSample.csproj
+++ b/samples/webapi/SwaggerWebApiSample/SwaggerWebApiSample.csproj
@@ -1,179 +1,25 @@
-
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {6BEDE228-4BE9-499E-B1E6-93B6B0AC62DA}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Microsoft.Examples
- SwaggerWebApiSample
- v4.6
- true
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
- bin\SwaggerWebApiSample.xml
-
-
- true
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
- bin\SwaggerWebApiSample.xml
-
-
-
- ..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
-
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
-
-
- ..\..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
-
-
- ..\..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
-
-
- ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
- ..\..\..\packages\Swashbuckle.Core.5.5.3\lib\net40\Swashbuckle.Core.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.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {91e1f0b5-905d-446c-a2dd-4c1edabfaf6c}
- Microsoft.AspNet.WebApi.Versioning.ApiExplorer
-
-
- {3bac97ed-1a8e-4f5a-a716-db5255f51c81}
- Microsoft.AspNet.WebApi.Versioning
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 15721
- /
- http://localhost:15721/
- False
- False
-
-
- False
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+ Exe
+ net461
+ Microsoft.Examples
+ bin\$(Configuration)\$(TargetFramework)\$(MSBuildThisFileName).xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/Web.Debug.config b/samples/webapi/SwaggerWebApiSample/Web.Debug.config
deleted file mode 100644
index fae9cfef..00000000
--- a/samples/webapi/SwaggerWebApiSample/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/Web.Release.config b/samples/webapi/SwaggerWebApiSample/Web.Release.config
deleted file mode 100644
index da6e960b..00000000
--- a/samples/webapi/SwaggerWebApiSample/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/Web.config b/samples/webapi/SwaggerWebApiSample/Web.config
deleted file mode 100644
index 809d891e..00000000
--- a/samples/webapi/SwaggerWebApiSample/Web.config
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/SwaggerWebApiSample/packages.config b/samples/webapi/SwaggerWebApiSample/packages.config
deleted file mode 100644
index 7fc093ac..00000000
--- a/samples/webapi/SwaggerWebApiSample/packages.config
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/webapi/directory.build.targets b/samples/webapi/directory.build.targets
deleted file mode 100644
index 50a7388a..00000000
--- a/samples/webapi/directory.build.targets
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Common.OData.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs b/src/Common.OData.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
index 4d722bb9..bf48e1c2 100644
--- a/src/Common.OData.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
+++ b/src/Common.OData.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
@@ -139,23 +139,6 @@ protected virtual ApiParameterDescription NewCountParameter( ODataQueryOptionDes
return NewParameterDescription( GetName( Count ), description, typeof( bool ), defaultValue: false );
}
- static bool IsSupportHttpMethod( string httpMethod )
- {
- Contract.Requires( !string.IsNullOrEmpty( httpMethod ) );
-
- switch ( httpMethod.ToUpperInvariant() )
- {
- // query or function
- case "GET":
-
- // action
- case "POST":
- return true;
- }
-
- return false;
- }
-
string GetName( AllowedQueryOptions option )
{
Contract.Requires( option == Filter || ( option > Filter && option < Supported && ( (int) option % 2 == 0 ) ) );
diff --git a/src/Common.OData.ApiExplorer/AspNet.OData/TypeExtensions.cs b/src/Common.OData.ApiExplorer/AspNet.OData/TypeExtensions.cs
index 5cc96e91..c27d49c7 100644
--- a/src/Common.OData.ApiExplorer/AspNet.OData/TypeExtensions.cs
+++ b/src/Common.OData.ApiExplorer/AspNet.OData/TypeExtensions.cs
@@ -15,7 +15,6 @@
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
- using static System.StringComparison;
#if WEBAPI
using IActionResult = System.Web.Http.IHttpActionResult;
#endif
@@ -26,11 +25,14 @@
public static partial class TypeExtensions
{
static readonly Type VoidType = typeof( void );
- static readonly Type ActionResultType = typeof( IActionResult );
static readonly Type HttpResponseType = typeof( HttpResponseMessage );
static readonly Type IEnumerableOfT = typeof( IEnumerable<> );
static readonly Type ODataValueOfT = typeof( ODataValue<> );
static readonly Type SingleResultOfT = typeof( SingleResult<> );
+ static readonly Type ActionResultType = typeof( IActionResult );
+#if !WEBAPI
+ static readonly Type ActionResultOfT = typeof( ActionResult<> );
+#endif
///
/// Substitutes the specified type, if required.
@@ -157,7 +159,11 @@ internal static Type ExtractInnerType( this Type type )
var typeArg = typeArgs[0];
- if ( typeDef.IsDelta() || typeDef.Equals( ODataValueOfT ) || typeDef.IsActionResult() || typeDef.Equals( SingleResultOfT ) )
+#if WEBAPI
+ if ( typeDef.IsDelta() || typeDef.IsODataValue() || typeDef.IsSingleResult() )
+#else
+ if ( typeDef.IsDelta() || typeDef.IsODataValue() || typeDef.IsSingleResult() || typeDef.IsActionResult() )
+#endif
{
return typeArg;
}
@@ -189,7 +195,11 @@ static bool IsSubstitutableGeneric( Type type, Stack openTypes, out Type i
var typeArg = typeArgs[0];
- if ( typeDef.Equals( IEnumerableOfT ) || typeDef.IsDelta() || typeDef.Equals( ODataValueOfT ) || typeDef.IsActionResult() || typeDef.Equals( SingleResultOfT ) )
+#if WEBAPI
+ if ( typeDef.Equals( IEnumerableOfT ) || typeDef.IsDelta() || typeDef.IsODataValue() || typeDef.IsSingleResult() )
+#else
+ if ( typeDef.Equals( IEnumerableOfT ) || typeDef.IsDelta() || typeDef.IsODataValue() || typeDef.IsSingleResult() || typeDef.IsActionResult() )
+#endif
{
innerType = typeArg;
}
@@ -284,12 +294,18 @@ internal static bool IsEnumerable( this Type type, out Type itemType )
return false;
}
- static bool IsActionResult( this Type type ) =>
- type.IsGenericType &&
- type.GetGenericTypeDefinition().FullName.Equals( "Microsoft.AspNetCore.Mvc.ActionResult`1", Ordinal );
+ static bool IsSingleResult( this Type type ) => type.Is( SingleResultOfT );
+
+ static bool IsODataValue( this Type type ) => type.Is( ODataValueOfT );
- static bool IsSingleResult( this Type type ) => SingleResultOfT.IsAssignableFrom( type );
+ static bool Is( this Type type, Type typeDefinition ) => type.IsGenericType && type.GetGenericTypeDefinition().Equals( typeDefinition );
+#if WEBAPI
+ static bool ShouldExtractInnerType( this Type type ) => type.IsDelta() || type.IsSingleResult();
+#else
static bool ShouldExtractInnerType( this Type type ) => type.IsDelta() || type.IsSingleResult() || type.IsActionResult();
+
+ static bool IsActionResult( this Type type ) => type.Is( ActionResultOfT );
+#endif
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
index 323f861b..f0858a0e 100644
--- a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
+++ b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/AspNet.OData/Builder/ODataValidationSettingsConvention.cs
@@ -1,6 +1,7 @@
namespace Microsoft.AspNet.OData.Builder
{
using Microsoft.AspNet.OData.Extensions;
+ using Microsoft.OData.Edm;
using System;
using System.Diagnostics.Contracts;
using System.Web.Http.Controllers;
@@ -18,7 +19,7 @@ public virtual void ApplyTo( ApiDescription apiDescription )
{
Arg.NotNull( apiDescription, nameof( apiDescription ) );
- if ( !IsSupportHttpMethod( apiDescription.HttpMethod.Method ) )
+ if ( !IsSupported( apiDescription ) )
{
return;
}
@@ -136,5 +137,22 @@ static ApiParameterDescription SetAction( ApiParameterDescription parameter, Htt
return parameter;
}
+
+ static bool IsSupported( ApiDescription apiDescription )
+ {
+ Contract.Requires( apiDescription != null );
+
+ switch ( apiDescription.HttpMethod.Method.ToUpperInvariant() )
+ {
+ case "GET":
+ // query or function
+ return true;
+ case "POST":
+ // action
+ return apiDescription.Operation()?.IsAction() == true;
+ }
+
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/System.Web.Http/Description/ApiDescriptionExtensions.cs b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/System.Web.Http/Description/ApiDescriptionExtensions.cs
index d5f15257..30cc7af3 100644
--- a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/System.Web.Http/Description/ApiDescriptionExtensions.cs
+++ b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/System.Web.Http/Description/ApiDescriptionExtensions.cs
@@ -72,5 +72,22 @@ public static IEdmEntityType EntityType( this ApiDescription apiDescription )
Arg.NotNull( apiDescription, nameof( apiDescription ) );
return apiDescription.EntitySet()?.EntityType();
}
+
+ ///
+ /// Gets the operation associated with the API description.
+ ///
+ /// The API description to get the operation for.
+ /// The associated EDM operation or null if there is no associated operation.
+ public static IEdmOperation Operation( this ApiDescription apiDescription )
+ {
+ Arg.NotNull( apiDescription, nameof( apiDescription ) );
+
+ if ( apiDescription is VersionedApiDescription description )
+ {
+ return description.GetProperty();
+ }
+
+ return default;
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/Web.Http.Description/ODataApiExplorer.cs b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/Web.Http.Description/ODataApiExplorer.cs
index c0a1c3f9..33c1153f 100644
--- a/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/Web.Http.Description/ODataApiExplorer.cs
+++ b/src/Microsoft.AspNet.OData.Versioning.ApiExplorer/Web.Http.Description/ODataApiExplorer.cs
@@ -461,6 +461,16 @@ void PopulateActionDescriptions(
Properties = { [typeof( IEdmModel )] = routeBuilderContext.EdmModel },
};
+ if ( routeBuilderContext.EntitySet != null )
+ {
+ apiDescription.Properties[typeof( IEdmEntitySet )] = routeBuilderContext.EntitySet;
+ }
+
+ if ( routeBuilderContext.Operation != null )
+ {
+ apiDescription.Properties[typeof( IEdmOperation )] = routeBuilderContext.Operation;
+ }
+
apiDescription.ParameterDescriptions.AddRange( routeBuilderContext.ParameterDescriptions );
apiDescription.SupportedRequestBodyFormatters.AddRange( requestFormatters );
apiDescription.SupportedResponseFormatters.AddRange( responseFormatters );
diff --git a/src/Microsoft.AspNet.WebApi.Versioning/Dispatcher/HttpResponseExceptionFactory.cs b/src/Microsoft.AspNet.WebApi.Versioning/Dispatcher/HttpResponseExceptionFactory.cs
index 32f50a0e..e47c9fae 100644
--- a/src/Microsoft.AspNet.WebApi.Versioning/Dispatcher/HttpResponseExceptionFactory.cs
+++ b/src/Microsoft.AspNet.WebApi.Versioning/Dispatcher/HttpResponseExceptionFactory.cs
@@ -1,5 +1,6 @@
namespace Microsoft.Web.Http.Dispatcher
{
+ using Microsoft.Web.Http.Versioning;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@@ -9,7 +10,6 @@
using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Http.Tracing;
- using Microsoft.Web.Http.Versioning;
using static ApiVersion;
using static System.Net.HttpStatusCode;
using static System.String;
diff --git a/src/Microsoft.AspNet.WebApi.Versioning/Routing/ApiVersionRouteConstraint.cs b/src/Microsoft.AspNet.WebApi.Versioning/Routing/ApiVersionRouteConstraint.cs
index 4de0dd9f..9709ddb2 100644
--- a/src/Microsoft.AspNet.WebApi.Versioning/Routing/ApiVersionRouteConstraint.cs
+++ b/src/Microsoft.AspNet.WebApi.Versioning/Routing/ApiVersionRouteConstraint.cs
@@ -29,13 +29,7 @@ public bool Match( HttpRequestMessage request, IHttpRoute route, string paramete
return false;
}
- var properties = request.ApiVersionProperties();
-
- if ( values.TryGetValue( parameterName, out string value ) )
- {
- properties.RawRequestedApiVersion = value;
- }
- else
+ if ( !values.TryGetValue( parameterName, out string value ) )
{
return false;
}
@@ -45,6 +39,10 @@ public bool Match( HttpRequestMessage request, IHttpRoute route, string paramete
return !IsNullOrEmpty( value );
}
+ var properties = request.ApiVersionProperties();
+
+ properties.RawRequestedApiVersion = value;
+
if ( TryParse( value, out var requestedVersion ) )
{
properties.RequestedApiVersion = requestedVersion;
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ApiVersionParameterDescriptionContext.cs b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ApiVersionParameterDescriptionContext.cs
index c5d4b6ab..acecb453 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ApiVersionParameterDescriptionContext.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ApiVersionParameterDescriptionContext.cs
@@ -1,7 +1,6 @@
namespace Microsoft.AspNetCore.Mvc.ApiExplorer
{
using Microsoft.AspNetCore.Mvc.Abstractions;
- using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.Versioning;
@@ -158,7 +157,7 @@ protected virtual void AddHeader( string name )
}
///
- /// Adds the description for an API version expressed as a header.
+ /// Adds the description for an API version expressed as a route parameter in a URL segment.
///
protected virtual void UpdateUrlSegment()
{
@@ -175,10 +174,22 @@ where constraints.OfType().Any()
return;
}
+ parameter.IsRequired = true;
+ parameter.DefaultValue = ApiVersion.ToString();
parameter.ModelMetadata = ModelMetadata;
parameter.Type = ModelMetadata.ModelType;
parameter.RouteInfo.IsOptional = false;
- parameter.RouteInfo.DefaultValue = ApiVersion.ToString();
+ parameter.RouteInfo.DefaultValue = parameter.DefaultValue;
+
+ if ( parameter.ParameterDescriptor == null )
+ {
+ parameter.ParameterDescriptor = new ParameterDescriptor()
+ {
+ Name = parameter.Name,
+ ParameterType = typeof( ApiVersion ),
+ };
+ }
+
RemoveAllParametersExcept( parameter );
}
@@ -239,17 +250,29 @@ ApiParameterDescription NewApiVersionParameter( string name, BindingSource sourc
var parameter = new ApiParameterDescription()
{
- Name = name,
+ DefaultValue = ApiVersion.ToString(),
+ IsRequired = !optional,
ModelMetadata = ModelMetadata,
- Source = source,
- RouteInfo = new ApiParameterRouteInfo()
+ Name = name,
+ ParameterDescriptor = new ParameterDescriptor()
{
- DefaultValue = ApiVersion.ToString(),
- IsOptional = optional,
+ Name = name,
+ ParameterType = typeof( ApiVersion ),
},
+ Source = source,
Type = ModelMetadata.ModelType,
};
+ if ( source == BindingSource.Path )
+ {
+ parameter.IsRequired = true;
+ parameter.RouteInfo = new ApiParameterRouteInfo()
+ {
+ DefaultValue = ApiVersion.ToString(),
+ IsOptional = false,
+ };
+ }
+
optional = true;
parameters.Add( parameter );
@@ -258,7 +281,7 @@ ApiParameterDescription NewApiVersionParameter( string name, BindingSource sourc
void RemoveAllParametersExcept( ApiParameterDescription parameter )
{
- // note: in a scenario where multiple api version parameters are allowed, we can remove all other parameters because
+ // in a scenario where multiple api version parameters are allowed, we can remove all other parameters because
// the api version must be specified in the path. this will avoid unwanted, duplicate api version parameters
var collections = new ICollection[] { ApiDescription.ParameterDescriptions, parameters };
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer.csproj b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer.csproj
index d0dfb35e..5f12a5d2 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer.csproj
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer.csproj
@@ -1,8 +1,8 @@
- 3.0.0
- 3.0.0.0
+ 3.1.0
+ 3.1.0.0
netstandard2.0
2.0.0-*
2.0.0-*
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ReleaseNotes.txt b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ReleaseNotes.txt
index 5f282702..5e27ff88 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ReleaseNotes.txt
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer/ReleaseNotes.txt
@@ -1 +1 @@
-
\ No newline at end of file
+Support exploring default parameters values (#414)
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Abstractions/ActionDescriptorExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Abstractions/ActionDescriptorExtensions.cs
index fc7bf834..651ea560 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Abstractions/ActionDescriptorExtensions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Abstractions/ActionDescriptorExtensions.cs
@@ -1,10 +1,12 @@
namespace Microsoft.AspNetCore.Mvc.Abstractions
{
using Microsoft.AspNetCore.Mvc.ApplicationModels;
+ using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Versioning;
using System;
using System.Diagnostics.Contracts;
using System.Linq;
+ using System.Text;
using static Microsoft.AspNetCore.Mvc.Versioning.ApiVersionMapping;
using static System.Linq.Enumerable;
@@ -101,5 +103,47 @@ public static bool IsMappedTo( this ActionDescriptor action, ApiVersion apiVersi
Arg.NotNull( action, nameof( action ) );
return action.MappingTo( apiVersion ) > None;
}
+
+ internal static string ExpandSignature( this ActionDescriptor action )
+ {
+ Contract.Requires( action != null );
+ Contract.Ensures( !string.IsNullOrEmpty( Contract.Result() ) );
+
+ if ( !( action is ControllerActionDescriptor controllerAction ) )
+ {
+ return action.DisplayName;
+ }
+
+ var signature = new StringBuilder();
+ var controllerType = controllerAction.ControllerTypeInfo;
+
+ signature.Append( controllerType.GetTypeDisplayName() );
+ signature.Append( '.' );
+ signature.Append( controllerAction.MethodInfo.Name );
+ signature.Append( '(' );
+
+ using ( var parameter = action.Parameters.GetEnumerator() )
+ {
+ if ( parameter.MoveNext() )
+ {
+ var parameterType = parameter.Current.ParameterType;
+
+ signature.Append( parameterType.GetTypeDisplayName( false ) );
+
+ while ( parameter.MoveNext() )
+ {
+ parameterType = parameter.Current.ParameterType;
+ signature.Append( ", " );
+ signature.Append( parameterType.GetTypeDisplayName( false ) );
+ }
+ }
+ }
+
+ signature.Append( ") (" );
+ signature.Append( controllerType.Assembly.GetName().Name );
+ signature.Append( ')' );
+
+ return signature.ToString();
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/ApiBehaviorSpecification.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/ApiBehaviorSpecification.cs
new file mode 100644
index 00000000..9ba4f128
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/ApiBehaviorSpecification.cs
@@ -0,0 +1,34 @@
+namespace Microsoft.AspNetCore.Mvc.ApplicationModels
+{
+ using System;
+ using System.Linq;
+ using System.Reflection;
+
+ ///
+ /// Represents a specification that matches API controllers by the presence of API behaviors.
+ ///
+ [CLSCompliant( false )]
+ public sealed class ApiBehaviorSpecification : IApiControllerSpecification
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ApiBehaviorSpecification()
+ {
+ const string ApiBehaviorApplicationModelProviderTypeName = "Microsoft.AspNetCore.Mvc.ApplicationModels.ApiBehaviorApplicationModelProvider, Microsoft.AspNetCore.Mvc.Core";
+ var type = Type.GetType( ApiBehaviorApplicationModelProviderTypeName, throwOnError: true );
+ var method = type.GetRuntimeMethods().Single( m => m.Name == "IsApiController" );
+
+ IsApiController = (Func) method.CreateDelegate( typeof( Func ) );
+ }
+
+ Func IsApiController { get; }
+
+ ///
+ public bool IsSatisfiedBy( ControllerModel controller )
+ {
+ Arg.NotNull( controller, nameof( controller ) );
+ return IsApiController( controller );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/DefaultApiControllerFilter.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/DefaultApiControllerFilter.cs
new file mode 100644
index 00000000..75e350f5
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/DefaultApiControllerFilter.cs
@@ -0,0 +1,67 @@
+namespace Microsoft.AspNetCore.Mvc.ApplicationModels
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+
+ ///
+ /// Represents the default API controller filter.
+ ///
+ [CLSCompliant( false )]
+ public sealed class DefaultApiControllerFilter : IApiControllerFilter
+ {
+ readonly IReadOnlyList specifications;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The sequence of
+ /// specifications used by the filter
+ /// to identify API controllers.
+ public DefaultApiControllerFilter( IEnumerable specifications )
+ {
+ Arg.NotNull( specifications, nameof( specifications ) );
+ this.specifications = specifications.ToArray();
+ }
+
+ ///
+ public IList Apply( IList controllers )
+ {
+ Arg.NotNull( controllers, nameof( controllers ) );
+ Contract.Ensures( Contract.Result>() != null );
+
+ if ( specifications.Count == 0 )
+ {
+ return controllers;
+ }
+
+ var filtered = controllers.ToList();
+
+ for ( var i = filtered.Count - 1; i >= 0; i-- )
+ {
+ if ( !IsApiController( filtered[i] ) )
+ {
+ filtered.RemoveAt( i );
+ }
+ }
+
+ return filtered;
+ }
+
+ bool IsApiController( ControllerModel controller )
+ {
+ Contract.Requires( controller != null );
+
+ for ( var i = 0; i < specifications.Count; i++ )
+ {
+ if ( specifications[i].IsSatisfiedBy( controller ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerFilter.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerFilter.cs
new file mode 100644
index 00000000..eda2a5dd
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerFilter.cs
@@ -0,0 +1,21 @@
+namespace Microsoft.AspNetCore.Mvc.ApplicationModels
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Defines the behavior of an API controller filter.
+ ///
+ [CLSCompliant( false )]
+ public interface IApiControllerFilter
+ {
+ ///
+ /// Applies the filter to the provided list of controllers.
+ ///
+ /// The list of
+ /// controllers to filter.
+ /// A new, filtered list of API
+ /// controllers.
+ IList Apply( IList controllers );
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerSpecification.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerSpecification.cs
new file mode 100644
index 00000000..9142ae7e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/ApplicationModels/IApiControllerSpecification.cs
@@ -0,0 +1,18 @@
+namespace Microsoft.AspNetCore.Mvc.ApplicationModels
+{
+ using System;
+
+ ///
+ /// Defines the behavior of an API controller specification.
+ ///
+ [CLSCompliant( false )]
+ public interface IApiControllerSpecification
+ {
+ ///
+ /// Determines whether the specification is satisified by the provided controller model.
+ ///
+ /// The controller model to evaluate.
+ /// True if the satisifies the specification; otherwise, false.
+ bool IsSatisfiedBy( ControllerModel controller );
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.AspNetCore.Mvc.Versioning.csproj b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.AspNetCore.Mvc.Versioning.csproj
index 9335d10b..0a9ae1c6 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.AspNetCore.Mvc.Versioning.csproj
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.AspNetCore.Mvc.Versioning.csproj
@@ -1,8 +1,8 @@
- 3.0.0
- 3.0.0.0
+ 3.1.0
+ 3.1.0.0
netstandard2.0
2.0.0-*
2.0.0-*
@@ -13,7 +13,7 @@
-
+
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/AutoRegisterMiddleware.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/AutoRegisterMiddleware.cs
index 11cec8d4..be3bde0f 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/AutoRegisterMiddleware.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/AutoRegisterMiddleware.cs
@@ -2,6 +2,7 @@
{
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.Extensions.Options;
@@ -12,14 +13,20 @@ sealed class AutoRegisterMiddleware : IStartupFilter
{
readonly IApiVersionRoutePolicy routePolicy;
readonly IOptions options;
+ readonly IOptions mvcOptions;
- public AutoRegisterMiddleware( IApiVersionRoutePolicy routePolicy, IOptions options )
+ public AutoRegisterMiddleware(
+ IApiVersionRoutePolicy routePolicy,
+ IOptions options,
+ IOptions mvcOptions )
{
Contract.Requires( routePolicy != null );
Contract.Requires( options != null );
+ Contract.Requires( mvcOptions != null );
this.routePolicy = routePolicy;
this.options = options;
+ this.mvcOptions = mvcOptions;
}
public Action Configure( Action next )
@@ -35,7 +42,11 @@ public Action Configure( Action next )
}
next( app );
- app.UseRouter( builder => builder.Routes.Add( new CatchAllRouteHandler( routePolicy ) ) );
+
+ if ( !mvcOptions.Value.EnableEndpointRouting )
+ {
+ app.UseRouter( builder => builder.Routes.Add( new CatchAllRouteHandler( routePolicy ) ) );
+ }
};
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/IServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/IServiceCollectionExtensions.cs
index 41e51fca..55164076 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/IServiceCollectionExtensions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Microsoft.Extensions.DependencyInjection/IServiceCollectionExtensions.cs
@@ -60,12 +60,15 @@ static void AddApiVersioningServices( IServiceCollection services )
services.Add( Singleton( sp => sp.GetRequiredService>().Value.ErrorResponses ) );
services.Replace( Singleton() );
services.TryAddSingleton();
+ services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton( OnRequestIReportApiVersions );
services.TryAddEnumerable( Transient, ApiVersioningMvcOptionsSetup>() );
services.TryAddEnumerable( Transient, ApiVersioningRouteOptionsSetup>() );
services.TryAddEnumerable( Transient() );
services.TryAddEnumerable( Transient() );
+ services.TryAddEnumerable( Transient() );
+ services.TryAddEnumerable( Singleton() );
services.AddTransient();
}
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/ReleaseNotes.txt b/src/Microsoft.AspNetCore.Mvc.Versioning/ReleaseNotes.txt
index 5f282702..94e53af6 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/ReleaseNotes.txt
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/ReleaseNotes.txt
@@ -1 +1,4 @@
-
\ No newline at end of file
+Support Endpoint Routing (#413)
+ApiVersioningOptions.UseApiBehavior now defaults to true
+Enhanced API controller filtering with IApiControllerSpecification
+Add ApiBehaviorSpecification to match ApiControllerAttribute
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionMatcherPolicy.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionMatcherPolicy.cs
new file mode 100644
index 00000000..98c487b2
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionMatcherPolicy.cs
@@ -0,0 +1,248 @@
+namespace Microsoft.AspNetCore.Mvc.Routing
+{
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Mvc.Abstractions;
+ using Microsoft.AspNetCore.Mvc.Versioning;
+ using Microsoft.AspNetCore.Routing;
+ using Microsoft.AspNetCore.Routing.Matching;
+ using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Options;
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using static Microsoft.AspNetCore.Mvc.Versioning.ApiVersionMapping;
+ using static Microsoft.AspNetCore.Mvc.Versioning.ErrorCodes;
+ using static System.Threading.Tasks.Task;
+
+ ///
+ /// Represents the endpoint selector policy for API versions.
+ ///
+ [CLSCompliant( false )]
+ public sealed class ApiVersionMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
+ {
+ readonly IOptions options;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The options associated with the action selector.
+ /// The object used to report API versions.
+ /// The factory used to create loggers.
+ public ApiVersionMatcherPolicy(
+ IOptions options,
+ IReportApiVersions reportApiVersions,
+ ILoggerFactory loggerFactory )
+ {
+ Arg.NotNull( options, nameof( options ) );
+ Arg.NotNull( reportApiVersions, nameof( reportApiVersions ) );
+ Arg.NotNull( loggerFactory, nameof( loggerFactory ) );
+
+ this.options = options;
+ ApiVersionReporter = reportApiVersions;
+ Logger = loggerFactory.CreateLogger( GetType() );
+ }
+
+ ///
+ public override int Order => 0;
+
+ ApiVersioningOptions Options => options.Value;
+
+ IApiVersionSelector ApiVersionSelector => Options.ApiVersionSelector;
+
+ IReportApiVersions ApiVersionReporter { get; }
+
+ ILogger Logger { get; }
+
+ ///
+ public bool AppliesToEndpoints( IReadOnlyList endpoints )
+ {
+ Arg.NotNull( endpoints, nameof( endpoints ) );
+
+ for ( var i = 0; i < endpoints.Count; i++ )
+ {
+ var action = endpoints[i].Metadata?.GetMetadata();
+
+ if ( action?.GetProperty() != null )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ public Task ApplyAsync( HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates )
+ {
+ Arg.NotNull( httpContext, nameof( httpContext ) );
+ Arg.NotNull( context, nameof( context ) );
+ Arg.NotNull( candidates, nameof( candidates ) );
+
+ if ( IsRequestedApiVersionAmbiguous( httpContext, context, out var apiVersion ) )
+ {
+ return CompletedTask;
+ }
+
+ if ( apiVersion == null && Options.AssumeDefaultVersionWhenUnspecified )
+ {
+ apiVersion = TrySelectApiVersion( httpContext, candidates );
+ httpContext.Features.Get().RequestedApiVersion = apiVersion;
+ }
+
+ var finalMatches = EvaluateApiVersion( httpContext, candidates, apiVersion );
+
+ if ( finalMatches.Count == 0 )
+ {
+ context.Endpoint = ClientError( httpContext, candidates );
+ }
+ else
+ {
+ for ( var i = 0; i < finalMatches.Count; i++ )
+ {
+ candidates.SetValidity( finalMatches[i].index, true );
+ }
+ }
+
+ return CompletedTask;
+ }
+
+ static IReadOnlyList<(int index, ActionDescriptor action)> EvaluateApiVersion(
+ HttpContext httpContext,
+ CandidateSet candidates,
+ ApiVersion apiVersion )
+ {
+ Contract.Requires( httpContext != null );
+ Contract.Requires( candidates != null );
+ Contract.Ensures( Contract.Result>() != null );
+
+ var bestMatches = new List<(int index, ActionDescriptor action)>();
+ var implicitMatches = new List<(int, ActionDescriptor)>();
+
+ for ( var i = 0; i < candidates.Count; i++ )
+ {
+ if ( !candidates.IsValidCandidate( i ) )
+ {
+ continue;
+ }
+
+ ref var candidate = ref candidates[i];
+ var action = candidate.Endpoint.Metadata?.GetMetadata();
+
+ if ( action == null )
+ {
+ candidates.SetValidity( i, false );
+ continue;
+ }
+
+ switch ( action.MappingTo( apiVersion ) )
+ {
+ case Explicit:
+ bestMatches.Add( (i, action) );
+ break;
+ case Implicit:
+ implicitMatches.Add( (i, action) );
+ break;
+ }
+
+ // perf: always make the candidate invalid so we only need to loop through the
+ // final, best matches for any remaining, valid candidates
+ candidates.SetValidity( i, false );
+ }
+
+ switch ( bestMatches.Count )
+ {
+ case 0:
+ bestMatches.AddRange( implicitMatches );
+ break;
+ case 1:
+ var model = bestMatches[0].action.GetApiVersionModel();
+
+ if ( model.IsApiVersionNeutral )
+ {
+ bestMatches.AddRange( implicitMatches );
+ }
+
+ break;
+ }
+
+ return bestMatches.ToArray();
+ }
+
+ bool IsRequestedApiVersionAmbiguous( HttpContext httpContext, EndpointSelectorContext context, out ApiVersion apiVersion )
+ {
+ Contract.Requires( httpContext != null );
+ Contract.Requires( context != null );
+
+ try
+ {
+ apiVersion = httpContext.GetRequestedApiVersion();
+ }
+ catch ( AmbiguousApiVersionException ex )
+ {
+ Logger.LogInformation( ex.Message );
+ apiVersion = default;
+
+ var handlerContext = new RequestHandlerContext( Options.ErrorResponses )
+ {
+ Code = AmbiguousApiVersion,
+ Message = ex.Message,
+ };
+
+ context.Endpoint = new BadRequestHandler( handlerContext );
+ return true;
+ }
+
+ return false;
+ }
+
+ ApiVersion TrySelectApiVersion( HttpContext httpContext, CandidateSet candidates )
+ {
+ Contract.Requires( httpContext != null );
+ Contract.Requires( candidates != null );
+
+ var models = new List();
+
+ for ( var i = 0; i < candidates.Count; i++ )
+ {
+ ref var candidate = ref candidates[i];
+ var model = candidate.Endpoint.Metadata?.GetMetadata()?.GetApiVersionModel();
+
+ if ( model != null )
+ {
+ models.Add( model );
+ }
+ }
+
+ return ApiVersionSelector.SelectVersion( httpContext.Request, models.Aggregate() );
+ }
+
+ RequestHandler ClientError( HttpContext httpContext, CandidateSet candidateSet )
+ {
+ var candidates = new List( candidateSet.Count );
+
+ for ( var i = 0; i < candidateSet.Count; i++ )
+ {
+ ref var candidate = ref candidateSet[i];
+ var action = candidate.Endpoint.Metadata?.GetMetadata();
+
+ if ( action != null )
+ {
+ candidates.Add( action );
+ }
+ }
+
+ var builder = new ClientErrorBuilder()
+ {
+ Options = Options,
+ ApiVersionReporter = ApiVersionReporter,
+ HttpContext = httpContext,
+ Candidates = candidates,
+ Logger = Logger,
+ };
+
+ return builder.Build();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionRouteConstraint.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionRouteConstraint.cs
index ff821cbc..06978824 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionRouteConstraint.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ApiVersionRouteConstraint.cs
@@ -30,13 +30,7 @@ public bool Match( HttpContext httpContext, IRouter route, string routeKey, Rout
return false;
}
- var feature = httpContext.Features.Get();
-
- if ( values.TryGetValue( routeKey, out string value ) )
- {
- feature.RawRequestedApiVersion = value;
- }
- else
+ if ( !values.TryGetValue( routeKey, out string value ) )
{
return false;
}
@@ -46,6 +40,10 @@ public bool Match( HttpContext httpContext, IRouter route, string routeKey, Rout
return !IsNullOrEmpty( value );
}
+ var feature = httpContext.Features.Get();
+
+ feature.RawRequestedApiVersion = value;
+
if ( TryParse( value, out var requestedVersion ) )
{
feature.RequestedApiVersion = requestedVersion;
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ClientErrorBuilder.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ClientErrorBuilder.cs
new file mode 100644
index 00000000..e9e15e96
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/ClientErrorBuilder.cs
@@ -0,0 +1,178 @@
+namespace Microsoft.AspNetCore.Mvc.Routing
+{
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Http.Extensions;
+ using Microsoft.AspNetCore.Mvc.Abstractions;
+ using Microsoft.AspNetCore.Mvc.Internal;
+ using Microsoft.AspNetCore.Mvc.Versioning;
+ using Microsoft.Extensions.Logging;
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using static Microsoft.AspNetCore.Mvc.ApiVersion;
+ using static Microsoft.AspNetCore.Mvc.Versioning.ErrorCodes;
+ using static System.Environment;
+ using static System.Linq.Enumerable;
+ using static System.String;
+
+ sealed class ClientErrorBuilder
+ {
+ internal ApiVersioningOptions Options { get; set; }
+
+ internal IReportApiVersions ApiVersionReporter { get; set; }
+
+ internal HttpContext HttpContext { get; set; }
+
+ internal IReadOnlyCollection Candidates { get; set; }
+
+ internal ILogger Logger { get; set; }
+
+ IErrorResponseProvider ErrorResponseProvider => Options.ErrorResponses;
+
+ internal RequestHandler Build()
+ {
+ var feature = HttpContext.Features.Get();
+ var request = HttpContext.Request;
+ var method = request.Method;
+ var requestedVersion = feature.RawRequestedApiVersion;
+ var parsedVersion = feature.RequestedApiVersion;
+ var actionNames = new Lazy( () => Join( NewLine, Candidates.Select( a => a.DisplayName ) ) );
+ var allowedMethods = new Lazy>( () => AllowedMethodsFromCandidates( Candidates, parsedVersion ) );
+ var apiVersions = new Lazy( Candidates.Select( a => a.GetApiVersionModel() ).Aggregate );
+ var handlerContext = new RequestHandlerContext( ErrorResponseProvider, ApiVersionReporter, apiVersions );
+ var url = new Uri( request.GetDisplayUrl() ).SafeFullPath();
+
+ if ( parsedVersion == null )
+ {
+ if ( IsNullOrEmpty( requestedVersion ) )
+ {
+ if ( Options.AssumeDefaultVersionWhenUnspecified || Candidates.Any( c => c.GetApiVersionModel().IsApiVersionNeutral ) )
+ {
+ return VersionNeutralUnmatched( handlerContext, url, method, allowedMethods.Value, actionNames.Value );
+ }
+
+ return UnspecifiedApiVersion( handlerContext, actionNames.Value );
+ }
+ else if ( !TryParse( requestedVersion, out parsedVersion ) )
+ {
+ return MalformedApiVersion( handlerContext, url, requestedVersion );
+ }
+ }
+ else if ( IsNullOrEmpty( requestedVersion ) )
+ {
+ return VersionNeutralUnmatched( handlerContext, url, method, allowedMethods.Value, actionNames.Value );
+ }
+ else
+ {
+ requestedVersion = parsedVersion.ToString();
+ }
+
+ return Unmatched( handlerContext, url, method, allowedMethods.Value, actionNames.Value, parsedVersion, requestedVersion );
+ }
+
+ static HashSet AllowedMethodsFromCandidates( IEnumerable candidates, ApiVersion apiVersion )
+ {
+ Contract.Requires( candidates != null );
+ Contract.Ensures( Contract.Result>() != null );
+
+ var httpMethods = new HashSet( StringComparer.OrdinalIgnoreCase );
+
+ foreach ( var candidate in candidates )
+ {
+ if ( candidate.ActionConstraints == null || !candidate.IsMappedTo( apiVersion ) )
+ {
+ continue;
+ }
+
+ foreach ( var constraint in candidate.ActionConstraints.OfType() )
+ {
+ httpMethods.AddRange( constraint.HttpMethods );
+ }
+ }
+
+ return httpMethods;
+ }
+
+ RequestHandler VersionNeutralUnmatched(
+ RequestHandlerContext context,
+ string requestUrl,
+ string method,
+ IReadOnlyCollection allowedMethods,
+ string actionNames )
+ {
+ Contract.Requires( context != null );
+ Contract.Requires( !IsNullOrEmpty( requestUrl ) );
+ Contract.Requires( !IsNullOrEmpty( method ) );
+ Contract.Requires( allowedMethods != null );
+
+ Logger.ApiVersionUnspecified( actionNames );
+ context.Code = UnsupportedApiVersion;
+
+ if ( allowedMethods.Count == 0 || allowedMethods.Contains( method ) )
+ {
+ context.Message = SR.VersionNeutralResourceNotSupported.FormatDefault( requestUrl );
+ return new BadRequestHandler( context );
+ }
+
+ context.Message = SR.VersionNeutralMethodNotSupported.FormatDefault( requestUrl, method );
+ context.AllowedMethods = allowedMethods.ToArray();
+
+ return new MethodNotAllowedHandler( context );
+ }
+
+ RequestHandler UnspecifiedApiVersion( RequestHandlerContext context, string actionNames )
+ {
+ Contract.Requires( context != null );
+
+ Logger.ApiVersionUnspecified( actionNames );
+ context.Code = ApiVersionUnspecified;
+ context.Message = SR.ApiVersionUnspecified;
+
+ return new BadRequestHandler( context );
+ }
+
+ RequestHandler MalformedApiVersion( RequestHandlerContext context, string requestUrl, string requestedVersion )
+ {
+ Contract.Requires( context != null );
+ Contract.Requires( !IsNullOrEmpty( requestUrl ) );
+ Contract.Requires( !IsNullOrEmpty( requestedVersion ) );
+
+ Logger.ApiVersionInvalid( requestedVersion );
+ context.Code = InvalidApiVersion;
+ context.Message = SR.VersionedResourceNotSupported.FormatDefault( requestUrl, requestedVersion );
+
+ return new BadRequestHandler( context );
+ }
+
+ RequestHandler Unmatched(
+ RequestHandlerContext context,
+ string requestUrl,
+ string method,
+ IReadOnlyCollection allowedMethods,
+ string actionNames,
+ ApiVersion parsedVersion,
+ string requestedVersion )
+ {
+ Contract.Requires( context != null );
+ Contract.Requires( !IsNullOrEmpty( requestUrl ) );
+ Contract.Requires( !IsNullOrEmpty( method ) );
+ Contract.Requires( allowedMethods != null );
+ Contract.Requires( parsedVersion != null );
+ Contract.Requires( !IsNullOrEmpty( requestedVersion ) );
+
+ Logger.ApiVersionUnmatched( parsedVersion, actionNames );
+ context.Code = UnsupportedApiVersion;
+
+ if ( allowedMethods.Count == 0 || allowedMethods.Contains( method ) )
+ {
+ context.Message = SR.VersionedResourceNotSupported.FormatDefault( requestUrl, requestedVersion );
+ return new BadRequestHandler( context );
+ }
+
+ context.Message = SR.VersionedMethodNotSupported.FormatDefault( requestUrl, requestedVersion, method );
+ context.AllowedMethods = allowedMethods.ToArray();
+
+ return new MethodNotAllowedHandler( context );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/DefaultApiVersionRoutePolicy.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/DefaultApiVersionRoutePolicy.cs
index 550bb408..2141dcbb 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/DefaultApiVersionRoutePolicy.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Routing/DefaultApiVersionRoutePolicy.cs
@@ -1,21 +1,13 @@
namespace Microsoft.AspNetCore.Mvc.Routing
{
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Abstractions;
- using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
using System.Linq;
- using System.Text;
- using static Microsoft.AspNetCore.Mvc.ApiVersion;
- using static Microsoft.AspNetCore.Mvc.Versioning.ErrorCodes;
using static System.Environment;
using static System.Linq.Enumerable;
using static System.String;
@@ -125,7 +117,25 @@ protected virtual void OnUnmatched( RouteContext context, ActionSelectionResult
Arg.NotNull( context, nameof( context ) );
Arg.NotNull( selectionResult, nameof( selectionResult ) );
- context.Handler = ClientError( context.HttpContext, selectionResult );
+ const RequestHandler NotFound = default;
+ var candidates = selectionResult.CandidateActions;
+ var handler = NotFound;
+
+ if ( candidates.Count > 0 )
+ {
+ var builder = new ClientErrorBuilder()
+ {
+ Options = Options,
+ ApiVersionReporter = ApiVersionReporter,
+ HttpContext = context.HttpContext,
+ Candidates = candidates,
+ Logger = Logger,
+ };
+
+ handler = builder.Build();
+ }
+
+ context.Handler = handler;
}
///
@@ -139,7 +149,7 @@ protected virtual void OnMultipleMatches( RouteContext context, ActionSelectionR
Arg.NotNull( context, nameof( context ) );
Arg.NotNull( selectionResult, nameof( selectionResult ) );
- var actionNames = Join( NewLine, selectionResult.MatchingActions.Select( ExpandActionSignature ) );
+ var actionNames = Join( NewLine, selectionResult.MatchingActions.Select( a => a.ExpandSignature() ) );
Logger.AmbiguousActions( actionNames );
@@ -147,203 +157,5 @@ protected virtual void OnMultipleMatches( RouteContext context, ActionSelectionR
throw new AmbiguousActionException( message );
}
-
- static string ExpandActionSignature( ActionDescriptor match )
- {
- Contract.Requires( match != null );
- Contract.Ensures( !IsNullOrEmpty( Contract.Result() ) );
-
- if ( !( match is ControllerActionDescriptor action ) )
- {
- return match.DisplayName;
- }
-
- var signature = new StringBuilder();
- var controllerType = action.ControllerTypeInfo;
-
- signature.Append( controllerType.GetTypeDisplayName() );
- signature.Append( '.' );
- signature.Append( action.MethodInfo.Name );
- signature.Append( '(' );
-
- using ( var parameter = action.Parameters.GetEnumerator() )
- {
- if ( parameter.MoveNext() )
- {
- var parameterType = parameter.Current.ParameterType;
-
- signature.Append( parameterType.GetTypeDisplayName( false ) );
-
- while ( parameter.MoveNext() )
- {
- parameterType = parameter.Current.ParameterType;
- signature.Append( ", " );
- signature.Append( parameterType.GetTypeDisplayName( false ) );
- }
- }
- }
-
- signature.Append( ") (" );
- signature.Append( controllerType.Assembly.GetName().Name );
- signature.Append( ')' );
-
- return signature.ToString();
- }
-
- RequestHandler ClientError( HttpContext httpContext, ActionSelectionResult selectionResult )
- {
- Contract.Requires( httpContext != null );
- Contract.Requires( selectionResult != null );
-
- const RequestHandler NotFound = default;
- var candidates = selectionResult.CandidateActions;
-
- if ( candidates.Count == 0 )
- {
- return NotFound;
- }
-
- var feature = httpContext.Features.Get();
- var method = httpContext.Request.Method;
- var requestUrl = new Lazy( httpContext.Request.GetDisplayUrl );
- var requestedVersion = feature.RawRequestedApiVersion;
- var parsedVersion = feature.RequestedApiVersion;
- var actionNames = new Lazy( () => Join( NewLine, candidates.Select( a => a.DisplayName ) ) );
- var allowedMethods = new Lazy>( () => AllowedMethodsFromCandidates( candidates, parsedVersion ) );
- var apiVersions = new Lazy( candidates.Select( a => a.GetApiVersionModel() ).Aggregate );
- var handlerContext = new RequestHandlerContext( ErrorResponseProvider, ApiVersionReporter, apiVersions );
- var url = new Uri( requestUrl.Value );
- var safeUrl = url.SafeFullPath();
-
- if ( parsedVersion == null )
- {
- if ( IsNullOrEmpty( requestedVersion ) )
- {
- if ( Options.AssumeDefaultVersionWhenUnspecified || candidates.Any( c => c.GetApiVersionModel().IsApiVersionNeutral ) )
- {
- return VersionNeutralUnmatched( handlerContext, safeUrl, method, allowedMethods.Value, actionNames.Value );
- }
-
- return UnspecifiedApiVersion( handlerContext, actionNames.Value );
- }
- else if ( !TryParse( requestedVersion, out parsedVersion ) )
- {
- return MalformedApiVersion( handlerContext, safeUrl, requestedVersion );
- }
- }
- else if ( IsNullOrEmpty( requestedVersion ) )
- {
- return VersionNeutralUnmatched( handlerContext, safeUrl, method, allowedMethods.Value, actionNames.Value );
- }
- else
- {
- requestedVersion = parsedVersion.ToString();
- }
-
- return Unmatched( handlerContext, safeUrl, method, allowedMethods.Value, actionNames.Value, parsedVersion, requestedVersion );
- }
-
- static HashSet AllowedMethodsFromCandidates( IEnumerable candidates, ApiVersion apiVersion )
- {
- Contract.Requires( candidates != null );
- Contract.Ensures( Contract.Result>() != null );
-
- var httpMethods = new HashSet( StringComparer.OrdinalIgnoreCase );
-
- foreach ( var candidate in candidates )
- {
- if ( candidate.ActionConstraints == null || !candidate.IsMappedTo( apiVersion ) )
- {
- continue;
- }
-
- foreach ( var constraint in candidate.ActionConstraints.OfType() )
- {
- httpMethods.AddRange( constraint.HttpMethods );
- }
- }
-
- return httpMethods;
- }
-
- RequestHandler VersionNeutralUnmatched( RequestHandlerContext context, string requestUrl, string method, IReadOnlyCollection allowedMethods, string actionNames )
- {
- Contract.Requires( context != null );
- Contract.Requires( !IsNullOrEmpty( requestUrl ) );
- Contract.Requires( !IsNullOrEmpty( method ) );
- Contract.Requires( allowedMethods != null );
-
- Logger.ApiVersionUnspecified( actionNames );
- context.Code = UnsupportedApiVersion;
-
- if ( allowedMethods.Count == 0 || allowedMethods.Contains( method ) )
- {
- context.Message = SR.VersionNeutralResourceNotSupported.FormatDefault( requestUrl );
- return new BadRequestHandler( context );
- }
-
- context.Message = SR.VersionNeutralMethodNotSupported.FormatDefault( requestUrl, method );
- context.AllowedMethods = allowedMethods.ToArray();
-
- return new MethodNotAllowedHandler( context );
- }
-
- RequestHandler UnspecifiedApiVersion( RequestHandlerContext context, string actionNames )
- {
- Contract.Requires( context != null );
-
- Logger.ApiVersionUnspecified( actionNames );
-
- context.Code = ApiVersionUnspecified;
- context.Message = SR.ApiVersionUnspecified;
-
- return new BadRequestHandler( context );
- }
-
- RequestHandler MalformedApiVersion( RequestHandlerContext context, string requestUrl, string requestedVersion )
- {
- Contract.Requires( context != null );
- Contract.Requires( !IsNullOrEmpty( requestUrl ) );
- Contract.Requires( !IsNullOrEmpty( requestedVersion ) );
-
- Logger.ApiVersionInvalid( requestedVersion );
-
- context.Code = InvalidApiVersion;
- context.Message = SR.VersionedResourceNotSupported.FormatDefault( requestUrl, requestedVersion );
-
- return new BadRequestHandler( context );
- }
-
- RequestHandler Unmatched(
- RequestHandlerContext context,
- string requestUrl,
- string method,
- IReadOnlyCollection allowedMethods,
- string actionNames,
- ApiVersion parsedVersion,
- string requestedVersion )
- {
- Contract.Requires( context != null );
- Contract.Requires( !IsNullOrEmpty( requestUrl ) );
- Contract.Requires( !IsNullOrEmpty( method ) );
- Contract.Requires( allowedMethods != null );
- Contract.Requires( parsedVersion != null );
- Contract.Requires( !IsNullOrEmpty( requestedVersion ) );
-
- Logger.ApiVersionUnmatched( parsedVersion, actionNames );
-
- context.Code = UnsupportedApiVersion;
-
- if ( allowedMethods.Count == 0 || allowedMethods.Contains( method ) )
- {
- context.Message = SR.VersionedResourceNotSupported.FormatDefault( requestUrl, requestedVersion );
- return new BadRequestHandler( context );
- }
-
- context.Message = SR.VersionedMethodNotSupported.FormatDefault( requestUrl, requestedVersion, method );
- context.AllowedMethods = allowedMethods.ToArray();
-
- return new MethodNotAllowedHandler( context );
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningApplicationModelProvider.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningApplicationModelProvider.cs
index 5cc1236c..3f1675c2 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningApplicationModelProvider.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningApplicationModelProvider.cs
@@ -4,10 +4,7 @@
using Microsoft.AspNetCore.Mvc.Versioning.Conventions;
using Microsoft.Extensions.Options;
using System;
- using System.Collections.Generic;
using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Reflection;
///
/// Represents an application model provider, which
@@ -22,10 +19,14 @@ public class ApiVersioningApplicationModelProvider : IApplicationModelProvider
/// Initializes a new instance of the class.
///
/// The current API versioning options.
- public ApiVersioningApplicationModelProvider( IOptions options )
+ /// The filter used for API controllers.
+ public ApiVersioningApplicationModelProvider( IOptions options, IApiControllerFilter controllerFilter )
{
Arg.NotNull( options, nameof( options ) );
+ Arg.NotNull( controllerFilter, nameof( controllerFilter ) );
+
this.options = options;
+ ControllerFilter = controllerFilter;
}
///
@@ -34,6 +35,12 @@ public ApiVersioningApplicationModelProvider( IOptions opt
/// The current API versioning options.
protected ApiVersioningOptions Options => options.Value;
+ ///
+ /// Gets the filter used for API controllers.
+ ///
+ /// The used to filter API controllers.
+ protected IApiControllerFilter ControllerFilter { get; }
+
///
public int Order { get; protected set; }
@@ -45,7 +52,12 @@ public virtual void OnProvidersExecuted( ApplicationModelProviderContext context
var implicitVersionModel = new ApiVersionModel( Options.DefaultApiVersion );
var conventionBuilder = Options.Conventions;
var application = context.Result;
- var controllers = FilterControllers( application.Controllers );
+ var controllers = application.Controllers;
+
+ if ( Options.UseApiBehavior )
+ {
+ controllers = ControllerFilter.Apply( controllers );
+ }
foreach ( var controller in controllers )
{
@@ -59,37 +71,6 @@ public virtual void OnProvidersExecuted( ApplicationModelProviderContext context
///
public virtual void OnProvidersExecuting( ApplicationModelProviderContext context ) { }
- IEnumerable FilterControllers( IEnumerable controllers )
- {
- Contract.Requires( controllers != null );
- Contract.Ensures( Contract.Result>() != null );
-
- if ( !Options.UseApiBehavior )
- {
- return controllers;
- }
-
- var assembly = typeof( ControllerAttribute ).Assembly;
- var apiBehaviorSupported = assembly.ExportedTypes.Any( t => t.Name == "ApiControllerAttribute" );
-
- return apiBehaviorSupported ? controllers.Where( IsApiController ) : controllers;
- }
-
- static bool IsApiController( ControllerModel controller )
- {
- if ( controller.Attributes.Any( IsApiBehaviorMetadata ) )
- {
- return true;
- }
-
- var controllerAssembly = controller.ControllerType.Assembly;
- var assemblyAttributes = controllerAssembly.GetCustomAttributes();
-
- return assemblyAttributes.Any( IsApiBehaviorMetadata );
- }
-
- static bool IsApiBehaviorMetadata( object attribute ) => attribute.GetType().GetInterfaces().Any( i => i.Name == "IApiBehaviorMetadata" );
-
static bool IsDecoratedWithAttributes( ControllerModel controller )
{
Contract.Requires( controller != null );
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningOptions.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningOptions.cs
index 312eb072..b65fa4e3 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningOptions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/ApiVersioningOptions.cs
@@ -1,6 +1,7 @@
namespace Microsoft.AspNetCore.Mvc.Versioning
{
using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Mvc.ApplicationModels;
///
/// Provides additional implementation specific to ASP.NET Core.
@@ -21,11 +22,11 @@ public partial class ApiVersioningOptions
///
/// Gets or sets a value indicating whether to use web API behaviors.
///
- /// True to use web API behaviors; otherwise, false. The default value is false.
- /// Setting this property to true applies API versioning policies only to controllers that
- /// have the ApiControllerAttribute applied. A value of true is only effective when using ASP.NET Core
- /// 2.1 or above. The default value of false retains backward capability with the existing behaviors
- /// before the API behavior feature was introduced.
- public bool UseApiBehavior { get; set; }
+ /// True to use web API behaviors; otherwise, false. The default value is true.
+ /// When this property is set to true, API versioning policies only apply to controllers
+ /// that remain after the has been applied. When this property is set
+ /// to false, API versioning policies are considers for all controllers. This was default behavior
+ /// behavior in previous versions.
+ public bool UseApiBehavior { get; set; } = true;
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandler.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandler.cs
index 9dff1391..fce2c72d 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandler.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandler.cs
@@ -30,9 +30,20 @@ internal Task ExecuteAsync( HttpContext httpContext )
return result.ExecuteResultAsync( actionContext );
}
-#pragma warning disable CA2225 // Operator overloads have named alternates; intentionally one-way
+#pragma warning disable CA2225 // Operator overloads have named alternates; implicit cast only intended
public static implicit operator RequestDelegate( RequestHandler handler ) =>
handler == null ? default( RequestDelegate ) : handler.ExecuteAsync;
#pragma warning restore CA2225
+
+ public static implicit operator Endpoint( RequestHandler handler ) => handler?.ToEndpoint();
+
+ internal Endpoint ToEndpoint()
+ {
+ var metadata = Context.Metadata == null ?
+ new EndpointMetadataCollection() :
+ new EndpointMetadataCollection( Context.Metadata );
+
+ return new Endpoint( ExecuteAsync, metadata, default );
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandlerContext.cs b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandlerContext.cs
index ccb19653..9196b617 100644
--- a/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandlerContext.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Versioning/Versioning/RequestHandlerContext.cs
@@ -2,6 +2,7 @@
{
using Microsoft.AspNetCore.Http;
using System;
+ using System.Collections.Generic;
using System.Diagnostics.Contracts;
sealed class RequestHandlerContext
@@ -32,6 +33,8 @@ internal RequestHandlerContext(
internal string[] AllowedMethods { get; set; }
+ internal IList