Dela via


Skapa webb-API:er med ASP.NET Core

ASP.NET Core har stöd för att skapa webb-API:er med hjälp av kontrollanter eller med minimala API:er. Kontrollanter i ett webb-API är klasser som härleds från ControllerBase. Styrenheter aktiveras och tas bort per begäran.

Den här artikeln visar hur du använder kontrollanter för hantering av webb-API-begäranden. Information om hur du skapar webb-API:er utan kontrollanter finns i Självstudie: Skapa ett minimalt API med ASP.NET Core.

Viktigt!

Från och med ASP.NET Core 10 omdirigeras inte längre kända API-slutpunkter till inloggningssidor när autentisering används cookie . I stället returnerar de statuskoder för 401/403. Mer information finns i BETEENDE för API-slutpunktsautentisering i ASP.NET Core.

ControllerBase-klass

Ett kontrollantbaserat webb-API består av en eller flera kontrollantklasser som härleds från ControllerBase. Webb-API-projektmallen innehåller en startkontrollant:

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

Webb-API-kontrollanter bör vanligtvis härledas från ControllerBase snarare från Controller. Controller härleds från ControllerBase och lägger till stöd för vyer, så det är för att hantera webbsidor, inte webb-API-begäranden. Om samma kontroller måste ha stöd för vyer och webb-API:er ska härledas från Controller.

Klassen ControllerBase innehåller många egenskaper och metoder som är användbara för att hantera HTTP-begäranden. Returnerar till exempel CreatedAtAction en statuskod för 201:

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

Följande tabell innehåller exempel på metoder i ControllerBase.

Method Notes
BadRequest Returnerar statuskoden 400.
NotFound Returnerar statuskoden 404.
PhysicalFile Returnerar en fil.
TryUpdateModelAsync Anropar modellbindning.
TryValidateModel Anropar modellverifiering.

En lista över alla tillgängliga metoder och egenskaper finns i ControllerBase.

Attributes

Namnområdet Microsoft.AspNetCore.Mvc innehåller attribut som kan användas för att konfigurera beteendet för webb-API-kontrollanter och åtgärdsmetoder. I följande exempel används attribut för att ange http-åtgärdsverb som stöds och eventuella kända HTTP-statuskoder som kan returneras:

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

Här är några fler exempel på attribut som är tillgängliga.

Attribute Notes
[Route] Anger URL-mönster för en kontrollant eller åtgärd.
[Bind] Anger prefix och egenskaper som ska inkluderas för modellbindning.
[HttpGet] Identifierar en åtgärd som stöder HTTP GET-åtgärdsverb.
[Consumes] Anger datatyper som en åtgärd accepterar.
[Produces] Anger datatyper som en åtgärd returnerar.

En lista som innehåller de tillgängliga attributen finns i Microsoft.AspNetCore.Mvc namnområdet.

ApiController-attribut

Attributet [ApiController] kan tillämpas på en kontrollantklass för att aktivera följande åsiktsbaserade, API-specifika beteenden:

Attribut på specifika kontrollanter

Attributet [ApiController] kan tillämpas på specifika kontrollanter, som i följande exempel från projektmallen:

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

Attribut på flera kontrollanter

En metod för att använda attributet på mer än en kontrollant är att skapa en anpassad baskontrollantklass som kommenterats med [ApiController] attributet. I följande exempel visas en anpassad basklass och en kontrollant som härleds från den:

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

Attribut för en sammansättning

Attributet [ApiController] kan tillämpas på en sammansättning. När [ApiController]-attributet tillämpas på en assembly, tillämpas [ApiController]-attributet på alla kontroller i assemblyn. Det finns inget sätt att välja bort enskilda kontrollanter. Använd attributet på sammansättningsnivå för Program.cs filen:

using Microsoft.AspNetCore.Mvc;
[assembly: ApiController]

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Krav för attributroutning

Attributet [ApiController] gör attributroutning till ett krav. Till exempel:

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

Åtgärder är otillgängliga via konventionella vägar som definieras av UseEndpoints, UseMvceller UseMvcWithDefaultRoute.

Automatiska HTTP 400-svar

Attributet [ApiController] gör att modellverifieringsfel automatiskt utlöser ett HTTP 400-svar. Följande kod är därför onödig i en åtgärdsmetod:

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

ASP.NET Core MVC använder åtgärdsfiltret ModelStateInvalidFilter för att göra föregående kontroll.

Standardsvar för BadRequest

Standardsvarstypen för ett HTTP 400-svar är ValidationProblemDetails. Följande svarstext är ett exempel på den serialiserade typen:

{
  "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."
    ]
  }
}

Typ ValidationProblemDetails :

Om du vill göra automatiska och anpassade svar konsekventa anropar du ValidationProblem metoden i stället BadRequestför . ValidationProblem returnerar ett ValidationProblemDetails objekt samt det automatiska svaret.

Logga automatiska 400-svar

Om du vill logga automatiska 400-svar, ställ in egenskapen för delegering InvalidModelStateResponseFactory så att anpassad bearbetning kan utföras. Som standard InvalidModelStateResponseFactory används ProblemDetailsFactory för att skapa en instans av ValidationProblemDetails.

I följande exempel visas hur du hämtar en instans av ILogger<TCategoryName> för att logga information om ett automatiskt 400-svar:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
      // To preserve the default behavior, capture the original delegate to call later.
        var builtInFactory = options.InvalidModelStateResponseFactory;

        options.InvalidModelStateResponseFactory = context =>
        {
            var logger = context.HttpContext.RequestServices
                                .GetRequiredService<ILogger<Program>>();

            // Perform logging here.
            // ...

            // Invoke the default behavior, which produces a ValidationProblemDetails
            // response.
            // To produce a custom response, return a different implementation of 
            // IActionResult instead.
            return builtInFactory(context);
        };
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Inaktivera automatiskt 400-svar

Om du vill inaktivera det automatiska 400-beteendet anger du SuppressModelStateInvalidFilter egenskapen till true. Lägg till följande markerade kod:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Bindning av källparameterinferens

Ett attribut för bindningskälla definierar den plats där värdet för en åtgärdsparameter hittas. Följande bindningskällaattribut finns:

Attribute Bindningskälla
[FromBody] begäranens innehåll
[FromForm] Formulärdata i begärandetexten
[FromHeader] Begärandehuvud
[FromQuery] Frågesträngsparameter för begäran
[FromRoute] Skicka vidare data från den aktuella begäran
[FromServices] Begärandetjänsten som matas in som en åtgärdsparameter
[AsParameters] Metodparametrar

Warning

Använd [FromRoute] inte när värden kan innehålla %2f (alltså /). %2f kommer inte att tas bort från /. Använd [FromQuery] om värdet kan innehålla %2f.

[ApiController] Utan attributet eller bindningskällans attribut som [FromQuery]försöker ASP.NET Core-körningen använda den komplexa objektmodellbindningen. Den komplexa objektmodellbindningen hämtar data från värdeprovidrar i en definierad ordning.

I följande exempel [FromQuery] anger attributet att discontinuedOnly parametervärdet anges i frågesträngen för begärande-URL:en:

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

Attributet [ApiController] tillämpar slutsatsdragningsregler för standarddatakällorna för åtgärdsparametrar. Dessa regler sparar dig från att behöva identifiera bindningskällor manuellt genom att tillämpa attribut på åtgärdsparametrarna. Bindningskällans slutsatsdragningsregler fungerar på följande sätt:

  • [FromServices] härleds för komplexa typparametrar som registrerats i DI-containern.
  • [FromBody] härleds för komplexa typparametrar som inte har registrerats i DI-containern. Ett undantag från slutsatsdragningsregeln [FromBody] är alla komplexa, inbyggda typer med en särskild betydelse, till exempel IFormCollection och CancellationToken. Inferenskoden för bindningskällan ignorerar dessa specialtyper.
  • [FromForm] härleds för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Det härleds inte för några enkla eller användardefinierade typer.
  • [FromRoute] härleds för alla åtgärdsparameternamn som matchar en parameter i routningsmallen. När mer än en väg matchar en åtgärdsparameter betraktas alla routningsvärden som [FromRoute].
  • [FromQuery] härleds för vilka som helst andra åtgärdsparametrar.

FromBody-slutsatsdragningsanteckningar

[FromBody] härleds inte för enkla typer som string eller int. Därför [FromBody] bör attributet användas för enkla typer när den funktionen behövs.

När en åtgärd har fler än en parameter som är bunden från begärandetexten genereras ett undantag. Till exempel orsakar signaturerna för alla följande åtgärdsmetoder ett undantag:

  • [FromBody] härleds på båda eftersom de är komplexa typer.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] attributet på den ena, härleds på den andra eftersom det är en komplex typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] attribut på båda.

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

Slutsatsdragningsanteckningar för FromServices

Parameterbindning binder parametrar via beroendeinmatning när typen konfigureras som en tjänst. Det innebär att det inte krävs att attributet uttryckligen tillämpas på [FromServices] en parameter. I följande kod returnerar båda åtgärderna tiden:

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    public ActionResult GetWithAttribute([FromServices] IDateTime dateTime) 
                                                        => Ok(dateTime.Now);

    [Route("noAttribute")]
    public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
}

I sällsynta fall kan automatisk DI bryta appar som har en typ i DI som också accepteras i en API-kontrollants åtgärdsmetoder. Det är inte vanligt att ha en typ i DI och som argument i en API-kontrollantåtgärd.

Om du vill inaktivera [FromServices] slutsatsdragning för en enskild åtgärdsparameter använder du det önskade bindningskällans attribut för parametern. Använd till exempel [FromBody] attributet för en åtgärdsparameter som ska bindas från brödtexten i begäran.

Om du vill inaktivera [FromServices] slutsatsdragning globalt anger du DisableImplicitFromServicesParameters till true:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.DisableImplicitFromServicesParameters = true;
});

var app = builder.Build();

app.MapControllers();

app.Run();

Typer kontrolleras vid appstart med IServiceProviderIsService för att avgöra om ett argument i en API-kontrollantåtgärd kommer från DI eller från andra källor.

Mekanismen för att härleda bindningskällan för API Controller-åtgärdsparametrar använder följande regler:

Inaktivera slutsatsdragningsregler

Om du vill inaktivera bindningskällans slutsatsdragning anger du SuppressInferBindingSourcesForParameters till true:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
        options.DisableImplicitFromServicesParameters = true;
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Bearbetning av multipart/form-data-begäranden

Attributet [ApiController] tillämpar en slutsatsdragningsregel för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Innehållstypen multipart/form-data för begäran härleds för dessa typer.

Om du vill inaktivera standardbeteendet anger du SuppressConsumesConstraintForFormFileParameters egenskapen till true:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Probleminformation för felstatuskoder

MVC transformerar ett felresultat (ett resultat med statuskod 400 eller senare) till ett resultat med ProblemDetails. Typen ProblemDetails baseras på RFC 7807-specifikationen för att tillhandahålla maskinläsbar felinformation i ett HTTP-svar.

Överväg följande kod i en kontrollantåtgärd:

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

Metoden NotFound genererar en HTTP 404-statuskod med en ProblemDetails brödtext. Till exempel:

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

Inaktivera ProblemDetails-svar

Automatiskt skapande av en ProblemDetails för felstatuskoder inaktiveras när egenskapen SuppressMapClientErrors är inställd på true. Lägg till följande kod:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Definiera innehållstyper för begäranden som stöds med attributet [Förbrukar]

Som standard stöder en åtgärd alla tillgängliga innehållstyper för begäranden. Om en app till exempel har konfigurerats för att stödja både JSON- och XML-indataformaterare stöder en åtgärd flera innehållstyper, inklusive application/json och application/xml.

Attributet [Förbrukar] tillåter en åtgärd för att begränsa innehållstyperna för begäranden som stöds. [Consumes] Använd attributet för en åtgärd eller kontrollant och ange en eller flera innehållstyper:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

I föregående kod anger åtgärden CreateProduct innehållstypen application/xml. Begäranden som dirigeras till den här åtgärden måste ange ett Content-Type huvud för application/xml. Begäranden som inte specificerar en Content-Type-rubrik resulterar i ett svar med application/xml.

Attributet [Consumes] gör också att en åtgärd kan påverka dess val baserat på en inkommande begärans innehållstyp genom att tillämpa en typbegränsning. Tänk på följande exempel:

[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
    [HttpPost]
    [Consumes("application/json")]
    public IActionResult PostJson(IEnumerable<int> values) =>
        Ok(new { Consumes = "application/json", Values = values });

    [HttpPost]
    [Consumes("application/x-www-form-urlencoded")]
    public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
        Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}

I föregående kod ConsumesController är konfigurerad för att hantera begäranden som skickas till https://localhost:5001/api/Consumes URL:en. Båda åtgärderna, PostJson och PostForm, i kontrollern hanterar POST-begäranden med samma URL. Utan att [Consumes] attributet tillämpar en typbegränsning genereras ett tvetydigt matchningsfel.

Attributet [Consumes] tillämpas på båda åtgärderna. Åtgärden PostJson hanterar begäranden som skickas med rubriken Content-Typeapplication/json. Åtgärden PostForm hanterar begäranden som skickas med rubriken Content-Typeapplication/x-www-form-urlencoded.

Ytterligare resurser

ASP.NET Core har stöd för att skapa webb-API:er med hjälp av kontrollanter eller med minimala API:er. Kontrollanter i ett webb-API är klasser som härleds från ControllerBase. Den här artikeln visar hur du använder kontrollanter för hantering av webb-API-begäranden. Information om hur du skapar webb-API:er utan kontrollanter finns i Självstudie: Skapa ett minimalt API med ASP.NET Core.

ControllerBase-klass

Ett kontrollantbaserat webb-API består av en eller flera kontrollantklasser som härleds från ControllerBase. Webb-API-projektmallen innehåller en startkontrollant:

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

Webb-API-kontrollanter bör vanligtvis härledas från ControllerBase snarare från Controller. Controller härleds från ControllerBase och lägger till stöd för vyer, så det är för att hantera webbsidor, inte webb-API-begäranden. Om samma kontroller måste ha stöd för vyer och webb-API:er ska härledas från Controller.

Klassen ControllerBase innehåller många egenskaper och metoder som är användbara för att hantera HTTP-begäranden. Returnerar till exempel CreatedAtAction en statuskod för 201:

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

Följande tabell innehåller exempel på metoder i ControllerBase.

Method Notes
BadRequest Returnerar statuskoden 400.
NotFound Returnerar statuskoden 404.
PhysicalFile Returnerar en fil.
TryUpdateModelAsync Anropar modellbindning.
TryValidateModel Anropar modellverifiering.

En lista över alla tillgängliga metoder och egenskaper finns i ControllerBase.

Attributes

Namnområdet Microsoft.AspNetCore.Mvc innehåller attribut som kan användas för att konfigurera beteendet för webb-API-kontrollanter och åtgärdsmetoder. I följande exempel används attribut för att ange http-åtgärdsverb som stöds och eventuella kända HTTP-statuskoder som kan returneras:

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

Här är några fler exempel på attribut som är tillgängliga.

Attribute Notes
[Route] Anger URL-mönster för en kontrollant eller åtgärd.
[Bind] Anger prefix och egenskaper som ska inkluderas för modellbindning.
[HttpGet] Identifierar en åtgärd som stöder HTTP GET-åtgärdsverb.
[Consumes] Anger datatyper som en åtgärd accepterar.
[Produces] Anger datatyper som en åtgärd returnerar.

En lista som innehåller de tillgängliga attributen finns i Microsoft.AspNetCore.Mvc namnområdet.

ApiController-attribut

Attributet [ApiController] kan tillämpas på en kontrollantklass för att aktivera följande åsiktsbaserade, API-specifika beteenden:

Attribut på specifika kontrollanter

Attributet [ApiController] kan tillämpas på specifika kontrollanter, som i följande exempel från projektmallen:

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

Attribut på flera kontrollanter

En metod för att använda attributet på mer än en kontrollant är att skapa en anpassad baskontrollantklass som kommenterats med [ApiController] attributet. I följande exempel visas en anpassad basklass och en kontrollant som härleds från den:

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

Attribut för en sammansättning

Attributet [ApiController] kan tillämpas på en sammansättning. När [ApiController]-attributet tillämpas på en assembly, tillämpas [ApiController]-attributet på alla kontroller i assemblyn. Det finns inget sätt att välja bort enskilda kontrollanter. Använd attributet på sammansättningsnivå för Program.cs filen:

using Microsoft.AspNetCore.Mvc;
[assembly: ApiController]

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Krav för attributroutning

Attributet [ApiController] gör attributroutning till ett krav. Till exempel:

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

Åtgärder är otillgängliga via konventionella vägar som definieras av UseEndpoints, UseMvceller UseMvcWithDefaultRoute.

Automatiska HTTP 400-svar

Attributet [ApiController] gör att modellverifieringsfel automatiskt utlöser ett HTTP 400-svar. Följande kod är därför onödig i en åtgärdsmetod:

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

ASP.NET Core MVC använder åtgärdsfiltret ModelStateInvalidFilter för att göra föregående kontroll.

Standardsvar för BadRequest

Följande svarstext är ett exempel på den serialiserade typen:

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

Standardsvarstypen för ett HTTP 400-svar är ValidationProblemDetails. Följande svarstext är ett exempel på den serialiserade typen:

{
  "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."
    ]
  }
}

Typ ValidationProblemDetails :

Om du vill göra automatiska och anpassade svar konsekventa anropar du ValidationProblem metoden i stället BadRequestför . ValidationProblem returnerar ett ValidationProblemDetails objekt samt det automatiska svaret.

Logga automatiska 400-svar

Om du vill logga automatiska 400-svar, ställ in egenskapen för delegering InvalidModelStateResponseFactory så att anpassad bearbetning kan utföras. Som standard InvalidModelStateResponseFactory används ProblemDetailsFactory för att skapa en instans av ValidationProblemDetails.

I följande exempel visas hur du hämtar en instans av ILogger<TCategoryName> för att logga information om ett automatiskt 400-svar:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
      // To preserve the default behavior, capture the original delegate to call later.
        var builtInFactory = options.InvalidModelStateResponseFactory;

        options.InvalidModelStateResponseFactory = context =>
        {
            var logger = context.HttpContext.RequestServices
                                .GetRequiredService<ILogger<Program>>();

            // Perform logging here.
            // ...

            // Invoke the default behavior, which produces a ValidationProblemDetails
            // response.
            // To produce a custom response, return a different implementation of 
            // IActionResult instead.
            return builtInFactory(context);
        };
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Inaktivera automatiskt 400-svar

Om du vill inaktivera det automatiska 400-beteendet anger du SuppressModelStateInvalidFilter egenskapen till true. Lägg till följande markerade kod:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Bindning av källparameterinferens

Ett attribut för bindningskälla definierar den plats där värdet för en åtgärdsparameter hittas. Följande bindningskällaattribut finns:

Attribute Bindningskälla
[FromBody] begäranens innehåll
[FromForm] Formulärdata i begärandetexten
[FromHeader] Begärandehuvud
[FromQuery] Frågesträngsparameter för begäran
[FromRoute] Skicka vidare data från den aktuella begäran
[FromServices] Begärandetjänsten som matas in som en åtgärdsparameter

Warning

Använd [FromRoute] inte när värden kan innehålla %2f (alltså /). %2f kommer inte att tas bort från /. Använd [FromQuery] om värdet kan innehålla %2f.

[ApiController] Utan attributet eller bindningskällans attribut som [FromQuery]försöker ASP.NET Core-körningen använda den komplexa objektmodellbindningen. Den komplexa objektmodellbindningen hämtar data från värdeprovidrar i en definierad ordning.

I följande exempel [FromQuery] anger attributet att discontinuedOnly parametervärdet anges i frågesträngen för begärande-URL:en:

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

Attributet [ApiController] tillämpar slutsatsdragningsregler för standarddatakällorna för åtgärdsparametrar. Dessa regler sparar dig från att behöva identifiera bindningskällor manuellt genom att tillämpa attribut på åtgärdsparametrarna. Bindningskällans slutsatsdragningsregler fungerar på följande sätt:

  • [FromBody] härleds för komplexa typparametrar som inte har registrerats i DI-containern. Ett undantag från slutsatsdragningsregeln [FromBody] är alla komplexa, inbyggda typer med en särskild betydelse, till exempel IFormCollection och CancellationToken. Inferenskoden för bindningskällan ignorerar dessa specialtyper.
  • [FromForm] härleds för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Det härleds inte för några enkla eller användardefinierade typer.
  • [FromRoute] härleds för alla åtgärdsparameternamn som matchar en parameter i routningsmallen. När mer än en väg matchar en åtgärdsparameter betraktas alla routningsvärden som [FromRoute].
  • [FromQuery] härleds för vilka som helst andra åtgärdsparametrar.

FromBody-slutsatsdragningsanteckningar

[FromBody] härleds inte för enkla typer som string eller int. Därför [FromBody] bör attributet användas för enkla typer när den funktionen behövs.

När en åtgärd har fler än en parameter som är bunden från begärandetexten genereras ett undantag. Till exempel orsakar signaturerna för alla följande åtgärdsmetoder ett undantag:

  • [FromBody] härleds på båda eftersom de är komplexa typer.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] attributet på den ena, härleds på den andra eftersom det är en komplex typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] attribut på båda.

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

Inaktivera slutsatsdragningsregler

Om du vill inaktivera bindningskällans slutsatsdragning anger du SuppressInferBindingSourcesForParameters till true:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Bearbetning av multipart/form-data-begäranden

Attributet [ApiController] tillämpar en slutsatsdragningsregel för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Innehållstypen multipart/form-data för begäran härleds för dessa typer.

Om du vill inaktivera standardbeteendet anger du SuppressConsumesConstraintForFormFileParameters egenskapen till true:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Probleminformation för felstatuskoder

MVC transformerar ett felresultat (ett resultat med statuskod 400 eller senare) till ett resultat med ProblemDetails. Typen ProblemDetails baseras på RFC 7807-specifikationen för att tillhandahålla maskinläsbar felinformation i ett HTTP-svar.

Överväg följande kod i en kontrollantåtgärd:

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

Metoden NotFound genererar en HTTP 404-statuskod med en ProblemDetails brödtext. Till exempel:

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

Inaktivera ProblemDetails-svar

Automatiskt skapande av en ProblemDetails för felstatuskoder inaktiveras när egenskapen är inställd på SuppressMapClientErrorstrue:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;
        options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
            "https://httpstatuses.com/404";
    });

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Definiera innehållstyper för begäranden som stöds med attributet [Förbrukar]

Som standard stöder en åtgärd alla tillgängliga innehållstyper för begäranden. Om en app till exempel har konfigurerats för att stödja både JSON- och XML-indataformaterare stöder en åtgärd flera innehållstyper, inklusive application/json och application/xml.

Attributet [Förbrukar] tillåter en åtgärd för att begränsa innehållstyperna för begäranden som stöds. [Consumes] Använd attributet för en åtgärd eller kontrollant och ange en eller flera innehållstyper:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

I föregående kod anger åtgärden CreateProduct innehållstypen application/xml. Begäranden som dirigeras till den här åtgärden måste ange ett Content-Type huvud för application/xml. Begäranden som inte specificerar en Content-Type-rubrik resulterar i ett svar med application/xml.

Attributet [Consumes] gör också att en åtgärd kan påverka dess val baserat på en inkommande begärans innehållstyp genom att tillämpa en typbegränsning. Tänk på följande exempel:

[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
    [HttpPost]
    [Consumes("application/json")]
    public IActionResult PostJson(IEnumerable<int> values) =>
        Ok(new { Consumes = "application/json", Values = values });

    [HttpPost]
    [Consumes("application/x-www-form-urlencoded")]
    public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
        Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}

I föregående kod ConsumesController är konfigurerad för att hantera begäranden som skickas till https://localhost:5001/api/Consumes URL:en. Båda åtgärderna, PostJson och PostForm, i kontrollern hanterar POST-begäranden med samma URL. Utan att [Consumes] attributet tillämpar en typbegränsning genereras ett tvetydigt matchningsfel.

Attributet [Consumes] tillämpas på båda åtgärderna. Åtgärden PostJson hanterar begäranden som skickas med rubriken Content-Typeapplication/json. Åtgärden PostForm hanterar begäranden som skickas med rubriken Content-Typeapplication/x-www-form-urlencoded.

Ytterligare resurser

ASP.NET Core har stöd för att skapa RESTful-tjänster, även kallade webb-API:er, med hjälp av C#. För att hantera begäranden använder ett webb-API kontrollanter. Kontrollanter i ett webb-API är klasser som härleds från ControllerBase. Den här artikeln visar hur du använder kontrollanter för hantering av webb-API-begäranden.

Visa eller ladda ned exempelkod. (Ladda ned).

ControllerBase-klass

Ett webb-API består av en eller flera kontrollantklasser som härleds från ControllerBase. Webb-API-projektmallen innehåller en startkontrollant:

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

Skapa inte en webb-API-kontrollant genom att härleda från Controller klassen. Controller härleds från ControllerBase och lägger till stöd för vyer, så det är för att hantera webbsidor, inte webb-API-begäranden. Det finns ett undantag till den här regeln: om du planerar att använda samma kontrollant för både vyer och webb-API:er härleder du den från Controller.

Klassen ControllerBase innehåller många egenskaper och metoder som är användbara för att hantera HTTP-begäranden. Returnerar till exempel ControllerBase.CreatedAtAction en statuskod för 201:

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

Här följer några fler exempel på metoder som ControllerBase tillhandahåller.

Method Notes
BadRequest Returnerar statuskoden 400.
NotFound Returnerar statuskoden 404.
PhysicalFile Returnerar en fil.
TryUpdateModelAsync Anropar modellbindning.
TryValidateModel Anropar modellverifiering.

En lista över alla tillgängliga metoder och egenskaper finns i ControllerBase.

Attributes

Namnområdet Microsoft.AspNetCore.Mvc innehåller attribut som kan användas för att konfigurera beteendet för webb-API-kontrollanter och åtgärdsmetoder. I följande exempel används attribut för att ange http-åtgärdsverb som stöds och eventuella kända HTTP-statuskoder som kan returneras:

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

Här är några fler exempel på attribut som är tillgängliga.

Attribute Notes
[Route] Anger URL-mönster för en kontrollant eller åtgärd.
[Bind] Anger prefix och egenskaper som ska inkluderas för modellbindning.
[HttpGet] Identifierar en åtgärd som stöder HTTP GET-åtgärdsverb.
[Consumes] Anger datatyper som en åtgärd accepterar.
[Produces] Anger datatyper som en åtgärd returnerar.

En lista som innehåller de tillgängliga attributen finns i Microsoft.AspNetCore.Mvc namnområdet.

ApiController-attribut

Attributet [ApiController] kan tillämpas på en kontrollantklass för att aktivera följande åsiktsbaserade, API-specifika beteenden:

Attribut på specifika kontrollanter

Attributet [ApiController] kan tillämpas på specifika kontrollanter, som i följande exempel från projektmallen:

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

Attribut på flera kontrollanter

En metod för att använda attributet på mer än en kontrollant är att skapa en anpassad baskontrollantklass som kommenterats med [ApiController] attributet. I följande exempel visas en anpassad basklass och en kontrollant som härleds från den:

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

Attribut för en sammansättning

Attributet [ApiController] kan tillämpas på en sammansättning. Anteckningar på det här sättet tillämpar webb-API-beteendet på alla kontrollanter i sammansättningen. Det finns inget sätt att välja bort enskilda kontrollanter. Använd attributet på sammansättningsnivå för namnområdesdeklarationen Startup som omger klassen:

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

Krav för attributroutning

Attributet [ApiController] gör attributroutning till ett krav. Till exempel:

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

Åtgärder är otillgängliga via konventionella vägar som definieras av UseEndpoints, UseMvceller UseMvcWithDefaultRoute i Startup.Configure.

Automatiska HTTP 400-svar

Attributet [ApiController] gör att modellverifieringsfel automatiskt utlöser ett HTTP 400-svar. Följande kod är därför onödig i en åtgärdsmetod:

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

ASP.NET Core MVC använder åtgärdsfiltret ModelStateInvalidFilter för att göra föregående kontroll.

Standardsvar för BadRequest

Följande begärandetext är ett exempel på den serialiserade typen:

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

Standardsvarstypen för ett HTTP 400-svar är ValidationProblemDetails. Följande begärandetext är ett exempel på den serialiserade typen:

{
  "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."
    ]
  }
}

Typ ValidationProblemDetails :

Om du vill göra automatiska och anpassade svar konsekventa anropar du ValidationProblem metoden i stället BadRequestför . ValidationProblem returnerar ett ValidationProblemDetails objekt samt det automatiska svaret.

Logga automatiska 400-svar

Om du vill logga automatiska 400-svar anger du InvalidModelStateResponseFactory egenskapen delegate för att utföra anpassad bearbetning i Startup.ConfigureServices. Som standard InvalidModelStateResponseFactory används ProblemDetailsFactory för att skapa en instans av ValidationProblemDetails.

I följande exempel visas hur du hämtar en instans av ILogger<TCategoryName> för att logga information om ett automatiskt 400-svar:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        // To preserve the default behavior, capture the original delegate to call later.
        var builtInFactory = options.InvalidModelStateResponseFactory;

        options.InvalidModelStateResponseFactory = context =>
        {
            var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Startup>>();

            // Perform logging here.
            // ...

            // Invoke the default behavior, which produces a ValidationProblemDetails response.
            // To produce a custom response, return a different implementation of IActionResult instead.
            return builtInFactory(context);
        };
    });

Inaktivera automatiskt 400-svar

Om du vill inaktivera det automatiska 400-beteendet anger du SuppressModelStateInvalidFilter egenskapen till true. Lägg till följande markerade kod i Startup.ConfigureServices:

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

Bindning av källparameterinferens

Ett attribut för bindningskälla definierar den plats där värdet för en åtgärdsparameter hittas. Följande bindningskällaattribut finns:

Attribute Bindningskälla
[FromBody] begäranens innehåll
[FromForm] Formulärdata i begärandetexten
[FromHeader] Begärandehuvud
[FromQuery] Frågesträngsparameter för begäran
[FromRoute] Skicka vidare data från den aktuella begäran
[FromServices] Begärandetjänsten som matas in som en åtgärdsparameter

Warning

Använd [FromRoute] inte när värden kan innehålla %2f (alltså /). %2f kommer inte att tas bort från /. Använd [FromQuery] om värdet kan innehålla %2f.

[ApiController] Utan attributet eller bindningskällans attribut som [FromQuery]försöker ASP.NET Core-körningen använda den komplexa objektmodellbindningen. Den komplexa objektmodellbindningen hämtar data från värdeprovidrar i en definierad ordning.

I följande exempel [FromQuery] anger attributet att discontinuedOnly parametervärdet anges i frågesträngen för begärande-URL:en:

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

Attributet [ApiController] tillämpar slutsatsdragningsregler för standarddatakällorna för åtgärdsparametrar. Dessa regler sparar dig från att behöva identifiera bindningskällor manuellt genom att tillämpa attribut på åtgärdsparametrarna. Bindningskällans slutsatsdragningsregler fungerar på följande sätt:

  • [FromBody] härleds för komplexa typparametrar. Ett undantag från slutsatsdragningsregeln [FromBody] är alla komplexa, inbyggda typer med en särskild betydelse, till exempel IFormCollection och CancellationToken. Inferenskoden för bindningskällan ignorerar dessa specialtyper.
  • [FromForm] härleds för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Det härleds inte för några enkla eller användardefinierade typer.
  • [FromRoute] härleds för alla åtgärdsparameternamn som matchar en parameter i routningsmallen. När mer än en väg matchar en åtgärdsparameter betraktas alla routningsvärden som [FromRoute].
  • [FromQuery] härleds för vilka som helst andra åtgärdsparametrar.

FromBody-slutsatsdragningsanteckningar

[FromBody] härleds inte för enkla typer som string eller int. Därför [FromBody] bör attributet användas för enkla typer när den funktionen behövs.

När en åtgärd har fler än en parameter som är bunden från begärandetexten genereras ett undantag. Till exempel orsakar signaturerna för alla följande åtgärdsmetoder ett undantag:

  • [FromBody] härleds på båda eftersom de är komplexa typer.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] attributet på den ena, härleds på den andra eftersom det är en komplex typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] attribut på båda.

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

Inaktivera slutsatsdragningsregler

Om du vill inaktivera bindningskällans slutsatsdragning anger du SuppressInferBindingSourcesForParameters till true. Lägg till följande kod i Startup.ConfigureServices:

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

Bearbetning av multipart/form-data-begäranden

Attributet [ApiController] tillämpar en slutsatsdragningsregel för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Innehållstypen multipart/form-data för begäran härleds för dessa typer.

Om du vill inaktivera standardbeteendet anger du SuppressConsumesConstraintForFormFileParameters egenskapen till true i Startup.ConfigureServices:

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

Probleminformation för felstatuskoder

MVC transformerar ett felresultat (ett resultat med statuskod 400 eller senare) till ett resultat med ProblemDetails. Typen ProblemDetails baseras på RFC 7807-specifikationen för att tillhandahålla maskinläsbar felinformation i ett HTTP-svar.

Överväg följande kod i en kontrollantåtgärd:

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

Metoden NotFound genererar en HTTP 404-statuskod med en ProblemDetails brödtext. Till exempel:

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

Inaktivera ProblemDetails-svar

Automatiskt skapande av en ProblemDetails för felstatuskoder inaktiveras när egenskapen SuppressMapClientErrors är inställd på true. Lägg till följande kod i Startup.ConfigureServices:

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

Definiera innehållstyper för begäranden som stöds med attributet [Förbrukar]

Som standard stöder en åtgärd alla tillgängliga innehållstyper för begäranden. Om en app till exempel har konfigurerats för att stödja både JSON- och XML-indataformaterare stöder en åtgärd flera innehållstyper, inklusive application/json och application/xml.

Attributet [Förbrukar] tillåter en åtgärd för att begränsa innehållstyperna för begäranden som stöds. [Consumes] Använd attributet för en åtgärd eller kontrollant och ange en eller flera innehållstyper:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

I föregående kod anger åtgärden CreateProduct innehållstypen application/xml. Begäranden som dirigeras till den här åtgärden måste ange ett Content-Type huvud för application/xml. Begäranden som inte specificerar en Content-Type-rubrik resulterar i ett svar med application/xml.

Attributet [Consumes] gör också att en åtgärd kan påverka dess val baserat på en inkommande begärans innehållstyp genom att tillämpa en typbegränsning. Tänk på följande exempel:

[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
    [HttpPost]
    [Consumes("application/json")]
    public IActionResult PostJson(IEnumerable<int> values) =>
        Ok(new { Consumes = "application/json", Values = values });

    [HttpPost]
    [Consumes("application/x-www-form-urlencoded")]
    public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
        Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}

I föregående kod ConsumesController är konfigurerad för att hantera begäranden som skickas till https://localhost:5001/api/Consumes URL:en. Båda åtgärderna, PostJson och PostForm, i kontrollern hanterar POST-begäranden med samma URL. Utan att [Consumes] attributet tillämpar en typbegränsning genereras ett tvetydigt matchningsfel.

Attributet [Consumes] tillämpas på båda åtgärderna. Åtgärden PostJson hanterar begäranden som skickas med rubriken Content-Typeapplication/json. Åtgärden PostForm hanterar begäranden som skickas med rubriken Content-Typeapplication/x-www-form-urlencoded.

Ytterligare resurser

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

Skapa inte en webb-API-kontrollant genom att härleda från Controller klassen. Controller härleds från ControllerBase och lägger till stöd för vyer, så det är för att hantera webbsidor, inte webb-API-begäranden. Det finns ett undantag till den här regeln: om du planerar att använda samma kontrollant för både vyer och webb-API:er härleder du den från Controller. Klassen ControllerBase innehåller många egenskaper och metoder som är användbara för att hantera HTTP-begäranden. Returnerar till exempel ControllerBase.CreatedAtAction en statuskod för 201:

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

Här följer några fler exempel på metoder som ControllerBase tillhandahåller:

Method Notes
BadRequest Returnerar statuskoden 400.
NotFound Returnerar statuskoden 404.
PhysicalFile Returnerar en fil.
TryUpdateModelAsync Anropar modellbindning.
TryValidateModel Anropar modellverifiering.

En lista över alla tillgängliga metoder och egenskaper finns i ControllerBase.

Attributes

Namnområdet Microsoft.AspNetCore.Mvc innehåller attribut som kan användas för att konfigurera beteendet för webb-API-kontrollanter och åtgärdsmetoder. I följande exempel används attribut för att ange http-åtgärdsverb som stöds och eventuella kända HTTP-statuskoder som kan returneras:

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

Här är några fler exempel på attribut som är tillgängliga:

Attribute Notes
[Route] Anger URL-mönster för en kontrollant eller åtgärd.
[Bind] Anger prefix och egenskaper som ska inkluderas för modellbindning.
[HttpGet] Identifierar en åtgärd som stöder HTTP GET-åtgärdsverb.
[Consumes] Anger datatyper som en åtgärd accepterar.
[Produces] Anger datatyper som en åtgärd returnerar.

En lista som innehåller de tillgängliga attributen finns i Microsoft.AspNetCore.Mvc namnområdet.

ApiController-attribut

Attributet [ApiController] kan tillämpas på en kontrollantklass för att aktivera följande åsiktsbaserade, API-specifika beteenden:

Attribut på specifika kontrollanter

Attributet [ApiController] kan tillämpas på specifika kontrollanter, som i följande exempel från projektmallen:

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

Attribut på flera kontrollanter

En metod för att använda attributet på mer än en kontrollant är att skapa en anpassad baskontrollantklass som kommenterats med [ApiController] attributet. I följande exempel visas en anpassad basklass och en kontrollant som härleds från den:

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

Attribut för en sammansättning

Om kompatibilitetsversionen är inställd på 2.2 eller senare [ApiController] kan attributet tillämpas på en sammansättning. Anteckningar på det här sättet tillämpar webb-API-beteendet på alla kontrollanter i sammansättningen. Det finns inget sätt att välja bort enskilda kontrollanter. Använd attributet på sammansättningsnivå för namnområdesdeklarationen Startup som omger klassen:

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

Krav för attributroutning

Attributet [ApiController] gör attributroutning till ett krav. Till exempel:

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

Åtgärder är otillgängliga via konventionella vägar som definieras av UseMvc eller UseMvcWithDefaultRoute i Startup.Configure.

Automatiska HTTP 400-svar

Attributet [ApiController] gör att modellverifieringsfel automatiskt utlöser ett HTTP 400-svar. Följande kod är därför onödig i en åtgärdsmetod:

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

ASP.NET Core MVC använder åtgärdsfiltret ModelStateInvalidFilter för att göra föregående kontroll.

Standardsvar för BadRequest

Med en kompatibilitetsversion av 2.1 är SerializableErrorstandardsvarstypen för ett HTTP 400-svar . Följande begärandetext är ett exempel på den serialiserade typen:

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

Med en kompatibilitetsversion av 2.2 eller senare är ValidationProblemDetailsstandardsvarstypen för ett HTTP 400-svar . Följande begärandetext är ett exempel på den serialiserade typen:

{
  "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."
    ]
  }
}

Typ ValidationProblemDetails :

Om du vill göra automatiska och anpassade svar konsekventa anropar du ValidationProblem metoden i stället BadRequestför . ValidationProblem returnerar ett ValidationProblemDetails objekt samt det automatiska svaret.

Logga automatiska 400-svar

Se följande för information om hur man loggar automatiska 400-svar vid modellvalideringsfel (dotnet/AspNetCore.Docs#12157).

Inaktivera automatiskt 400-svar

Om du vill inaktivera det automatiska 400-beteendet anger du SuppressModelStateInvalidFilter egenskapen till true. Lägg till följande markerade kod i Startup.ConfigureServices:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Bindning av källparameterinferens

Ett attribut för bindningskälla definierar den plats där värdet för en åtgärdsparameter hittas. Följande bindningskällaattribut finns:

Attribute Bindningskälla
[FromBody] begäranens innehåll
[FromForm] Formulärdata i begärandetexten
[FromHeader] Begärandehuvud
[FromQuery] Frågesträngsparameter för begäran
[FromRoute] Skicka vidare data från den aktuella begäran
[FromServices] Begärandetjänsten som matas in som en åtgärdsparameter

Warning

Använd [FromRoute] inte när värden kan innehålla %2f (alltså /). %2f kommer inte att tas bort från /. Använd [FromQuery] om värdet kan innehålla %2f. [ApiController] Utan attributet eller bindningskällans attribut som [FromQuery]försöker ASP.NET Core-körningen använda den komplexa objektmodellbindningen. Den komplexa objektmodellbindningen hämtar data från värdeprovidrar i en definierad ordning.

I följande exempel [FromQuery] anger attributet att discontinuedOnly parametervärdet anges i frågesträngen för begärande-URL:en:

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

Attributet [ApiController] tillämpar slutsatsdragningsregler för standarddatakällorna för åtgärdsparametrar. Dessa regler sparar dig från att behöva identifiera bindningskällor manuellt genom att tillämpa attribut på åtgärdsparametrarna. Bindningskällans slutsatsdragningsregler fungerar på följande sätt:

  • [FromBody] härleds för komplexa typparametrar. Ett undantag från slutsatsdragningsregeln [FromBody] är alla komplexa, inbyggda typer med en särskild betydelse, till exempel IFormCollection och CancellationToken. Inferenskoden för bindningskällan ignorerar dessa specialtyper.
  • [FromForm] härleds för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Det härleds inte för några enkla eller användardefinierade typer.
  • [FromRoute] härleds för alla åtgärdsparameternamn som matchar en parameter i routningsmallen. När mer än en väg matchar en åtgärdsparameter betraktas alla routningsvärden som [FromRoute].
  • [FromQuery] härleds för vilka som helst andra åtgärdsparametrar.

FromBody-slutsatsdragningsanteckningar

[FromBody] härleds inte för enkla typer som string eller int. Därför [FromBody] bör attributet användas för enkla typer när den funktionen behövs.

När en åtgärd har fler än en parameter som är bunden från begärandetexten genereras ett undantag. Till exempel orsakar signaturerna för alla följande åtgärdsmetoder ett undantag:

  • [FromBody] härleds på båda eftersom de är komplexa typer.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] attributet på den ena, härleds på den andra eftersom det är en komplex typ.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] attribut på båda.

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

Note

I ASP.NET Core 2.1 härleds parametrar av samlingstyp som listor och matriser felaktigt som [FromQuery]. Attributet [FromBody] ska användas för dessa parametrar om de ska bindas från begärandetexten. Det här beteendet korrigeras i ASP.NET Core 2.2 eller senare, där parametrar av samlingstyp härleds att vara bundna från brödtexten som standard.

Inaktivera slutsatsdragningsregler

Om du vill inaktivera bindningskällans slutsatsdragning anger du SuppressInferBindingSourcesForParameters till true. Lägg till följande kod i Startup.ConfigureServices:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Bearbetning av multipart/form-data-begäranden

Attributet [ApiController] tillämpar en slutsatsdragningsregel för åtgärdsparametrar av typen IFormFile och IFormFileCollection. Innehållstypen multipart/form-data för begäran härleds för dessa typer. Om du vill inaktivera standardbeteendet anger du SuppressConsumesConstraintForFormFileParameters egenskapen till true i Startup.ConfigureServices:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

Probleminformation för felstatuskoder

När kompatibilitetsversionen är 2.2 eller senare omvandlar MVC ett felresultat (ett resultat med statuskod 400 eller senare) till ett resultat med ProblemDetails. Typen ProblemDetails baseras på RFC 7807-specifikationen för att tillhandahålla maskinläsbar felinformation i ett HTTP-svar. Överväg följande kod i en kontrollantåtgärd:

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

Metoden NotFound genererar en HTTP 404-statuskod med en ProblemDetails brödtext. Till exempel:

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

Inaktivera ProblemDetails-svar

Automatiskt skapande av en ProblemDetails för felstatuskoder inaktiveras när egenskapen SuppressMapClientErrors är inställd på true. Lägg till följande kod i Startup.ConfigureServices:

Definiera innehållstyper för begäranden som stöds med attributet [Förbrukar]

Som standard stöder en åtgärd alla tillgängliga innehållstyper för begäranden. Om en app till exempel har konfigurerats för att stödja både JSON- och XML-indataformaterare stöder en åtgärd flera innehållstyper, inklusive application/json och application/xml.

Attributet [Förbrukar] tillåter en åtgärd för att begränsa innehållstyperna för begäranden som stöds. [Consumes] Använd attributet för en åtgärd eller kontrollant och ange en eller flera innehållstyper:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

I föregående kod anger åtgärden CreateProduct innehållstypen application/xml. Begäranden som dirigeras till den här åtgärden måste ange ett Content-Type huvud för application/xml. Begäranden som inte specificerar en Content-Type-rubrik resulterar i ett svar med application/xml. Attributet [Consumes] gör också att en åtgärd kan påverka dess val baserat på en inkommande begärans innehållstyp genom att tillämpa en typbegränsning. Tänk på följande exempel:

[ApiController]
[Route("api/[controller]")]
public class ConsumesController : ControllerBase
{
    [HttpPost]
    [Consumes("application/json")]
    public IActionResult PostJson(IEnumerable<int> values) =>
        Ok(new { Consumes = "application/json", Values = values });

    [HttpPost]
    [Consumes("application/x-www-form-urlencoded")]
    public IActionResult PostForm([FromForm] IEnumerable<int> values) =>
        Ok(new { Consumes = "application/x-www-form-urlencoded", Values = values });
}

I föregående kod ConsumesController är konfigurerad för att hantera begäranden som skickas till https://localhost:5001/api/Consumes URL:en. Båda åtgärderna, PostJson och PostForm, i kontrollern hanterar POST-begäranden med samma URL. Utan att [Consumes] attributet tillämpar en typbegränsning genereras ett tvetydigt matchningsfel. Attributet [Consumes] tillämpas på båda åtgärderna. Åtgärden PostJson hanterar begäranden som skickas med rubriken Content-Typeapplication/json. Åtgärden PostForm hanterar begäranden som skickas med rubriken Content-Typeapplication/x-www-form-urlencoded.

Ytterligare resurser