Переход с веб-API ASP.NET на ASP.NET Core

ASP.NET Core объединяет ASP.NET модели MVC и веб-API 4.x в одну модель программирования, известную как ASP.NET Core MVC.

В этой статье показано, как перенести контроллер продуктов, созданный в разделе "Начало работы с веб-API ASP.NET 2 в ASP.NET Core".

Необходимые компоненты

Создание проекта веб-API ASP.NET Core

  1. В меню Файл выберите пункт Создать>Проект.
  2. В поле поиска введите Веб-API.
  3. Выберите шаблон Веб-API ASP.NET Core и нажмите кнопку Далее.
  4. В диалоговом окне "Настройка нового проекта" назовите project ProductsCore и нажмите кнопку "Далее".
  5. В диалоговом окне "Дополнительные сведения":
    1. Убедитесь, что для параметра Платформа выбрано значение .NET 6.0 (долгосрочная поддержка).
    2. Убедитесь, что флажок Use controllers (uncheck to use minimal APIs) (Использовать контроллеры (снимите этот флажок для использования минимальных API)) установлен.
    3. Снимите флажок Включить поддержку OpenAPI.
    4. Выберите Создать.

Удаление файлов шаблонов WeatherForecast

  1. Удалите и Controllers/WeatherForecastController.cs примеры файлов из нового проекта ProductsCore.WeatherForecast.cs
  2. Откройте файл Properties\launchSettings.json.
  3. Изменение launchUrl свойств с weatherforcastproductscore.

Конфигурация веб-API ASP.NET Core

ASP.NET Core не использует папку App_Start или файл Global.asax . Файл web.config добавляется во время публикации. Дополнительные сведения см . в файле web.config.

Файл Program.cs:

  • Заменяет Global.asax.
  • Обрабатывает все задачи запуска приложения.

Подробные сведения см. в статье Запуск приложения в ASP.NET Core.

Ниже показан код запуска приложения в файле ASP.NET Core Program.cs :

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();

Копирование модели продукта

  1. В обозревателе решений щелкните проект правой кнопкой мыши. Выберите Добавить>Новая папка. Присвойте папке имя Models.
  2. Щелкните правой кнопкой мыши папку Models. Выберите Добавить>Класс. Назовите класс Product и нажмите кнопку "Добавить".
  3. Замените код модели шаблона следующим:
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; }
    }
}

Предыдущий выделенный код изменяет следующий код:

  • Заметка ? добавлена для объявления Name ссылочных типов, допускающих значение NULL, и Category свойств.

Используя функцию NULL, представленную в C# 8, ASP.NET Core может обеспечить дополнительный анализ потока кода и безопасность во время компиляции в обработке ссылочных типов. Например, защита от исключений ссылок на null.

В этом случае намерение заключается в том, что Name и Category может быть типы, допускающие значение NULL.

ASP.NET проекты Core 6.0 по умолчанию позволяют использовать ссылочные типы, допускающие значение NULL. Дополнительные сведения см. в статье Ссылочные типы, допускающие значение NULL.

Копирование ProductsController

  1. Щелкните папку Controllers правой кнопкой мыши.
  2. Выберите " Добавить > контроллер...".
  3. В диалоговом окне "Добавить новый шаблон" выберите контроллер Mvc — пустой и нажмите кнопку "Добавить".
  4. Назовите контроллер ProductsController и нажмите кнопку "Добавить".
  5. Замените код контроллера шаблона следующим образом:
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;
    }
}

Предыдущий выделенный код изменяет следующий код, чтобы перейти на ASP.NET Core:

  • Удаляет инструкции using для следующих компонентов ASP.NET 4.x, которые не существуют в ASP.NET Core:

    • Класс ApiController
    • Пространство имен System.Web.Http
    • IHttpActionResult Интерфейс
  • Изменяет инструкцию using ProductsApp.Models;using ProductsCore.Models;на .

  • Задает для корневого пространства имен значение ProductsCore.

  • Изменяет ApiController на ControllerBase.

  • Добавляется using Microsoft.AspNetCore.Mvc; для разрешения ControllerBase ссылки.

  • GetProduct Изменяет возвращаемый тип действия в IHttpActionResultActionResult<Product>. Дополнительные сведения см. в разделе "Возвращаемые типы действий контроллера".

  • Упрощает инструкцию GetProduct действия return до следующей инструкции:

    return product;
    
  • Добавляет следующие атрибуты, которые описаны в следующих разделах:

    • [Route("api/[controller]")]
    • [ApiController]
    • [HttpGet]
    • [HttpGet("{id}")]

Маршрутизация

ASP.NET Core предоставляет минимальную модель размещения, в которой ПО промежуточного слоя маршрутизации конечных точек упаковывает весь конвейер ПО промежуточного слоя, поэтому маршруты можно добавлять непосредственно в WebApplication без явного вызова UseEndpoints или UseRouting регистрации маршрутов.

UseRouting можно использовать для указания того, где происходит сопоставление маршрутов, но UseRouting не требуется явно вызывать, если маршруты должны соответствовать в начале конвейера по промежуточного слоя.

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();

Примечание. Маршруты, добавленные непосредственно в WebApplication выполнение в конце конвейера.

Маршрутизация в перенесенном режиме ProductsController

Перенесенный ProductsController содержит следующие выделенные атрибуты:

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;
    }
}
  • Атрибут [Route] настраивает шаблон маршрутизации атрибутов контроллера.

  • Атрибут [ApiController] делает маршрутизацию атрибутов обязательным для всех действий в этом контроллере.

  • Маршрутизация атрибутов поддерживает маркеры, такие как [controller] и [action]. Во время выполнения каждый маркер заменяется именем контроллера или действия соответственно, к которому был применен атрибут. Маркеры:

    • Уменьшает или устраняет необходимость использования жестко закодированных строк для маршрута.
    • Убедитесь, что маршруты остаются синхронизированными с соответствующими контроллерами и действиями при применении автоматического рефакторинга переименования.
  • Http-запросы get включены для ProductController действий со следующими атрибутами:

    • [HttpGet] атрибут, примененный к GetAllProducts действию.
    • [HttpGet("{id}")] атрибут, примененный к GetProduct действию.

Запустите перенесенный проект и перейдите к /api/productsней. Например: https://localhost:<port>/api/products. Появится полный список трех продуктов. Перейдите в /api/products/1. Появится первый продукт.

Просмотреть или скачать образец кода (описание загрузки)

Дополнительные ресурсы

В этой статье показано, как выполнить миграцию с веб-API ASP.NET 4.x в ASP.NET Core MVC.

Просмотреть или скачать образец кода (описание загрузки)

Необходимые компоненты

Просмотр проекта веб-API ASP.NET версии 4.x

В этой статье используется проект ProductsApp, созданный в разделе "Начало работы с веб-API ASP.NET 2". В этом проекте базовый проект веб-API ASP.NET 4.x настраивается следующим образом.

В Global.asax.cs, вызов выполняется для 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);
        }
    }
}

Класс WebApiConfig найден в папке App_Start и имеет статический Register метод:

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 }
            );
        }
    }
}

Предыдущий класс :

  • Настраивает маршрутизацию атрибутов, хотя она не используется.
  • Настраивает таблицу маршрутизации. Пример кода ожидает, что URL-адреса соответствуют формату /api/{controller}/{id}, при этом {id} необязательно.

В следующих разделах демонстрируется перенос проекта веб-API на ASP.NET Core MVC.

Создание целевого проекта

Создайте пустое решение в Visual Studio и добавьте проект веб-API ASP.NET 4.x для миграции:

  1. В меню Файл выберите пункт Создать>Проект.
  2. Выберите шаблон "Пустое решение " и нажмите кнопку "Далее".
  3. Назовите решение WebAPIMigration. Выберите Создать.
  4. Добавьте существующий проект ProductsApp в решение.

Добавьте новый проект API для миграции в:

  1. Добавьте в решение новый проект веб-приложения ASP.NET Core.
  2. В диалоговом окне "Настройка нового проекта" назовите project ProductsCore и нажмите кнопку "Создать".
  3. В диалоговом окне Создание веб-приложения ASP.NET Core убедитесь в том, что выбраны платформы .NET Core и ASP.NET Core 3.1. Выберите шаблон проекта API и нажмите кнопку Создать.
  4. Удалите и Controllers/WeatherForecastController.cs примеры файлов из нового проекта ProductsCore.WeatherForecast.cs

Теперь решение содержит два проекта. В следующих разделах объясняется, как перенести содержимое проекта ProductsApp в проект ProductsCore .

Миграция конфигурации

ASP.NET Core не использует папку App_Start или файл Global.asax . Кроме того, файл web.config добавляется во время публикации.

Класс Startup:

  • Заменяет Global.asax.
  • Обрабатывает все задачи запуска приложения.

Подробные сведения см. в статье Запуск приложения в ASP.NET Core.

Перенос моделей и контроллеров

В следующем коде ProductsController показано обновление для 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);
        }
    }
}

ProductsController Обновите ASP.NET Core:

  1. Скопируйте Controllers/ProductsController.cs и папку Models из исходного проекта в новую.
  2. Измените корневое пространство ProductsCoreимен скопированных файлов на .
  3. Обновите инструкцию using ProductsApp.Models;using ProductsCore.Models;до .

Следующие компоненты не существуют в ASP.NET Core:

  • Класс ApiController
  • Пространство имен System.Web.Http
  • IHttpActionResult Интерфейс

Внесите следующие изменения:

  1. Измените ApiController на ControllerBase. Добавьте using Microsoft.AspNetCore.Mvc; для разрешения ControllerBase ссылки.

  2. Удалите using System.Web.Http;.

  3. Измените GetProduct тип возвращаемого действия на IHttpActionResultActionResult<Product>.

  4. Упростите инструкцию GetProduct действия return следующим образом:

    return product;
    

Настройка маршрутизации

Шаблон проекта API ASP.NET Core включает конфигурацию маршрутизации конечных точек в созданный код.

UseRouting Следующие и UseEndpoints вызовы:

  • Зарегистрируйте сопоставление маршрутов и выполнение конечной точки в конвейере ПО промежуточного слоя .
  • Замените файл проекта App_Start/WebApiConfig.cs ProductsApp.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Настройте маршрутизацию следующим образом:

  1. ProductsController Пометьте класс следующими атрибутами:

    [Route("api/[controller]")]
    [ApiController]
    

    [Route] Предыдущий атрибут настраивает шаблон маршрутизации атрибутов контроллера. Атрибут [ApiController] делает маршрутизацию атрибутов обязательным для всех действий в этом контроллере.

    Маршрутизация атрибутов поддерживает маркеры, такие как [controller] и [action]. Во время выполнения каждый маркер заменяется именем контроллера или действия соответственно, к которому был применен атрибут. Маркеры:

    • Уменьшите количество магических строк в проекте.
    • Убедитесь, что маршруты остаются синхронизированными с соответствующими контроллерами и действиями при применении автоматического рефакторинга переименования.
  2. Включите HTTP-запросы Get к действиям ProductsController :

    • [HttpGet] Примените атрибут к GetAllProducts действию.
    • [HttpGet("{id}")] Примените атрибут к GetProduct действию.

Запустите перенесенный проект и перейдите к /api/productsней. Появится полный список трех продуктов. Перейдите в /api/products/1. Появится первый продукт.

Дополнительные ресурсы