Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
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.
WeatherForecast.cs
and Controllers/WeatherForecastController.cs
example files from the new ProductsCore project.launchUrl
properties from weatherforcast
to productscore
.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:
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();
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:
?
annotation has been added to declare the Name
and Category
properties 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 6.0 projects enable nullable reference types by default. For more information, see Nullable reference types.
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:
ApiController
classSystem.Web.Http
namespaceIHttpActionResult
interfaceChanges the using ProductsApp.Models;
statement to using ProductsCore.Models;
.
Sets the root namespace to ProductsCore
.
Changes ApiController
to ControllerBase.
Adds using Microsoft.AspNetCore.Mvc;
to resolve the ControllerBase
reference.
Changes the GetProduct
action's return type from IHttpActionResult
to ActionResult<Product>
. For more info, see Controller action return types.
Simplifies the GetProduct
action's return
statement to the following statement:
return product;
Adds the following attributes which are explained in the next sections:
[Route("api/[controller]")]
[ApiController]
[HttpGet]
[HttpGet("{id}")]
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.
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:
HTTP Get requests are enabled for ProductController
actions with the following attributes:
[HttpGet]
attribute applied to the GetAllProducts
action.[HttpGet("{id}")]
attribute applied to the GetProduct
action.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.
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)
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:
/api/{controller}/{id}
, with {id}
being optional.The following sections demonstrate migration of the Web API project to ASP.NET Core MVC.
Create a new blank solution in Visual Studio and add the ASP.NET 4.x Web API project to migrate:
Add a new API project to migrate to:
WeatherForecast.cs
and Controllers/WeatherForecastController.cs
example 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.
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:
For more information, see App startup in ASP.NET Core.
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:
Controllers/ProductsController.cs
and the Models folder from the original project to the new one.ProductsCore
.using ProductsApp.Models;
statement to using ProductsCore.Models;
.The following components don't exist in ASP.NET Core:
ApiController
classSystem.Web.Http
namespaceIHttpActionResult
interfaceMake the following changes:
Change ApiController
to ControllerBase. Add using Microsoft.AspNetCore.Mvc;
to resolve the ControllerBase
reference.
Delete using System.Web.Http;
.
Change the GetProduct
action's return type from IHttpActionResult
to ActionResult<Product>
.
Simplify the GetProduct
action's return
statement to the following:
return product;
The ASP.NET Core API project template includes endpoint routing configuration in the generated code.
The following UseRouting and UseEndpoints calls:
App_Start/WebApiConfig.cs
file.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 ProductsController
class 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:
Enable HTTP Get requests to the ProductsController
actions:
[HttpGet]
attribute to the GetAllProducts
action.[HttpGet("{id}")]
attribute to the GetProduct
action.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.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn more