From 3e9dcea390ab64752bf71dfab0a95c019d8b5fdf Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Fri, 3 Apr 2015 11:41:24 -0400 Subject: [PATCH 1/6] Writing web api 2 migration article --- docs/index.rst | 2 +- .../migratingfromwebapi2.rst | 60 ++++++++ .../ProductsApp/App_Start/WebApiConfig.cs | 24 ++++ .../Controllers/ProductsController.cs | 34 +++++ .../WebAPIMigration/ProductsApp/Global.asax | 1 + .../ProductsApp/Global.asax.cs | 17 +++ .../ProductsApp/Models/Product.cs | 11 ++ .../ProductsApp/ProductsApp.csproj | 134 ++++++++++++++++++ .../ProductsApp/Properties/AssemblyInfo.cs | 35 +++++ .../ProductsApp/Web.Debug.config | 30 ++++ .../ProductsApp/Web.Release.config | 31 ++++ .../WebAPIMigration/ProductsApp/Web.config | 21 +++ .../ProductsApp/packages.config | 8 ++ 13 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst create mode 100644 samples/WebAPIMigration/ProductsApp/App_Start/WebApiConfig.cs create mode 100644 samples/WebAPIMigration/ProductsApp/Controllers/ProductsController.cs create mode 100644 samples/WebAPIMigration/ProductsApp/Global.asax create mode 100644 samples/WebAPIMigration/ProductsApp/Global.asax.cs create mode 100644 samples/WebAPIMigration/ProductsApp/Models/Product.cs create mode 100644 samples/WebAPIMigration/ProductsApp/ProductsApp.csproj create mode 100644 samples/WebAPIMigration/ProductsApp/Properties/AssemblyInfo.cs create mode 100644 samples/WebAPIMigration/ProductsApp/Web.Debug.config create mode 100644 samples/WebAPIMigration/ProductsApp/Web.Release.config create mode 100644 samples/WebAPIMigration/ProductsApp/Web.config create mode 100644 samples/WebAPIMigration/ProductsApp/packages.config diff --git a/docs/index.rst b/docs/index.rst index e2aa83bca4e6..61630f146ab0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,7 +29,7 @@ Web API .. toctree:: :maxdepth: 1 - + webapi/migratingfromwebapi2/migratingfromwebapi2 Mobile ------ diff --git a/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst new file mode 100644 index 000000000000..41c0ef1e3cac --- /dev/null +++ b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst @@ -0,0 +1,60 @@ +Migrating From ASP.NET Web API 2 to ASP.NET 5 +============================================= +By `Steve Smith`_ | Originally Published: 1 June 2015 + +.. _`Steve Smith`: Author_ + +ASP.NET Web API 2 was separate from ASP.NET MVC 5, with each using their own libraries for dependency resolution, among other things. In ASP.NET 6, Web API has been merged with MVC, providing a single, consistent way of building web applications. In this article we demonstrate the steps required to migrate from an ASP.NET Web API 2 project to ASP.NET 5. + +This article covers the following topics: + - Review Web API 2 Project + - Create the Destination Project + - Migrate Configuration + - Migrate Models and Controllers + +You can view the finished source from the project created in this article `on GitHub `_. + +Review Web API 2 Project +^^^^^^^^^^^^^^^^^^^^^^^^ + +This article uses the sample project, ProductsApp, created in the article, `Getting Started with ASP.NET Web API 2 (C#) `_ as its starting point. + +In Global.asax.cs, a call is made to WebApiConfig.Register: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsApp/global.asax.cs + :language: c# + :emphasize-lines: 14 + :linenos: + +WebApiConfig is defined in App_Start, and has just one static Register method: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsApp/App_Start/WebApiConfig.cs + :language: c# + :emphasize-lines: 15-20 + :linenos: + +This class configures `attribute routing `_, which isn't actually being used in this project, as well as the routing table that Web API 2 uses. In this case, Web API will expect URLs to match /api/{controller}/{id}, with {id} being optional. + +The ProductsApp project includes just one simple controller, which inherits from ApiController and exposes two methods: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsApp/Controllers/ProductsController.cs + :language: c# + :emphasize-lines: 19,24 + :linenos: + +Finally, the model, Product, used by the ProductsApp, is a simple class: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsApp/Models/Product.cs + :language: c# + :linenos: + +Create the Destination Project +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Summary +^^^^^^^ + +ToDo + +.. include:: /_authors/steve-smith.rst diff --git a/samples/WebAPIMigration/ProductsApp/App_Start/WebApiConfig.cs b/samples/WebAPIMigration/ProductsApp/App_Start/WebApiConfig.cs new file mode 100644 index 000000000000..fce089f9b25a --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/App_Start/WebApiConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; + +namespace ProductsApp +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API configuration and services + + // Web API routes + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/samples/WebAPIMigration/ProductsApp/Controllers/ProductsController.cs b/samples/WebAPIMigration/ProductsApp/Controllers/ProductsController.cs new file mode 100644 index 000000000000..a969883d1da2 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Controllers/ProductsController.cs @@ -0,0 +1,34 @@ +using ProductsApp.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Web.Http; + +namespace ProductsApp.Controllers +{ + public class ProductsController : ApiController + { + Product[] products = new Product[] + { + new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, + new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, + new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } + }; + + public IEnumerable GetAllProducts() + { + return products; + } + + public IHttpActionResult GetProduct(int id) + { + var product = products.FirstOrDefault((p) => p.Id == id); + if (product == null) + { + return NotFound(); + } + return Ok(product); + } + } +} diff --git a/samples/WebAPIMigration/ProductsApp/Global.asax b/samples/WebAPIMigration/ProductsApp/Global.asax new file mode 100644 index 000000000000..4209ae8e8344 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="ProductsApp.WebApiApplication" Language="C#" %> diff --git a/samples/WebAPIMigration/ProductsApp/Global.asax.cs b/samples/WebAPIMigration/ProductsApp/Global.asax.cs new file mode 100644 index 000000000000..55b834904268 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Global.asax.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Routing; + +namespace ProductsApp +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/samples/WebAPIMigration/ProductsApp/Models/Product.cs b/samples/WebAPIMigration/ProductsApp/Models/Product.cs new file mode 100644 index 000000000000..bd08186a50b3 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Models/Product.cs @@ -0,0 +1,11 @@ + +namespace ProductsApp.Models +{ + public class Product + { + public int Id { get; set; } + public string Name { get; set; } + public string Category { get; set; } + public decimal Price { get; set; } + } +} \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj b/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj new file mode 100644 index 000000000000..16fc10dd3846 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj @@ -0,0 +1,134 @@ + + + + + Debug + AnyCPU + + + 2.0 + {8811BC19-201C-4487-A264-C6704D245010} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + ProductsApp + ProductsApp + v4.5 + true + + + + + ..\ + true + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.0.0\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.0.0\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.0.0\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + Global.asax + + + + + + + + Web.config + + + Web.config + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 47503 + / + http://localhost:47503/ + False + False + + + False + + + + + + + \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsApp/Properties/AssemblyInfo.cs b/samples/WebAPIMigration/ProductsApp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000000..fcc92df368fe --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ProductsApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProductsApp")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[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("15c57bd4-a2eb-48c8-89bb-acd56faa7d28")] + +// 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/WebAPIMigration/ProductsApp/Web.Debug.config b/samples/WebAPIMigration/ProductsApp/Web.Debug.config new file mode 100644 index 000000000000..2e302f9f9548 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsApp/Web.Release.config b/samples/WebAPIMigration/ProductsApp/Web.Release.config new file mode 100644 index 000000000000..c35844462ba8 --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsApp/Web.config b/samples/WebAPIMigration/ProductsApp/Web.config new file mode 100644 index 000000000000..dedc07489b3d --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/Web.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/WebAPIMigration/ProductsApp/packages.config b/samples/WebAPIMigration/ProductsApp/packages.config new file mode 100644 index 000000000000..a01820817f1d --- /dev/null +++ b/samples/WebAPIMigration/ProductsApp/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From dd1796f106543f4e9c9762ffde7442d0ca82a3d2 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Fri, 3 Apr 2015 14:03:22 -0400 Subject: [PATCH 2/6] Migrating Web API article complete --- .../_static/add-web-project.png | Bin 0 -> 49826 bytes .../_static/aspnet-5-webapi.png | Bin 0 -> 14551 bytes .../_static/webapimigration-solution.png | Bin 0 -> 18791 bytes .../migratingfromwebapi2.rst | 87 +++++++- .../ProductsApp/ProductsApp.csproj | 31 +-- .../WebAPIMigration/ProductsApp/Web.config | 15 +- .../ProductsApp/packages.config | 10 +- .../Controllers/ProductsController.cs | 32 +++ .../ProductsDnx/Models/Product.cs | 11 + .../ProductsDnx/Project_Readme.html | 204 ------------------ .../WebAPIMigration/ProductsDnx/Startup.cs | 9 + 11 files changed, 174 insertions(+), 225 deletions(-) create mode 100644 docs/webapi/migratingfromwebapi2/_static/add-web-project.png create mode 100644 docs/webapi/migratingfromwebapi2/_static/aspnet-5-webapi.png create mode 100644 docs/webapi/migratingfromwebapi2/_static/webapimigration-solution.png create mode 100644 samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs create mode 100644 samples/WebAPIMigration/ProductsDnx/Models/Product.cs delete mode 100644 samples/WebAPIMigration/ProductsDnx/Project_Readme.html diff --git a/docs/webapi/migratingfromwebapi2/_static/add-web-project.png b/docs/webapi/migratingfromwebapi2/_static/add-web-project.png new file mode 100644 index 0000000000000000000000000000000000000000..bd2c2ffc481711b129f43c6f5b7a997c3f7228bc GIT binary patch literal 49826 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
WH{kgh)tN~|cxTJn{j(2nC+72ng-e#+g7WZOd% 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 b?-AXK*KWfZtEwRC|0<6)AC*0@`s05A2RGYt literal 0 HcmV?d00001 diff --git a/docs/webapi/migratingfromwebapi2/_static/aspnet-5-webapi.png b/docs/webapi/migratingfromwebapi2/_static/aspnet-5-webapi.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd74fe1ab96b95ea295a9ec169453f96045ae88 GIT binary patch literal 14551 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 literal 0 HcmV?d00001 diff --git a/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst index 41c0ef1e3cac..25ca4115c66b 100644 --- a/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst +++ b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst @@ -51,10 +51,95 @@ Finally, the model, Product, used by the ProductsApp, is a simple class: Create the Destination Project ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Using Visual Studio 2015, create a new, empty solution, and add the existing ProductsApp project to it. Then, add a new Web Project to the solution. In this case, I'm naming the new project 'ProductsDnx'. + +.. image:: _static/add-web-project.png + +Next, choose the ASP.NET 5 Web API template project. We will migrate the ProductsApp contents to this new project. + +.. image:: _static/aspnet-5-webapi.png + +Delete the Project_Readme.html file from the new project. You can also delete the Your solution should now look like this: + +.. image:: _static/webapimigration-solution.png + +Migrate Configuration +^^^^^^^^^^^^^^^^^^^^^ + +ASP.NET 5 no longer uses global.asax, web.config, or App_Start folders. Instead, all startup tasks are done in Startup.cs in the root of the project, and static configuration files can be wired up from there if needed. Since Web API is now built into ASP.NET 5, there is less need to configure it. Attribute-based routing is now included by default when UseMvc() is called, and this is how the Web API starter project handles routing. + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Startup.cs + :language: c# + :emphasize-lines: 27 + :linenos: + +If you want to use attribute routing in your project going forward, you don't need to do any additional configuration. You can simply apply the attributes as needed to the API methods or controllers, as is done in the sample ValuesController.cs class that is included in the Web API starter project: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Controllers/ValuesController.cs + :language: c# + :emphasize-lines: 8,12,19,32,38 + :linenos: + +In this case, once we copy ProductsController to the new project, we would simply include the route attribute on the controller: + +.. code-block:: c# + + [Route("api/[controller]")] + +However, if you have a large number of files, or you simply want to configure your routes in one place, rather than on each Controller, you can still configure routing globally. Back in Startup.cs, the UseMvc() call accepts a parameter that defines routing information. You can pass in the same route configuration that was previously defined in WebApiConfig.cs in the old project, like so: + +.. code-block:: c# + + app.UseMvc(routes => + { + routes.MapRoute( + name: "DefaultApi", + template: "api/{controller}/{action}/{id:int?}", + defaults: new { controller = "Products", action = "GetAllProducts" }); + }); + +**Note** `routeTemplate` has been renamed to `template`, and the id parameter has now been marked as being an `int` and option (`?`) without the need for specifying anything in the `defaults` parameter. + +If you are using the `sample project `_, you will need to uncomment the above code block in Startup.cs. + +No additional configuration is required for us to complete the migration. + +Migrate Models and Controllers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The last step in the migration process for this simple Web API project is to copy over the Controllers and any Models they use. In this case, simply copy Controllers/ProductsController.cs from the original project to the new one. Then, copy the entire Models folder from the original project to the new one. Adjust the namespaces to match the new project name (`ProductsDnx`). At this point, you can build the application, and you will find a number of compilation errors. These should generally fall into three categories: + + - `ApiController` does not exist + - `System.Web.Http` namespace does not exist + - `IHttpActionResult` does not exist + - `NotFound` does not exist + - `Ok` does not exist + +Fortunately, these are all very easy to correct: + + - Change `ApiController` to `Controller` (you may need to add `using Microsoft.AspNet.Mvc`) + - Delete any using statement referring to `System.Web.Http` + - Change any method returning `IHttpActionResult` to return a `IActionResult` + - Change `NotFound` to `HttpNotFound` + - Change `Ok(product)` to `new ObjectResult(product)` + +Once these changes have been made and unused using statements removed, the migrated ProductsController class looks like this: + +.. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs + :language: c# + :emphasize-lines: 1,2,6,8,22,27,29 + :linenos: + +You should now be able to run the migrated project and browse to /api/products, and you should see the full list of 3 products. Summary ^^^^^^^ -ToDo +Migrating a simple Web API 2 project to ASP.NET 5 is fairly straightforward, thanks to the fact that Web API has been merged with MVC in ASP.NET 5. The main pieces every Web API 2 project will need to migrate are routes, controllers, and models, along with updates to the types used by ASP.NET 5 controllers and actions. + +Related Resources +^^^^^^^^^^^^^^^^^ + +`Create a Web API in MVC 6 `_ .. include:: /_authors/steve-smith.rst diff --git a/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj b/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj index 16fc10dd3846..034246b0b891 100644 --- a/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj +++ b/samples/WebAPIMigration/ProductsApp/ProductsApp.csproj @@ -21,6 +21,7 @@ ..\ true + true @@ -41,7 +42,15 @@ + + ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll + True + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + True + @@ -51,6 +60,14 @@ + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + True + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + True + @@ -59,20 +76,6 @@ - - - ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Microsoft.AspNet.WebApi.Client.5.0.0\lib\net45\System.Net.Http.Formatting.dll - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.0.0\lib\net45\System.Web.Http.dll - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.0.0\lib\net45\System.Web.Http.WebHost.dll - - diff --git a/samples/WebAPIMigration/ProductsApp/Web.config b/samples/WebAPIMigration/ProductsApp/Web.config index dedc07489b3d..3063931e0364 100644 --- a/samples/WebAPIMigration/ProductsApp/Web.config +++ b/samples/WebAPIMigration/ProductsApp/Web.config @@ -10,7 +10,8 @@ - + + @@ -18,4 +19,16 @@ + + + + + + + + + + + + diff --git a/samples/WebAPIMigration/ProductsApp/packages.config b/samples/WebAPIMigration/ProductsApp/packages.config index a01820817f1d..07a69e35f911 100644 --- a/samples/WebAPIMigration/ProductsApp/packages.config +++ b/samples/WebAPIMigration/ProductsApp/packages.config @@ -1,8 +1,8 @@  - - - - - + + + + + \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs b/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs new file mode 100644 index 000000000000..dec9dfbd0e62 --- /dev/null +++ b/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNet.Mvc; +using ProductsDnx.Models; +using System.Collections.Generic; +using System.Linq; + +namespace ProductsDnx.Controllers +{ + public class ProductsController : Controller + { + Product[] products = new Product[] + { + new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, + new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, + new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } + }; + + public IEnumerable GetAllProducts() + { + return products; + } + + public IActionResult GetProduct(int id) + { + var product = products.FirstOrDefault((p) => p.Id == id); + if (product == null) + { + return HttpNotFound(); + } + return new ObjectResult(product); + } + } +} diff --git a/samples/WebAPIMigration/ProductsDnx/Models/Product.cs b/samples/WebAPIMigration/ProductsDnx/Models/Product.cs new file mode 100644 index 000000000000..3b13c07d2da6 --- /dev/null +++ b/samples/WebAPIMigration/ProductsDnx/Models/Product.cs @@ -0,0 +1,11 @@ + +namespace ProductsDnx.Models +{ + public class Product + { + public int Id { get; set; } + public string Name { get; set; } + public string Category { get; set; } + public decimal Price { get; set; } + } +} \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsDnx/Project_Readme.html b/samples/WebAPIMigration/ProductsDnx/Project_Readme.html deleted file mode 100644 index b693be4eba03..000000000000 --- a/samples/WebAPIMigration/ProductsDnx/Project_Readme.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Welcome to ASP.NET 5 - - - - - - - - - - \ No newline at end of file diff --git a/samples/WebAPIMigration/ProductsDnx/Startup.cs b/samples/WebAPIMigration/ProductsDnx/Startup.cs index 8619851b601b..602c646917b5 100644 --- a/samples/WebAPIMigration/ProductsDnx/Startup.cs +++ b/samples/WebAPIMigration/ProductsDnx/Startup.cs @@ -25,6 +25,15 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) app.UseStaticFiles(); // Add MVC to the request pipeline. app.UseMvc(); + + // Add routes from ProductsApp + //app.UseMvc(routes => + //{ + // routes.MapRoute( + // name: "DefaultApi", + // template: "api/{controller}/{action}/{id:int?}", + // defaults: new { controller = "Products", action = "GetAllProducts" }); + //}); } } } From eefa7f3d8dd497728e85658a25fc615f22363be5 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Wed, 8 Apr 2015 11:17:38 -0400 Subject: [PATCH 3/6] Added ref link to application startup --- docs/yourfirst/fundamentalconcepts/fundamentalconcepts.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/yourfirst/fundamentalconcepts/fundamentalconcepts.rst b/docs/yourfirst/fundamentalconcepts/fundamentalconcepts.rst index 9d4ae7f8c7fb..c801f3bd48ff 100644 --- a/docs/yourfirst/fundamentalconcepts/fundamentalconcepts.rst +++ b/docs/yourfirst/fundamentalconcepts/fundamentalconcepts.rst @@ -162,6 +162,7 @@ Run the application and navigate to the About page and you should see the result .. image:: _static/about-page.png .. _Startup.cs: +.. _fundamentalconcepts-application-startup: Application Startup ^^^^^^^^^^^^^^^^^^^ From b125c08c33d6928e4810e35aec4f28fba69969ad Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Wed, 8 Apr 2015 11:19:42 -0400 Subject: [PATCH 4/6] removed route configuration --- samples/WebAPIMigration/ProductsDnx/Startup.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/samples/WebAPIMigration/ProductsDnx/Startup.cs b/samples/WebAPIMigration/ProductsDnx/Startup.cs index 602c646917b5..8619851b601b 100644 --- a/samples/WebAPIMigration/ProductsDnx/Startup.cs +++ b/samples/WebAPIMigration/ProductsDnx/Startup.cs @@ -25,15 +25,6 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) app.UseStaticFiles(); // Add MVC to the request pipeline. app.UseMvc(); - - // Add routes from ProductsApp - //app.UseMvc(routes => - //{ - // routes.MapRoute( - // name: "DefaultApi", - // template: "api/{controller}/{action}/{id:int?}", - // defaults: new { controller = "Products", action = "GetAllProducts" }); - //}); } } } From 8ee5d4218a6689c11550f88d83137da782b40d04 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Wed, 8 Apr 2015 11:19:56 -0400 Subject: [PATCH 5/6] Added proper attribute routing --- .../ProductsDnx/Controllers/ProductsController.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs b/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs index dec9dfbd0e62..e71c950bf92f 100644 --- a/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs +++ b/samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs @@ -5,6 +5,7 @@ namespace ProductsDnx.Controllers { + [Route("api/[controller]")] public class ProductsController : Controller { Product[] products = new Product[] @@ -14,11 +15,15 @@ public class ProductsController : Controller new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } }; + // /api/products + [HttpGet] public IEnumerable GetAllProducts() { return products; } + // /api/products/1 + [HttpGet("{id}")] public IActionResult GetProduct(int id) { var product = products.FirstOrDefault((p) => p.Id == id); From db5ce9d8ded238be9beca342ac56877aec6f1b55 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Wed, 8 Apr 2015 11:20:17 -0400 Subject: [PATCH 6/6] Updated based on @danroth27 feedback --- .../migratingfromwebapi2.rst | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst index 25ca4115c66b..043134e3b966 100644 --- a/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst +++ b/docs/webapi/migratingfromwebapi2/migratingfromwebapi2.rst @@ -1,10 +1,10 @@ -Migrating From ASP.NET Web API 2 to ASP.NET 5 -============================================= +Migrating From ASP.NET Web API 2 to MVC 6 +========================================= By `Steve Smith`_ | Originally Published: 1 June 2015 .. _`Steve Smith`: Author_ -ASP.NET Web API 2 was separate from ASP.NET MVC 5, with each using their own libraries for dependency resolution, among other things. In ASP.NET 6, Web API has been merged with MVC, providing a single, consistent way of building web applications. In this article we demonstrate the steps required to migrate from an ASP.NET Web API 2 project to ASP.NET 5. +ASP.NET Web API 2 was separate from ASP.NET MVC 5, with each using their own libraries for dependency resolution, among other things. In MVC 6, Web API has been merged with MVC, providing a single, consistent way of building web applications. In this article we demonstrate the steps required to migrate from an ASP.NET Web API 2 project to MVC 6. This article covers the following topics: - Review Web API 2 Project @@ -17,7 +17,7 @@ You can view the finished source from the project created in this article `on Gi Review Web API 2 Project ^^^^^^^^^^^^^^^^^^^^^^^^ -This article uses the sample project, ProductsApp, created in the article, `Getting Started with ASP.NET Web API 2 (C#) `_ as its starting point. +This article uses the sample project, ProductsApp, created in the article, `Getting Started with ASP.NET Web API 2 (C#) `_ as its starting point. In that project, a simple Web API 2 project is configured as follows. In Global.asax.cs, a call is made to WebApiConfig.Register: @@ -33,7 +33,7 @@ WebApiConfig is defined in App_Start, and has just one static Register method: :emphasize-lines: 15-20 :linenos: -This class configures `attribute routing `_, which isn't actually being used in this project, as well as the routing table that Web API 2 uses. In this case, Web API will expect URLs to match /api/{controller}/{id}, with {id} being optional. +This class configures `attribute routing `_, although it's not actually being used in the project, as well as the routing table that Web API 2 uses. In this case, Web API will expect URLs to match the format */api/{controller}/{id}*, with *{id}* being optional. The ProductsApp project includes just one simple controller, which inherits from ApiController and exposes two methods: @@ -48,10 +48,12 @@ Finally, the model, Product, used by the ProductsApp, is a simple class: :language: c# :linenos: +Now that we have a simple project from which to start, we can demonstrate how to migrate this Web API 2 project to ASP.NET MVC 6. + Create the Destination Project ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Using Visual Studio 2015, create a new, empty solution, and add the existing ProductsApp project to it. Then, add a new Web Project to the solution. In this case, I'm naming the new project 'ProductsDnx'. +Using Visual Studio 2015, create a new, empty solution, and add the existing ProductsApp project to it. Then, add a new Web Project to the solution. Name the new project 'ProductsDnx'. .. image:: _static/add-web-project.png @@ -59,50 +61,49 @@ Next, choose the ASP.NET 5 Web API template project. We will migrate the Product .. image:: _static/aspnet-5-webapi.png -Delete the Project_Readme.html file from the new project. You can also delete the Your solution should now look like this: +Delete the Project_Readme.html file from the new project. Your solution should now look like this: .. image:: _static/webapimigration-solution.png +.. migrate-webapi-config: + Migrate Configuration ^^^^^^^^^^^^^^^^^^^^^ -ASP.NET 5 no longer uses global.asax, web.config, or App_Start folders. Instead, all startup tasks are done in Startup.cs in the root of the project, and static configuration files can be wired up from there if needed. Since Web API is now built into ASP.NET 5, there is less need to configure it. Attribute-based routing is now included by default when UseMvc() is called, and this is how the Web API starter project handles routing. +ASP.NET 5 no longer uses global.asax, web.config, or App_Start folders. Instead, all startup tasks are done in Startup.cs in the root of the project, and static configuration files can be wired up from there if needed (Learn more about :ref:`ASP.NET 5 Application Startup `). Since Web API is now built into MVC 6, there is less need to configure it. Attribute-based routing is now included by default when UseMvc() is called, and this is the recommended approach for configuring Web API routes (and is how the Web API starter project handles routing). .. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Startup.cs :language: c# :emphasize-lines: 27 :linenos: -If you want to use attribute routing in your project going forward, you don't need to do any additional configuration. You can simply apply the attributes as needed to the API methods or controllers, as is done in the sample ValuesController.cs class that is included in the Web API starter project: +Assuming you want to use attribute routing in your project going forward, you don't need to do any additional configuration. You can simply apply the attributes as needed to your controllers and actions,, as is done in the sample ValuesController.cs class that is included in the Web API starter project: .. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Controllers/ValuesController.cs :language: c# :emphasize-lines: 8,12,19,32,38 :linenos: -In this case, once we copy ProductsController to the new project, we would simply include the route attribute on the controller: +Note the presence of *[controller]* on line 8. Attribute-based routing now supports certain tokens, such as *[controller]* and *[action]* that are replaced at runtime with the name of the controller or action to which the attribute has been applied. This serves to reduce the number of magic strings in the project, and ensures the routes will be kept synchronized with their corresponding controllers and actions when automatic rename refactorings are applied. + +To migrate the Products API controller, we must first copy ProductsController to the new project. Then simply include the route attribute on the controller: .. code-block:: c# [Route("api/[controller]")] -However, if you have a large number of files, or you simply want to configure your routes in one place, rather than on each Controller, you can still configure routing globally. Back in Startup.cs, the UseMvc() call accepts a parameter that defines routing information. You can pass in the same route configuration that was previously defined in WebApiConfig.cs in the old project, like so: - -.. code-block:: c# +You also need to add the [HttpGet] attribute to the two methods, since they both should be called via HTTP Get. Include the expectation of an "id" parameter in the attribute for GetProduct(): - app.UseMvc(routes => - { - routes.MapRoute( - name: "DefaultApi", - template: "api/{controller}/{action}/{id:int?}", - defaults: new { controller = "Products", action = "GetAllProducts" }); - }); - -**Note** `routeTemplate` has been renamed to `template`, and the id parameter has now been marked as being an `int` and option (`?`) without the need for specifying anything in the `defaults` parameter. +.. code-block:: c# -If you are using the `sample project `_, you will need to uncomment the above code block in Startup.cs. + // /api/products + [HttpGet] + ... + + // /api/products/1 + [HttpGet("{id}")] -No additional configuration is required for us to complete the migration. +At this point routing is configured correctly, but we can't yet test it because there are changes we must make before ProductsController will compile. Migrate Models and Controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,15 +128,15 @@ Once these changes have been made and unused using statements removed, the migra .. literalinclude:: ../../../samples/WebAPIMigration/ProductsDnx/Controllers/ProductsController.cs :language: c# - :emphasize-lines: 1,2,6,8,22,27,29 + :emphasize-lines: 1,2,6,8-9,27,32,34 :linenos: -You should now be able to run the migrated project and browse to /api/products, and you should see the full list of 3 products. +You should now be able to run the migrated project and browse to /api/products, and you should see the full list of 3 products. Browse to /api/products/1 and you should see the first product. Summary ^^^^^^^ -Migrating a simple Web API 2 project to ASP.NET 5 is fairly straightforward, thanks to the fact that Web API has been merged with MVC in ASP.NET 5. The main pieces every Web API 2 project will need to migrate are routes, controllers, and models, along with updates to the types used by ASP.NET 5 controllers and actions. +Migrating a simple Web API 2 project to MVC 6 is fairly straightforward, thanks to the fact that Web API has been merged with MVC 6 in ASP.NET 5. The main pieces every Web API 2 project will need to migrate are routes, controllers, and models, along with updates to the types used by MVC 6 controllers and actions. Related Resources ^^^^^^^^^^^^^^^^^