ASP.NET Core로 Web API 만들기Create web APIs with ASP.NET Core

작성자: Scott Addie, Tom DykstraBy Scott Addie and Tom Dykstra

ASP.NET Core는 C#를 사용하여 Web API라고도 하는 RESTful 서비스 만들기를 지원합니다.ASP.NET Core supports creating RESTful services, also known as web APIs, using C#. 요청을 처리하기 위해 Web API는 컨트롤러를 사용합니다.To handle requests, a web API uses controllers. Web API의 컨트롤러ControllerBase에서 파생되는 클래스입니다.Controllers in a web API are classes that derive from ControllerBase. 이 문서에서는 웹 API 요청을 처리하기 위해 컨트롤러를 사용하는 방법을 보여 줍니다.This article shows how to use controllers for handling web API requests.

샘플 코드 보기 또는 다운로드View or download sample code. (다운로드하는 방법)(How to download).

ControllerBase 클래스ControllerBase class

Web API는 ControllerBase에서 파생되는 하나 이상의 컨트롤러 클래스로 구성됩니다.A web API consists of one or more controller classes that derive from ControllerBase. 웹 API 프로젝트 템플릿은 시작 컨트롤러를 제공합니다.The web API project template provides a starter controller:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Controller 클래스에서 파생된 Web API 컨트롤러를 만들지 마세요.Don't create a web API controller by deriving from the Controller class. ControllerControllerBase에서 파생되며 뷰에 대한 지원을 추가하므로 Web API 요청이 아닌 웹 페이지를 처리할 수 있습니다.Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests. 이 규칙에 대한 예외가 있습니다. 뷰와 웹 API 모두에 동일한 컨트롤러를 사용하려는 경우 Controller에서 파생합니다.There's an exception to this rule: if you plan to use the same controller for both views and web APIs, derive it from Controller.

ControllerBase 클래스는 HTTP 요청을 처리하는 데 유용한 많은 속성 및 메서드를 제공합니다.The ControllerBase class provides many properties and methods that are useful for handling HTTP requests. 예를 들어, ControllerBase.CreatedAtAction은 201 상태 코드를 반환합니다.For example, ControllerBase.CreatedAtAction returns a 201 status code:

[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
    pet.Id = _petsInMemoryStore.Any() ? 
             _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
    _petsInMemoryStore.Add(pet);

    return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

다음은 ControllerBase가 제공하는 메서드의 몇 가지 예입니다.Here are some more examples of methods that ControllerBase provides.

메서드Method 참고Notes
BadRequest 400 상태 코드를 반환합니다.Returns 400 status code.
NotFound 404 상태 코드를 반환합니다.Returns 404 status code.
PhysicalFile 파일을 반환합니다.Returns a file.
TryUpdateModelAsync 모델 바인딩을 호출합니다.Invokes model binding.
TryValidateModel 모델 유효성 검사를 호출합니다.Invokes model validation.

사용 가능한 모든 메서드 및 속성 목록을 보려면 ControllerBase를 참조하세요.For a list of all available methods and properties, see ControllerBase.

특성Attributes

Microsoft.AspNetCore.Mvc 네임스페이스는 Web API 컨트롤러 및 작업 메서드의 동작을 구성하는 데 사용할 수 있는 특성을 제공합니다.The Microsoft.AspNetCore.Mvc namespace provides attributes that can be used to configure the behavior of web API controllers and action methods. 다음 예제에서는 특성을 사용하여 지원되는 HTTP 작업 동사와 반환될 수 있는 알려진 HTTP 상태 코드를 지정합니다.The following example uses attributes to specify the supported HTTP action verb and any known HTTP status codes that could be returned:

[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
    pet.Id = _petsInMemoryStore.Any() ? 
             _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
    _petsInMemoryStore.Add(pet);

    return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

다음은 사용 가능한 특성의 몇 가지 예입니다.Here are some more examples of attributes that are available.

특성Attribute 참고Notes
[Route] 컨트롤러 또는 작업의 URL 패턴을 지정합니다.Specifies URL pattern for a controller or action.
[Bind] 모델 바인딩에 포함할 접두사 및 속성을 지정합니다.Specifies prefix and properties to include for model binding.
[HttpGet] HTTP GET 작업 동사를 지원하는 작업을 식별합니다.Identifies an action that supports the HTTP GET action verb.
[Consumes] 작업에서 허용하는 데이터 형식을 지정합니다.Specifies data types that an action accepts.
[Produces] 작업에서 반환하는 데이터 형식을 지정합니다.Specifies data types that an action returns.

사용 가능한 특성이 포함된 목록은 Microsoft.AspNetCore.Mvc 네임스페이스를 참조하세요.For a list that includes the available attributes, see the Microsoft.AspNetCore.Mvc namespace.

ApiController 특성ApiController attribute

[ApiController] 특성을 컨트롤러 클래스에 적용하여 다음과 같이 독자적인 API 관련 동작을 사용할 수 있습니다.The [ApiController] attribute can be applied to a controller class to enable the following opinionated, API-specific behaviors:

이러한 기능을 사용하려면 호환성 버전 2.1 이상이 필요합니다.These features require a compatibility version of 2.1 or later.

특정 컨트롤러의 특성Attribute on specific controllers

프로젝트 템플릿의 다음 예제에서처럼 [ApiController] 특성을 특정 컨트롤러에 적용할 수 있습니다.The [ApiController] attribute can be applied to specific controllers, as in the following example from the project template:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

여러 컨트롤러의 특성Attribute on multiple controllers

둘 이상의 컨트롤러에서 특성을 사용하는 방법으로 [ApiController] 특성으로 주석이 추가된 사용자 지정 기본 컨트롤러 클래스를 만드는 방법이 있습니다.One approach to using the attribute on more than one controller is to create a custom base controller class annotated with the [ApiController] attribute. 다음 예제는 사용자 지정 기본 클래스와 여기에서 파생되는 컨트롤러를 보여 줍니다.The following example shows a custom base class and a controller that derives from it:

[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase

어셈블리의 특성Attribute on an assembly

호환성 버전이 2.2 이상으로 설정된 경우 [ApiController] 특성을 어셈블리에 적용할 수 있습니다.If compatibility version is set to 2.2 or later, the [ApiController] attribute can be applied to an assembly. 이 방식의 주석은 웹 API 동작을 어셈블리의 모든 컨트롤러에 적용합니다.Annotation in this manner applies web API behavior to all controllers in the assembly. 개별 컨트롤러를 대상으로 옵트아웃하는 방법은 없습니다.There's no way to opt out for individual controllers. 어셈블리 수준 특성을 Startup 클래스 주위의 네임스페이스 선언에 적용합니다.Apply the assembly-level attribute to the namespace declaration surrounding the Startup class:

[assembly: ApiController]
namespace WebApiSample
{
    public class Startup
    {
        ...
    }
}

특성 라우팅 요구 사항Attribute routing requirement

[ApiController] 특성은 특성 라우팅을 요구합니다.The [ApiController] attribute makes attribute routing a requirement. 예:For example:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

작업은 Startup.ConfigureUseEndpoints, UseMvc 또는 UseMvcWithDefaultRoute에 의해 정의된 규칙 기반 경로를 통해 액세스할 수 없습니다.Actions are inaccessible via conventional routes defined by UseEndpoints, UseMvc, or UseMvcWithDefaultRoute in Startup.Configure.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

작업은 UseMvc에 의해 정의된 규칙 기반 경로를 통해 또는 Startup.ConfigureUseMvcWithDefaultRoute에서 액세스할 수 없습니다.Actions are inaccessible via conventional routes defined by UseMvc or UseMvcWithDefaultRoute in Startup.Configure.

자동 HTTP 400 응답Automatic HTTP 400 responses

[ApiController] 특성은 HTTP 400 응답을 자동으로 트리거하는 모델 유효성 검사 오류를 만듭니다.The [ApiController] attribute makes model validation errors automatically trigger an HTTP 400 response. 따라서 다음 코드는 작업 메서드에서 불필요합니다.Consequently, the following code is unnecessary in an action method:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

ASP.NET Core MVC는 ModelStateInvalidFilter 작업 필터를 사용하여 위의 검사를 수행합니다.ASP.NET Core MVC uses the ModelStateInvalidFilter action filter to do the preceding check.

기본 BadRequest 응답Default BadRequest response

호환성 버전이 2.1이면 HTTP 400 응답에 대한 기본 응답 형식은 SerializableError입니다.With a compatibility version of 2.1, the default response type for an HTTP 400 response is SerializableError. 다음 요청 본문은 직렬화된 형식의 예제입니다.The following request body is an example of the serialized type:

{
  "": [
    "A non-empty request body is required."
  ]
}

호환성 버전이 2.2 이상이면 HTTP 400 응답에 대한 기본 응답 형식은 ValidationProblemDetails입니다.With a compatibility version of 2.2 or later, the default response type for an HTTP 400 response is ValidationProblemDetails. 다음 요청 본문은 직렬화된 형식의 예제입니다.The following request body is an example of the serialized type:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|7fb5e16a-4c8f23bbfc974667.",
  "errors": {
    "": [
      "A non-empty request body is required."
    ]
  }
}

ValidationProblemDetails 형식:The ValidationProblemDetails type:

  • 웹 API 응답에서 오류를 지정하기 위해 머신이 읽을 수 있는 형식을 제공합니다.Provides a machine-readable format for specifying errors in web API responses.
  • RFC 7807 사양을 준수합니다.Complies with the RFC 7807 specification.

자동 400 응답 기록Log automatic 400 responses

How to log automatic 400 responses on model validation errors (aspnet/AspNetCore.Docs #12157)(모델 유효성 검사 오류에서 자동 400 응답을 기록하는 방법(aspnet/AspNetCore.Docs #12157))를 참조하세요.See How to log automatic 400 responses on model validation errors (aspnet/AspNetCore.Docs #12157).

자동 400 응답 사용 안 함Disable automatic 400 response

자동 400 동작을 사용하지 않으려면 SuppressModelStateInvalidFilter 속성을 true로 설정합니다.To disable the automatic 400 behavior, set the SuppressModelStateInvalidFilter property to true. Startup.ConfigureServices에 다음 강조 표시된 코드를 추가합니다.Add the following highlighted code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

바인딩 소스 매개 변수 유추Binding source parameter inference

바인딩 소스 특성은 작업 매개 변수 값이 발견되는 위치를 정의합니다.A binding source attribute defines the location at which an action parameter's value is found. 다음 바인딩 소스 특성이 존재합니다.The following binding source attributes exist:

특성Attribute 바인딩 원본Binding source
[FromBody] 요청 본문Request body
[FromForm] 요청 본문에서 양식 데이터Form data in the request body
[FromHeader] 요청 헤더Request header
[FromQuery] 요청 쿼리 문자열 매개 변수Request query string parameter
[FromRoute] 현재 요청의 경로 데이터Route data from the current request
[FromServices] 작업 매개 변수로 삽입된 요청 서비스The request service injected as an action parameter

경고

값에 %2f(즉, /)이 포함될 수 있는 경우 [FromRoute]를 사용하지 않습니다.Don't use [FromRoute] when values might contain %2f (that is /). %2f/로 이스케이프가 해제되지 않습니다.%2f won't be unescaped to /. 값에 %2f가 포함될 수 있으면 [FromQuery]를 사용합니다.Use [FromQuery] if the value might contain %2f.

[ApiController] 특성 또는 [FromQuery] 같은 다른 바인딩 소스 특성 없이, ASP.NET Core 런타임에서 복합 개체 모델 바인더 사용을 시도합니다.Without the [ApiController] attribute or binding source attributes like [FromQuery], the ASP.NET Core runtime attempts to use the complex object model binder. 복합 개체 모델 바인더는 정의된 순서로 값 공급자로부터 데이터를 풀합니다.The complex object model binder pulls data from value providers in a defined order.

다음 예제에서 [FromQuery] 특성은 discontinuedOnly 매개 변수 값이 요청 URL의 쿼리 문자열에 제공됨을 나타냅니다.In the following example, the [FromQuery] attribute indicates that the discontinuedOnly parameter value is provided in the request URL's query string:

[HttpGet]
public ActionResult<List<Product>> Get(
    [FromQuery] bool discontinuedOnly = false)
{
    List<Product> products = null;

    if (discontinuedOnly)
    {
        products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
    }
    else
    {
        products = _productsInMemoryStore;
    }

    return products;
}

[ApiController] 특성은 작업 매개 변수의 기본 데이터 원본에 유추 규칙을 적용합니다.The [ApiController] attribute applies inference rules for the default data sources of action parameters. 이러한 규칙을 통해 작업 매개 변수에 특성을 적용하여 바인딩 소스를 수동으로 식별할 필요가 없습니다.These rules save you from having to identify binding sources manually by applying attributes to the action parameters. 바인딩 소스 유추 규칙은 다음과 같이 동작합니다.The binding source inference rules behave as follows:

  • [FromBody]는 복합 형식 매개 변수에 대해 유추됩니다.[FromBody] is inferred for complex type parameters. [FromBody] 유추 규칙은 IFormCollectionCancellationToken 같이 특별한 의미를 지닌 복합 기본 제공 형식에는 적용되지 않습니다.An exception to the [FromBody] inference rule is any complex, built-in type with a special meaning, such as IFormCollection and CancellationToken. 바인딩 소스 유추 코드는 이러한 특별한 형식을 무시합니다.The binding source inference code ignores those special types.
  • [FromForm]IFormFileIFormFileCollection 형식의 작업 매개 변수에 대해 유추됩니다.[FromForm] is inferred for action parameters of type IFormFile and IFormFileCollection. 단순 또는 사용자 정의 형식에 대해서는 유추되지 않습니다.It's not inferred for any simple or user-defined types.
  • [FromRoute]는 경로 템플릿에서 매개 변수와 일치하는 작업 매개 변수 이름에 대해 유추됩니다.[FromRoute] is inferred for any action parameter name matching a parameter in the route template. 둘 이상의 경로가 작업 매개 변수와 일치하는 경우 모든 경로 값은 [FromRoute]로 간주됩니다.When more than one route matches an action parameter, any route value is considered [FromRoute].
  • [FromQuery]는 다른 작업 매개 변수에 대해 유추됩니다.[FromQuery] is inferred for any other action parameters.

FromBody 유추 메모FromBody inference notes

[FromBody]string 또는 int 같은 단순 형식에 대해 유추되지 않습니다.[FromBody] isn't inferred for simple types such as string or int. 따라서 해당 기능이 필요한 경우 단순 형식에 [FromBody] 특성을 사용해야 합니다.Therefore, the [FromBody] attribute should be used for simple types when that functionality is needed.

작업에 요청 본문에서 바인딩된 매개 변수가 두 개 이상 있는 경우 예외가 throw됩니다.When an action has more than one parameter bound from the request body, an exception is thrown. 예를 들어 다음 모든 작업 메서드 시그니처로 예외가 발생합니다.For example, all of the following action method signatures cause an exception:

  • 복합 형식이므로 둘 다에서 유추된 [FromBody][FromBody] inferred on both because they're complex types.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • 하나의 [FromBody] 특성, 복합 형식이므로 다른 하나에서 유추됨[FromBody] attribute on one, inferred on the other because it's a complex type.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • 둘 다의 [FromBody] 특성[FromBody] attribute on both.

    [HttpPost]
    public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
    

참고

ASP.NET Core 2.1에서 목록, 배열 등의 컬렉션 형식 매개 변수를 [FromQuery]로 잘못 유추합니다.In ASP.NET Core 2.1, collection type parameters such as lists and arrays are incorrectly inferred as [FromQuery]. 이러한 매개 변수가 요청 본문에서 바인딩되는 경우 해당 매개 변수에 [FromBody] 특성을 사용해야 합니다.The [FromBody] attribute should be used for these parameters if they are to be bound from the request body. 이 문제는 ASP.NET Core 2.2 이상에서 수정됩니다. 즉, 기본적으로 컬렉션 형식 매개 변수를 본문에서 바인딩되도록 유추합니다.This behavior is corrected in ASP.NET Core 2.2 or later, where collection type parameters are inferred to be bound from the body by default.

유추 규칙 사용 안 함Disable inference rules

바인딩 소스 유추를 사용하지 않으려면 SuppressInferBindingSourcesForParameterstrue로 설정합니다.To disable binding source inference, set SuppressInferBindingSourcesForParameters to true. 다음 코드를 Startup.ConfigureServices에 추가합니다.Add the following code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

다중 파트/폼 데이터 요청 유추Multipart/form-data request inference

작업 매개 변수를 [FromForm] 특성으로 주석 처리하는 경우 [ApiController] 특성이 유추 규칙에 적용됩니다.The [ApiController] attribute applies an inference rule when an action parameter is annotated with the [FromForm] attribute. multipart/form-data 요청 콘텐츠 형식이 유추됩니다.The multipart/form-data request content type is inferred.

기본 동작을 사용하지 않으려면 Startup.ConfigureServices에서 SuppressConsumesConstraintForFormFileParameters 속성을 true로 설정합니다.To disable the default behavior, set the SuppressConsumesConstraintForFormFileParameters property to true in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

오류 상태 코드에 대한 문제 세부 정보Problem details for error status codes

호환성 버전이 2.2 이상인 경우 MVC는 오류 결과(상태 코드 400 이상의 결과)를 ProblemDetails가 있는 결과로 변환합니다.When the compatibility version is 2.2 or later, MVC transforms an error result (a result with status code 400 or higher) to a result with ProblemDetails. ProblemDetails 형식은 HTTP 응답에 머신에서 읽을 수 있는 오류 세부 정보를 제공하기 위해 RFC 7807 사양을 기반으로 합니다.The ProblemDetails type is based on the RFC 7807 specification for providing machine-readable error details in an HTTP response.

다음 컨트롤러 작업에서 다음 코드를 고려하세요.Consider the following code in a controller action:

if (pet == null)
{
    return NotFound();
}

NotFound 메서드는 ProblemDetails 본문이 포함된 HTTP 404 상태 코드를 생성합니다.The NotFound method produces an HTTP 404 status code with a ProblemDetails body. 예:For example:

{
  type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  title: "Not Found",
  status: 404,
  traceId: "0HLHLV31KRN83:00000001"
}

ProblemDetails 응답 사용 안 함Disable ProblemDetails response

SuppressMapClientErrors 속성이 true로 설정된 경우 ProblemDetails 인스턴스의 자동 생성이 사용되지 않습니다.The automatic creation of a ProblemDetails instance is disabled when the SuppressMapClientErrors property is set to true. 다음 코드를 Startup.ConfigureServices에 추가합니다.Add the following code in Startup.ConfigureServices:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });
services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[404].Link =
            "https://httpstatuses.com/404";
    });

추가 자료Additional resources