ASP.NET Web API에서 ASP.NET Core로 마이그레이션

ASP.NET Core는 ASP.NET 4.x의 MVC 및 Web API 앱 모델을 ASP.NET Core MVC라는 단일 프로그래밍 모델로 결합합니다.

이 문서에서는 ASP.NET Web API 2를 사용하여 시작에서 만든 Products 컨트롤러를 ASP.NET Core 마이그레이션하는 방법을 보여 줍니다.

필수 조건

ASP.NET Core 웹 API 프로젝트 만들기

  1. 파일 메뉴에서 새로 만들기>프로젝트를 선택합니다.
  2. 검색 상자에 Web API를 입력합니다.
  3. ASP.NET Core Web API 템플릿을 선택하고 다음을 선택합니다.
  4. 새 프로젝트 구성 대화 상자에서 프로젝트 이름을 ProductsCore로 지정하고 다음을 선택합니다.
  5. 추가 정보 대화 상자에서:
    1. 프레임워크.Net 6.0(장기 지원)인지 확인합니다.
    2. 컨트롤러 사용(최소 API를 사용하려면 선택 취소) 확인란을 선택합니다.
    3. OpenAPI 지원 사용을 선택 취소합니다.
    4. 만들기를 실행합니다.

WeatherForecast 템플릿 파일 제거

  1. WeatherForecast.csProductsCore 프로젝트에서 파일 및 Controllers/WeatherForecastController.cs 예제를 제거합니다.
  2. Properties\launchSettings.json을 엽니다.
  3. launchUrl 속성을 weatherforcast에서 productscore로 변경합니다.

ASP.NET Core 웹 API에 대한 구성

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

위에 강조 표시된 코드는 다음을 변경합니다.

  • NameCategory 속성을 nullable 참조 형식으로 선언하기 위해 ? 주석이 추가되었습니다.

C# 8에 도입된 Null 허용 기능을 활용하여 ASP.NET Core는 참조 형식 처리에 추가로 코드 흐름 분석 및 컴파일 시간 안전을 제공할 수 있습니다. 예를 들면 null 참조 예외로부터 보호입니다.

이 경우 의도는 NameCategory가 nullable 형식일 수 있다는 것입니다.

ASP.NET Core 6.0 프로젝트는 기본적으로 nullable 참조 형식을 사용하도록 설정합니다. 자세한 내용은 nullable 참조 형식을 참조하세요.

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에 마이그레이션합니다.

  • ASP.NET Core에 존재하지 않는 다음 ASP.NET 4.x 구성 요소에 대한 using 문을 제거합니다.

    • ApiController 클래스
    • System.Web.Http 네임스페이스
    • IHttpActionResult 인터페이스
  • using ProductsApp.Models; 문을 using ProductsCore.Models;로 변경합니다.

  • 루트 네임스페이스를 ProductsCore로 설정합니다.

  • ApiControllerControllerBase로 변경합니다.

  • using Microsoft.AspNetCore.Mvc;를 추가하여 ControllerBase 참조를 확인합니다.

  • GetProduct 동작의 반환 형식을 IHttpActionResult에서 ActionResult<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 가져오기 요청은 다음 특성이 있는 ProductController 작업에 대해 사용하도록 설정됩니다.

    • GetAllProducts 작업에 적용되는 [HttpGet] 특성.
    • GetProduct 작업에 적용되는 [HttpGet("{id}")] 특성.

마이그레이션된 프로젝트를 실행하고 /api/products로 이동합니다. 예: https://localhost:<port>/api/products. 세 가지 제품의 전체 목록이 표시됩니다. /api/products/1으로 이동합니다. 첫 번째 제품이 나타납니다.

샘플 코드 보기 및 다운로드(다운로드 방법)

추가 리소스

이 문서에서는 ASP.NET 4.x Web API에서 ASP.NET Core MVC로 마이그레이션하는 데 필요한 단계를 보여줍니다.

샘플 코드 보기 및 다운로드(다운로드 방법)

필수 조건

ASP.NET 4.x Web API 프로젝트 검토

이 문서에서는 ASP.NET Web API 2 시작에서 만든 ProductsApp 프로젝트를 사용합니다. 해당 프로젝트에서 기본 ASP.NET 4.x Web API 프로젝트는 다음과 같이 구성됩니다.

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}는 선택 사항입니다.

다음 섹션에서는 Web API 프로젝트를 ASP.NET Core MVC로 마이그레이션하는 방법을 보여줍니다.

대상 프로젝트 만들기

Visual Studio에서 새 빈 솔루션을 만들고 마이그레이션할 ASP.NET 4.x Web API 프로젝트를 추가합니다.

  1. 파일 메뉴에서 새로 만들기>프로젝트를 선택합니다.
  2. 빈 솔루션 템플릿을 선택하고 다음을 선택합니다.
  3. 솔루션 이름을 WebAPIMigration으로 지정합니다. 만들기를 실행합니다.
  4. 솔루션에 기존 ProductsApp 프로젝트를 추가합니다.

마이그레이션할 새 API 프로젝트를 다음으로 추가합니다.

  1. 솔루션에 새 ASP.NET Core 웹 애플리케이션 프로젝트를 추가합니다.
  2. 새 프로젝트 구성 대화 상자에서 프로젝트 이름을 ProductsCore로 지정하고 만들기를 선택합니다.
  3. 새 ASP.NET Core 웹 애플리케이션 만들기 대화 상자에서 .NET CoreASP.NET Core 3.1이 선택되었는지 확인합니다. API 프로젝트 템플릿을 선택하고 만들기를 선택합니다.
  4. WeatherForecast.csProductsCore 프로젝트에서 파일 및 Controllers/WeatherForecastController.cs 예제를 제거합니다.

이젠 솔루션에는 두 개의 프로젝트가 포함됩니다. 다음 섹션에서는 ProductsApp 프로젝트의 콘텐츠를 ProductsCore 프로젝트로 마이그레이션하는 방법을 설명합니다.

구성 마이그레이션

ASP.NET Core는 App_Start 폴더 또는 Global.asax 파일을 사용하지 않습니다. 또한 web.config 파일이 게시 시 추가됩니다.

Startup 클래스:

  • Global.asax를 바꿉니다.
  • 모든 앱 시작 작업을 처리합니다.

자세한 내용은 ASP.NET Core에서 앱 시작을 참조하세요.

모델 및 컨트롤러 마이그레이션

다음 코드에서는 ASP.NET Core 대해 업데이트할 ProductsController를 보여줍니다.

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

ASP.NET Core용 ProductsController를 업데이트합니다.

  1. 원본 프로젝트에서 새 프로젝트로 모델 폴더를 복사 Controllers/ProductsController.cs 하고 복사합니다.
  2. 복사한 파일의 루트 네임스페이스를 ProductsCore로 변경합니다.
  3. using ProductsApp.Models; 문을 using ProductsCore.Models;로 업데이트합니다.

다음 구성 요소는 ASP.NET Core에 없습니다.

  • ApiController 클래스
  • System.Web.Http 네임스페이스
  • IHttpActionResult 인터페이스

다음과 같이 변경합니다.

  1. ApiControllerControllerBase로 바꿉니다. using Microsoft.AspNetCore.Mvc;를 추가하여 ControllerBase 참조를 확인합니다.

  2. using System.Web.Http;를 삭제합니다.

  3. GetProduct 동작의 반환 형식을 IHttpActionResult에서 ActionResult<Product>로 변경합니다.

  4. GetProduct 동작의 return 문을 다음과 같이 단순화합니다.

    return product;
    

라우팅 구성

ASP.NET Core API 프로젝트 템플릿에는 생성된 코드에 엔드포인트 라우팅 구성이 포함되어 있습니다.

다음 예제에서는 UseRoutingUseEndpoints를 호출합니다.

  • 미들웨어 파이프라인에 경로 일치 및 엔드포인트 실행을 등록합니다.
  • ProductsApp 프로젝트의 App_Start/WebApiConfig.cs 파일을 바꿉니다.
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. ProductsController 작업에 대한 HTTP Get 요청을 사용하도록 설정합니다.

    • GetAllProducts 동작에 [HttpGet] 특성을 적용합니다.
    • GetProduct 동작에 [HttpGet("{id}")] 특성을 적용합니다.

마이그레이션된 프로젝트를 실행하고 /api/products로 이동합니다. 세 가지 제품의 전체 목록이 표시됩니다. /api/products/1으로 이동합니다. 첫 번째 제품이 나타납니다.

추가 리소스