Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
ASP.NET Core combines ASP.NET 4.x's MVC and Web API app models into a single programming model known as ASP.NET Core MVC.
This article shows how to migrate the Products controller created in Getting Started with ASP.NET Web API 2 to ASP.NET Core.
Prerequisites
- Visual Studio 2022 with the ASP.NET and web development workload.
- .NET 6 SDK
Create the new ASP.NET Core Web API project
- From the File menu, select New > Project.
- Enter Web API in the search box.
- Select the ASP.NET Core Web API template and select Next.
- In the Configure your new project dialog, name the project ProductsCore and select Next.
- In the Additional information dialog:
- Confirm the Framework is .NET 6.0 (Long-term support).
- Confirm the checkbox for Use controllers(uncheck to use minimal APIs) is checked.
- Uncheck Enable OpenAPI support.
- Select Create.
Remove the WeatherForecast template files
- Remove the
WeatherForecast.csandControllers/WeatherForecastController.csexample files from the new ProductsCore project. - Open Properties\launchSettings.json.
- Change
launchUrlproperties fromweatherforcasttoproductscore.
The configuration for ASP.NET Core Web API
ASP.NET Core doesn't use the App_Start folder or the Global.asax file. The web.config file is added at publish time. For more information, see web.config file.
The Program.cs file:
- Replaces Global.asax.
- Handles all app startup tasks.
For more information, see App startup in ASP.NET Core.
The following shows the application startup code in the ASP.NET Core Program.cs file:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Copy the Product model
- In Solution Explorer, right-click the project. Select Add > New Folder. Name the folder Models.
- Right-click the Models folder. Select Add > Class. Name the class Product and select Add.
- Replace the template model code with the following:
namespace ProductsCore.Models
{
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Category { get; set; }
public decimal Price { get; set; }
}
}
The preceding highlighted code changes the following:
- The
?annotation has been added to declare theNameandCategoryproperties as nullable reference types.
By utilizing the Nullable feature introduced in C# 8, ASP.NET Core can provide additional code flow analysis and compile-time safety in the handling of reference types. For example, protecting against null reference exceptions.
In this case, the intent is that the Name and Category can be nullable types.
ASP.NET Core in .NET 6 projects enable nullable reference types by default. For more information, see Nullable reference types.
Copy the ProductsController
- Right-click the Controllers folder.
- Select Add > Controller....
- In Add New Scaffolded Item dialog, select Mvc Controller - Empty then select Add.
- Name the controller ProductsController and select Add.
- Replace the template controller code with the following:
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
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
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
The preceding highlighted code changes the following, to migrate to ASP.NET Core:
Removes using statements for the following ASP.NET 4.x components that don't exist in ASP.NET Core:
ApiControllerclassSystem.Web.HttpnamespaceIHttpActionResultinterface
Changes the
using ProductsApp.Models;statement tousing ProductsCore.Models;.Sets the root namespace to
ProductsCore.Changes
ApiControllerto ControllerBase.Adds
using Microsoft.AspNetCore.Mvc;to resolve theControllerBasereference.Changes the
GetProductaction's return type fromIHttpActionResulttoActionResult<Product>. For more info, see Controller action return types.Simplifies the
GetProductaction'sreturnstatement to the following statement:return product;Adds the following attributes which are explained in the next sections:
[Route("api/[controller]")][ApiController][HttpGet][HttpGet("{id}")]
Routing
ASP.NET Core provides a minimal hosting model in which the endpoint routing middleware wraps the entire middleware pipeline, therefore routes can be added directly to the WebApplication without an explicit call to UseEndpoints or UseRouting to register routes.
UseRouting can still be used to specify where route matching happens, but UseRouting doesn't need to be explicitly called if routes should be matched at the beginning of the middleware pipeline.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Note: Routes added directly to the WebApplication execute at the end of the pipeline.
Routing in the migrated ProductsController
The migrated ProductsController contains the following highlighted attributes:
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
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
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
The
[Route]attribute configures the controller's attribute routing pattern.The
[ApiController]attribute makes attribute routing a requirement for all actions in this controller.Attribute routing supports tokens, such as
[controller]and[action]. At runtime, each token is replaced with the name of the controller or action, respectively, to which the attribute has been applied. The tokens:- Reduces or eliminates the need to use hard coded strings for the route.
- Ensure routes remain synchronized with the corresponding controllers and actions when automatic rename refactorings are applied.
HTTP Get requests are enabled for
ProductControlleractions with the following attributes:[HttpGet]attribute applied to theGetAllProductsaction.[HttpGet("{id}")]attribute applied to theGetProductaction.
Run the migrated project, and browse to /api/products. For example: https://localhost:<port>/api/products. A full list of three products appears. Browse to /api/products/1. The first product appears.
View or download sample code (how to download)
Additional resources
This article demonstrates the steps required to migrate from ASP.NET 4.x Web API to ASP.NET Core MVC.
View or download sample code (how to download)
Prerequisites
- Visual Studio 2019 16.4 or later with the ASP.NET and web development workload
- .NET Core 3.1 SDK
Review ASP.NET 4.x Web API project
This article uses the ProductsApp project created in Getting Started with ASP.NET Web API 2. In that project, a basic ASP.NET 4.x Web API project is configured as follows.
In Global.asax.cs, a call is made to WebApiConfig.Register:
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);
}
}
}
The WebApiConfig class is found in the App_Start folder and has a static Register method:
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 }
);
}
}
}
The preceding class:
- Configures attribute routing, although it's not actually being used.
- Configures the routing table.
The sample code expects URLs to match the format
/api/{controller}/{id}, with{id}being optional.
The following sections demonstrate migration of the Web API project to ASP.NET Core MVC.
Create the destination project
Create a new blank solution in Visual Studio and add the ASP.NET 4.x Web API project to migrate:
- From the File menu, select New > Project.
- Select the Blank Solution template and select Next.
- Name the solution WebAPIMigration. Select Create.
- Add the existing ProductsApp project to the solution.
Add a new API project to migrate to:
- Add a new ASP.NET Core Web Application project to the solution.
- In the Configure your new project dialog, Name the project ProductsCore, and select Create.
- In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 3.1 are selected. Select the API project template, and select Create.
- Remove the
WeatherForecast.csandControllers/WeatherForecastController.csexample files from the new ProductsCore project.
The solution now contains two projects. The following sections explain migrating the ProductsApp project's contents to the ProductsCore project.
Migrate configuration
ASP.NET Core doesn't use the App_Start folder or the Global.asax file. Additionally, the web.config file is added at publish time.
The Startup class:
- Replaces Global.asax.
- Handles all app startup tasks.
For more information, see App startup in ASP.NET Core.
Migrate models and controllers
The following code shows the ProductsController to be updated for ASP.NET Core:
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<Product> GetAllProducts()
{
return products;
}
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
Update the ProductsController for ASP.NET Core:
- Copy
Controllers/ProductsController.csand the Models folder from the original project to the new one. - Change the copied files' root namespace to
ProductsCore. - Update the
using ProductsApp.Models;statement tousing ProductsCore.Models;.
The following components don't exist in ASP.NET Core:
ApiControllerclassSystem.Web.HttpnamespaceIHttpActionResultinterface
Make the following changes:
Change
ApiControllerto ControllerBase. Addusing Microsoft.AspNetCore.Mvc;to resolve theControllerBasereference.Delete
using System.Web.Http;.Change the
GetProductaction's return type fromIHttpActionResulttoActionResult<Product>.Simplify the
GetProductaction'sreturnstatement to the following:return product;
Configure routing
The ASP.NET Core API project template includes endpoint routing configuration in the generated code.
The following UseRouting and UseEndpoints calls:
- Register route matching and endpoint execution in the middleware pipeline.
- Replace the ProductsApp project's
App_Start/WebApiConfig.csfile.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Configure routing as follows:
Mark the
ProductsControllerclass with the following attributes:[Route("api/[controller]")] [ApiController]The preceding
[Route]attribute configures the controller's attribute routing pattern. The[ApiController]attribute makes attribute routing a requirement for all actions in this controller.Attribute routing supports tokens, such as
[controller]and[action]. At runtime, each token is replaced with the name of the controller or action, respectively, to which the attribute has been applied. The tokens:- Reduce the number of magic strings in the project.
- Ensure routes remain synchronized with the corresponding controllers and actions when automatic rename refactorings are applied.
Enable HTTP Get requests to the
ProductsControlleractions:- Apply the
[HttpGet]attribute to theGetAllProductsaction. - Apply the
[HttpGet("{id}")]attribute to theGetProductaction.
- Apply the
Run the migrated project, and browse to /api/products. A full list of three products appears. Browse to /api/products/1. The first product appears.
Additional resources
ASP.NET Core