Delen via


Web-API's maken met ASP.NET Core

ASP.NET Core ondersteunt het maken van web-API's met behulp van controllers of het gebruik van minimale API's. Controllers in een web-API zijn klassen die zijn afgeleid van ControllerBase. Controllers worden per aanvraag geactiveerd en verwijderd.

In dit artikel wordt beschreven hoe u controllers gebruikt voor het verwerken van web-API-aanvragen. Zie Zelfstudie: Een minimale API maken met ASP.NET Core voor meer informatie over het maken van web-API's zonder controllers.

ControllerBase class

Een web-API op basis van een controller bestaat uit een of meer controllerklassen die zijn afgeleid van ControllerBase. De web-API-projectsjabloon biedt een starterscontroller:

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

Web-API-controllers moeten doorgaans worden afgeleid van ControllerBase in plaats van Controller. Controller is afgeleid van ControllerBase en voegt ondersteuning toe voor weergaven, dus voor het verwerken van webpagina's, niet voor web-API-aanvragen. Als dezelfde controller weergaven en web-API's moet ondersteunen, afgeleid van Controller.

De ControllerBase-klasse biedt veel eigenschappen en methoden die handig zijn voor het verwerken van HTTP-aanvragen. Retourneert bijvoorbeeld CreatedAtAction een 201-statuscode:

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

De volgende tabel bevat voorbeelden van methoden in ControllerBase.

Method Notes
BadRequest Retourneert 400 statuscode.
NotFound Retourneert de 404-statuscode.
PhysicalFile Retourneert een bestand.
TryUpdateModelAsync Roept modelbinding aan.
TryValidateModel Roept modelvalidatie aan.

Zie voor een lijst met alle beschikbare methoden en eigenschappen ControllerBase.

Attributes

De Microsoft.AspNetCore.Mvc naamruimte bevat kenmerken die kunnen worden gebruikt om het gedrag van web-API-controllers en actiemethoden te configureren. In het volgende voorbeeld worden kenmerken gebruikt om het ondersteunde HTTP-actiewoord en eventuele bekende HTTP-statuscodes op te geven die kunnen worden geretourneerd:

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

Hier volgen nog enkele voorbeelden van kenmerken die beschikbaar zijn.

Attribute Notes
[Route] Hiermee geeft u een URL-patroon voor een controller of actie op.
[Bind] Hiermee geeft u het voorvoegsel en de eigenschappen op die moeten worden opgenomen voor modelbinding.
[HttpGet] Identificeert een actie die ondersteuning biedt voor het HTTP GET-actiewoord.
[Consumes] Hiermee geeft u gegevenstypen op die een actie accepteert.
[Produces] Hiermee geeft u gegevenstypen op die een actie retourneert.

Zie de Microsoft.AspNetCore.Mvc naamruimte voor een lijst met de beschikbare kenmerken.

ApiController attribute

Het [ApiController] kenmerk kan worden toegepast op een controllerklasse om het volgende, api-specifieke gedrag mogelijk te maken:

Kenmerk op specifieke controllers

Het [ApiController] kenmerk kan worden toegepast op specifieke controllers, zoals in het volgende voorbeeld van de projectsjabloon:

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

Kenmerk op meerdere controllers

Een benadering voor het gebruik van het kenmerk op meer dan één controller is het maken van een aangepaste basiscontrollerklasse die is geannoteerd met het [ApiController] kenmerk. In het volgende voorbeeld ziet u een aangepaste basisklasse en een controller die hiervan is afgeleid:

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

Kenmerk voor een assembly

Het [ApiController] kenmerk kan worden toegepast op een assembly. Wanneer het [ApiController] kenmerk wordt toegepast op een assembly, worden voor alle controllers in de assembly het [ApiController] kenmerk toegepast. U kunt zich niet afmelden voor afzonderlijke controllers. Pas het kenmerk assemblyniveau toe op het Program.cs bestand:

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

Vereiste voor kenmerkroutering

Het [ApiController] kenmerk maakt kenmerkroutering een vereiste. For example:

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

Acties zijn niet toegankelijk via conventionele routes die zijn gedefinieerd door UseEndpoints, UseMvcof UseMvcWithDefaultRoute.

Automatische HTTP 400-antwoorden

Met [ApiController] het kenmerk worden modelvalidatiefouten automatisch een HTTP 400-antwoord geactiveerd. Daarom is de volgende code niet nodig in een actiemethode:

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

ASP.NET Core MVC gebruikt het ModelStateInvalidFilter actiefilter om de voorgaande controle uit te voeren.

Standaard BadRequest-antwoord

Het standaardantwoordtype voor een HTTP 400-antwoord is ValidationProblemDetails. De volgende antwoordtekst is een voorbeeld van het geserialiseerde 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."
    ]
  }
}

Het ValidationProblemDetails type:

  • Biedt een door de machine leesbare indeling voor het opgeven van fouten in web-API-antwoorden.
  • Voldoet aan de RFC 7807-specificatie.

Als u automatische en aangepaste antwoorden consistent wilt maken, roept u de ValidationProblem methode aan in plaats van BadRequest. ValidationProblem retourneert een ValidationProblemDetails object en het automatische antwoord.

Automatische 400-antwoorden registreren

Als u automatische 400 antwoorden wilt registreren, stelt u de InvalidModelStateResponseFactory eigenschap gedelegeerde in om aangepaste verwerking uit te voeren. Maakt ProblemDetailsFactory standaard InvalidModelStateResponseFactory een exemplaar van ValidationProblemDetails.

In het volgende voorbeeld ziet u hoe u een exemplaar ophaalt van het vastleggen van ILogger<TCategoryName> informatie over een automatische 400-respons:

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

Automatische 400-respons uitschakelen

Als u het automatische 400-gedrag wilt uitschakelen, stelt u de SuppressModelStateInvalidFilter eigenschap in op true. Voeg de volgende gemarkeerde code toe:

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

Deductie van bindingsbronparameter

Een bindingsbronkenmerk definieert de locatie waarop de waarde van een actieparameter wordt gevonden. De volgende bindingsbronkenmerken bestaan:

Attribute Binding source
[FromBody] Request body
[FromForm] Formuliergegevens in de hoofdtekst van de aanvraag
[FromHeader] Request header
[FromQuery] Queryreeksparameter aanvragen
[FromRoute] Gegevens routeren vanuit de huidige aanvraag
[FromServices] De aanvraagservice die is geïnjecteerd als een actieparameter
[AsParameters] Method parameters

Warning

Gebruik niet wanneer waarden mogelijk bevatten %2f (dat wil /wel[FromRoute]). %2f zal niet ongezichtbaar zijn voor /. Gebruik [FromQuery] deze optie als de waarde mogelijk bevat %2f.

Zonder het kenmerk of de [ApiController] bindingsbronkenmerken, zoals [FromQuery], probeert de ASP.NET Core-runtime de binder van het complexe objectmodel te gebruiken. De binder voor het complexe objectmodel haalt gegevens op uit waardeproviders in een gedefinieerde volgorde.

In het volgende voorbeeld geeft het [FromQuery] kenmerk aan dat de discontinuedOnly parameterwaarde is opgegeven in de queryreeks van de aanvraag-URL:

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

Het [ApiController] kenmerk past deductieregels toe voor de standaardgegevensbronnen van actieparameters. Met deze regels hoeft u geen bindingsbronnen handmatig te identificeren door kenmerken toe te passen op de actieparameters. De regels voor bindingsbrondeductie gedragen zich als volgt:

  • [FromServices] wordt afgeleid voor complexe typeparameters die zijn geregistreerd in de DI-container.
  • [FromBody] wordt afgeleid voor complexe typeparameters die niet zijn geregistreerd in de DI-container. Een uitzondering op de deductieregel [FromBody] is een complex, ingebouwd type met een speciale betekenis, zoals IFormCollection en CancellationToken. De code voor bindingsbrondeductie negeert deze speciale typen.
  • [FromForm] wordt afgeleid voor actieparameters van het type IFormFile en IFormFileCollection. Het wordt niet afgeleid voor eenvoudige of door de gebruiker gedefinieerde typen.
  • [FromRoute] wordt afgeleid voor elke actieparameternaam die overeenkomt met een parameter in de routesjabloon. Wanneer meer dan één route overeenkomt met een actieparameter, wordt elke routewaarde als beschouwd [FromRoute].
  • [FromQuery] wordt afgeleid voor andere actieparameters.

VanBody-deductienotities

[FromBody] wordt niet afgeleid voor eenvoudige typen, zoals string of int. Daarom moet het [FromBody] kenmerk worden gebruikt voor eenvoudige typen wanneer die functionaliteit nodig is.

Wanneer een actie meer dan één parameter heeft die afhankelijk is van de aanvraagbody, wordt er een uitzondering gegenereerd. Alle handtekeningen van de volgende actiemethoden veroorzaken bijvoorbeeld een uitzondering:

  • [FromBody] afgeleid van beide omdat ze complexe typen zijn.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] kenmerk op de ene, afgeleid van het andere omdat het een complex type is.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] kenmerk op beide.

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

FromServices-deductienotities

Parameterbinding verbindt parameters via afhankelijkheidsinjectie wanneer het type is geconfigureerd als een service. Dit betekent dat het niet verplicht is om het [FromServices] kenmerk expliciet toe te passen op een parameter. In de volgende code retourneren beide acties de tijd:

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

In zeldzame gevallen kan automatische DI apps verbreken die een type DI hebben dat ook wordt geaccepteerd in de actiemethoden van een API-controller. Het is niet gebruikelijk om een type in DI te hebben en als argument in een API-controlleractie.

Als u deductie voor één actieparameter wilt uitschakelen [FromServices] , past u het gewenste bindingsbronkenmerk toe op de parameter. Pas bijvoorbeeld het [FromBody] kenmerk toe op een actieparameter die afhankelijk moet zijn van de hoofdtekst van de aanvraag.

Als u deductie globaal wilt uitschakelen [FromServices] , stelt u DisableImplicitFromServicesParameters in op 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();

Typen worden gecontroleerd bij het opstarten van de app om IServiceProviderIsService te bepalen of een argument in een API-controlleractie afkomstig is van DI of van de andere bronnen.

Het mechanisme voor het afleiden van de bindingsbron van de actieparameters van de API-controller gebruikt de volgende regels:

Deductieregels uitschakelen

Als u bindingsbrondeductie wilt uitschakelen, stelt u het SuppressInferBindingSourcesForParameters volgende truein:

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

Deductie van aanvraag voor meerdere onderdelen/formuliergegevens

Het [ApiController] kenmerk past een deductieregel toe voor actieparameters van het type IFormFile en IFormFileCollection. Het inhoudstype van de multipart/form-data aanvraag wordt afgeleid voor deze typen.

Als u het standaardgedrag wilt uitschakelen, stelt u de SuppressConsumesConstraintForFormFileParameters eigenschap truein op:

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

Probleemdetails voor foutcodes

MVC transformeert een foutresultaat (een resultaat met statuscode 400 of hoger) naar een resultaat met ProblemDetails. Het ProblemDetails type is gebaseerd op de RFC 7807-specificatie voor het leveren van machineleesbare foutdetails in een HTTP-antwoord.

Houd rekening met de volgende code in een controlleractie:

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

De NotFound methode produceert een HTTP 404-statuscode met een ProblemDetails hoofdtekst. For example:

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

ProblemDetails-antwoord uitschakelen

Het automatisch maken van een ProblemDetails voor foutcodes is uitgeschakeld wanneer de SuppressMapClientErrors eigenschap is ingesteld op true. Voeg de volgende code toe:

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

Ondersteunde aanvraaginhoudstypen definiëren met het kenmerk [Verbruikt]

Standaard ondersteunt een actie alle beschikbare aanvraaginhoudstypen. Als een app bijvoorbeeld is geconfigureerd ter ondersteuning van zowel JSON- als XML-invoerindelingen, ondersteunt een actie meerdere inhoudstypen, waaronder application/json en application/xml.

Met het kenmerk [Verbruiken] kan een actie de ondersteunde inhoudstypen voor aanvragen beperken. Pas het [Consumes] kenmerk toe op een actie of controller, waarbij een of meer inhoudstypen worden opgegeven:

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

In de voorgaande code geeft de CreateProduct actie het inhoudstype application/xmlop. Aanvragen die naar deze actie worden doorgestuurd, moeten een Content-Type header van application/xml. Aanvragen die geen header van het resultaat opgeven Content-Type in een reactie van application/xml415 niet-ondersteund mediatype .

Met [Consumes] het kenmerk kan een actie de selectie ervan beïnvloeden op basis van het inhoudstype van een binnenkomende aanvraag door een typebeperking toe te passen. Bekijk het volgende voorbeeld:

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

In de voorgaande code ConsumesController is geconfigureerd voor het verwerken van aanvragen die naar de https://localhost:5001/api/Consumes URL worden verzonden. Beide acties PostJson van de controller en PostFormverwerken POST-aanvragen met dezelfde URL. Zonder het [Consumes] kenmerk dat een typebeperking toepast, wordt er een dubbelzinnige overeenkomst-uitzondering gegenereerd.

Het [Consumes] kenmerk wordt toegepast op beide acties. De PostJson actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/json. De PostForm actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/x-www-form-urlencoded.

Additional resources

ASP.NET Core ondersteunt het maken van web-API's met behulp van controllers of het gebruik van minimale API's. Controllers in een web-API zijn klassen die zijn afgeleid van ControllerBase. In dit artikel wordt beschreven hoe u controllers gebruikt voor het verwerken van web-API-aanvragen. Zie Zelfstudie: Een minimale API maken met ASP.NET Core voor meer informatie over het maken van web-API's zonder controllers.

ControllerBase class

Een web-API op basis van een controller bestaat uit een of meer controllerklassen die zijn afgeleid van ControllerBase. De web-API-projectsjabloon biedt een starterscontroller:

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

Web-API-controllers moeten doorgaans worden afgeleid van ControllerBase in plaats van Controller. Controller is afgeleid van ControllerBase en voegt ondersteuning toe voor weergaven, dus voor het verwerken van webpagina's, niet voor web-API-aanvragen. Als dezelfde controller weergaven en web-API's moet ondersteunen, afgeleid van Controller.

De ControllerBase-klasse biedt veel eigenschappen en methoden die handig zijn voor het verwerken van HTTP-aanvragen. Retourneert bijvoorbeeld CreatedAtAction een 201-statuscode:

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

De volgende tabel bevat voorbeelden van methoden in ControllerBase.

Method Notes
BadRequest Retourneert 400 statuscode.
NotFound Retourneert de 404-statuscode.
PhysicalFile Retourneert een bestand.
TryUpdateModelAsync Roept modelbinding aan.
TryValidateModel Roept modelvalidatie aan.

Zie voor een lijst met alle beschikbare methoden en eigenschappen ControllerBase.

Attributes

De Microsoft.AspNetCore.Mvc naamruimte bevat kenmerken die kunnen worden gebruikt om het gedrag van web-API-controllers en actiemethoden te configureren. In het volgende voorbeeld worden kenmerken gebruikt om het ondersteunde HTTP-actiewoord en eventuele bekende HTTP-statuscodes op te geven die kunnen worden geretourneerd:

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

Hier volgen nog enkele voorbeelden van kenmerken die beschikbaar zijn.

Attribute Notes
[Route] Hiermee geeft u een URL-patroon voor een controller of actie op.
[Bind] Hiermee geeft u het voorvoegsel en de eigenschappen op die moeten worden opgenomen voor modelbinding.
[HttpGet] Identificeert een actie die ondersteuning biedt voor het HTTP GET-actiewoord.
[Consumes] Hiermee geeft u gegevenstypen op die een actie accepteert.
[Produces] Hiermee geeft u gegevenstypen op die een actie retourneert.

Zie de Microsoft.AspNetCore.Mvc naamruimte voor een lijst met de beschikbare kenmerken.

ApiController attribute

Het [ApiController] kenmerk kan worden toegepast op een controllerklasse om het volgende, api-specifieke gedrag mogelijk te maken:

Kenmerk op specifieke controllers

Het [ApiController] kenmerk kan worden toegepast op specifieke controllers, zoals in het volgende voorbeeld van de projectsjabloon:

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

Kenmerk op meerdere controllers

Een benadering voor het gebruik van het kenmerk op meer dan één controller is het maken van een aangepaste basiscontrollerklasse die is geannoteerd met het [ApiController] kenmerk. In het volgende voorbeeld ziet u een aangepaste basisklasse en een controller die hiervan is afgeleid:

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

Kenmerk voor een assembly

Het [ApiController] kenmerk kan worden toegepast op een assembly. Wanneer het [ApiController] kenmerk wordt toegepast op een assembly, worden voor alle controllers in de assembly het [ApiController] kenmerk toegepast. U kunt zich niet afmelden voor afzonderlijke controllers. Pas het kenmerk assemblyniveau toe op het Program.cs bestand:

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

Vereiste voor kenmerkroutering

Het [ApiController] kenmerk maakt kenmerkroutering een vereiste. For example:

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

Acties zijn niet toegankelijk via conventionele routes die zijn gedefinieerd door UseEndpoints, UseMvcof UseMvcWithDefaultRoute.

Automatische HTTP 400-antwoorden

Met [ApiController] het kenmerk worden modelvalidatiefouten automatisch een HTTP 400-antwoord geactiveerd. Daarom is de volgende code niet nodig in een actiemethode:

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

ASP.NET Core MVC gebruikt het ModelStateInvalidFilter actiefilter om de voorgaande controle uit te voeren.

Standaard BadRequest-antwoord

De volgende antwoordtekst is een voorbeeld van het geserialiseerde type:

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

Het standaardantwoordtype voor een HTTP 400-antwoord is ValidationProblemDetails. De volgende antwoordtekst is een voorbeeld van het geserialiseerde 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."
    ]
  }
}

Het ValidationProblemDetails type:

  • Biedt een door de machine leesbare indeling voor het opgeven van fouten in web-API-antwoorden.
  • Voldoet aan de RFC 7807-specificatie.

Als u automatische en aangepaste antwoorden consistent wilt maken, roept u de ValidationProblem methode aan in plaats van BadRequest. ValidationProblem retourneert een ValidationProblemDetails object en het automatische antwoord.

Automatische 400-antwoorden registreren

Als u automatische 400 antwoorden wilt registreren, stelt u de InvalidModelStateResponseFactory eigenschap gedelegeerde in om aangepaste verwerking uit te voeren. Maakt ProblemDetailsFactory standaard InvalidModelStateResponseFactory een exemplaar van ValidationProblemDetails.

In het volgende voorbeeld ziet u hoe u een exemplaar ophaalt van het vastleggen van ILogger<TCategoryName> informatie over een automatische 400-respons:

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

Automatische 400-respons uitschakelen

Als u het automatische 400-gedrag wilt uitschakelen, stelt u de SuppressModelStateInvalidFilter eigenschap in op true. Voeg de volgende gemarkeerde code toe:

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

Deductie van bindingsbronparameter

Een bindingsbronkenmerk definieert de locatie waarop de waarde van een actieparameter wordt gevonden. De volgende bindingsbronkenmerken bestaan:

Attribute Binding source
[FromBody] Request body
[FromForm] Formuliergegevens in de hoofdtekst van de aanvraag
[FromHeader] Request header
[FromQuery] Queryreeksparameter aanvragen
[FromRoute] Gegevens routeren vanuit de huidige aanvraag
[FromServices] De aanvraagservice die is geïnjecteerd als een actieparameter

Warning

Gebruik niet wanneer waarden mogelijk bevatten %2f (dat wil /wel[FromRoute]). %2f zal niet ongezichtbaar zijn voor /. Gebruik [FromQuery] deze optie als de waarde mogelijk bevat %2f.

Zonder het kenmerk of de [ApiController] bindingsbronkenmerken, zoals [FromQuery], probeert de ASP.NET Core-runtime de binder van het complexe objectmodel te gebruiken. De binder voor het complexe objectmodel haalt gegevens op uit waardeproviders in een gedefinieerde volgorde.

In het volgende voorbeeld geeft het [FromQuery] kenmerk aan dat de discontinuedOnly parameterwaarde is opgegeven in de queryreeks van de aanvraag-URL:

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

Het [ApiController] kenmerk past deductieregels toe voor de standaardgegevensbronnen van actieparameters. Met deze regels hoeft u geen bindingsbronnen handmatig te identificeren door kenmerken toe te passen op de actieparameters. De regels voor bindingsbrondeductie gedragen zich als volgt:

  • [FromBody] wordt afgeleid voor complexe typeparameters die niet zijn geregistreerd in de DI-container. Een uitzondering op de deductieregel [FromBody] is een complex, ingebouwd type met een speciale betekenis, zoals IFormCollection en CancellationToken. De code voor bindingsbrondeductie negeert deze speciale typen.
  • [FromForm] wordt afgeleid voor actieparameters van het type IFormFile en IFormFileCollection. Het wordt niet afgeleid voor eenvoudige of door de gebruiker gedefinieerde typen.
  • [FromRoute] wordt afgeleid voor elke actieparameternaam die overeenkomt met een parameter in de routesjabloon. Wanneer meer dan één route overeenkomt met een actieparameter, wordt elke routewaarde als beschouwd [FromRoute].
  • [FromQuery] wordt afgeleid voor andere actieparameters.

VanBody-deductienotities

[FromBody] wordt niet afgeleid voor eenvoudige typen, zoals string of int. Daarom moet het [FromBody] kenmerk worden gebruikt voor eenvoudige typen wanneer die functionaliteit nodig is.

Wanneer een actie meer dan één parameter heeft die afhankelijk is van de aanvraagbody, wordt er een uitzondering gegenereerd. Alle handtekeningen van de volgende actiemethoden veroorzaken bijvoorbeeld een uitzondering:

  • [FromBody] afgeleid van beide omdat ze complexe typen zijn.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] kenmerk op de ene, afgeleid van het andere omdat het een complex type is.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] kenmerk op beide.

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

Deductieregels uitschakelen

Als u bindingsbrondeductie wilt uitschakelen, stelt u het SuppressInferBindingSourcesForParameters volgende truein:

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

Deductie van aanvraag voor meerdere onderdelen/formuliergegevens

Het [ApiController] kenmerk past een deductieregel toe voor actieparameters van het type IFormFile en IFormFileCollection. Het inhoudstype van de multipart/form-data aanvraag wordt afgeleid voor deze typen.

Als u het standaardgedrag wilt uitschakelen, stelt u de SuppressConsumesConstraintForFormFileParameters eigenschap truein op:

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

Probleemdetails voor foutcodes

MVC transformeert een foutresultaat (een resultaat met statuscode 400 of hoger) naar een resultaat met ProblemDetails. Het ProblemDetails type is gebaseerd op de RFC 7807-specificatie voor het leveren van machineleesbare foutdetails in een HTTP-antwoord.

Houd rekening met de volgende code in een controlleractie:

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

De NotFound methode produceert een HTTP 404-statuscode met een ProblemDetails hoofdtekst. For example:

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

ProblemDetails-antwoord uitschakelen

Het automatisch maken van een ProblemDetails voor foutcodes is uitgeschakeld wanneer de SuppressMapClientErrors eigenschap is ingesteld trueop:

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

Ondersteunde aanvraaginhoudstypen definiëren met het kenmerk [Verbruikt]

Standaard ondersteunt een actie alle beschikbare aanvraaginhoudstypen. Als een app bijvoorbeeld is geconfigureerd ter ondersteuning van zowel JSON- als XML-invoerindelingen, ondersteunt een actie meerdere inhoudstypen, waaronder application/json en application/xml.

Met het kenmerk [Verbruiken] kan een actie de ondersteunde inhoudstypen voor aanvragen beperken. Pas het [Consumes] kenmerk toe op een actie of controller, waarbij een of meer inhoudstypen worden opgegeven:

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

In de voorgaande code geeft de CreateProduct actie het inhoudstype application/xmlop. Aanvragen die naar deze actie worden doorgestuurd, moeten een Content-Type header van application/xml. Aanvragen die geen header van het resultaat opgeven Content-Type in een reactie van application/xml415 niet-ondersteund mediatype .

Met [Consumes] het kenmerk kan een actie de selectie ervan beïnvloeden op basis van het inhoudstype van een binnenkomende aanvraag door een typebeperking toe te passen. Bekijk het volgende voorbeeld:

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

In de voorgaande code ConsumesController is geconfigureerd voor het verwerken van aanvragen die naar de https://localhost:5001/api/Consumes URL worden verzonden. Beide acties PostJson van de controller en PostFormverwerken POST-aanvragen met dezelfde URL. Zonder het [Consumes] kenmerk dat een typebeperking toepast, wordt er een dubbelzinnige overeenkomst-uitzondering gegenereerd.

Het [Consumes] kenmerk wordt toegepast op beide acties. De PostJson actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/json. De PostForm actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/x-www-form-urlencoded.

Additional resources

ASP.NET Core ondersteunt het maken van RESTful-services, ook wel web-API's genoemd, met behulp van C#. Voor het verwerken van aanvragen maakt een web-API gebruik van controllers. Controllers in een web-API zijn klassen die zijn afgeleid van ControllerBase. In dit artikel wordt beschreven hoe u controllers gebruikt voor het verwerken van web-API-aanvragen.

voorbeeldcode weergeven of downloaden. (Hoe te downloaden).

ControllerBase class

Een web-API bestaat uit een of meer controllerklassen die zijn afgeleid van ControllerBase. De web-API-projectsjabloon biedt een starterscontroller:

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

Maak geen web-API-controller door deze af te leiden van de Controller klasse. Controller is afgeleid van ControllerBase en voegt ondersteuning toe voor weergaven, dus voor het verwerken van webpagina's, niet voor web-API-aanvragen. Er is een uitzondering op deze regel: als u van plan bent dezelfde controller te gebruiken voor zowel weergaven als web-API's, afgeleid van Controller.

De ControllerBase-klasse biedt veel eigenschappen en methoden die handig zijn voor het verwerken van HTTP-aanvragen. Retourneert bijvoorbeeld ControllerBase.CreatedAtAction een 201-statuscode:

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

Hier volgen nog enkele voorbeelden van methoden die ControllerBase bieden.

Method Notes
BadRequest Retourneert 400 statuscode.
NotFound Retourneert de 404-statuscode.
PhysicalFile Retourneert een bestand.
TryUpdateModelAsync Roept modelbinding aan.
TryValidateModel Roept modelvalidatie aan.

Zie voor een lijst met alle beschikbare methoden en eigenschappen ControllerBase.

Attributes

De Microsoft.AspNetCore.Mvc naamruimte bevat kenmerken die kunnen worden gebruikt om het gedrag van web-API-controllers en actiemethoden te configureren. In het volgende voorbeeld worden kenmerken gebruikt om het ondersteunde HTTP-actiewoord en eventuele bekende HTTP-statuscodes op te geven die kunnen worden geretourneerd:

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

Hier volgen nog enkele voorbeelden van kenmerken die beschikbaar zijn.

Attribute Notes
[Route] Hiermee geeft u een URL-patroon voor een controller of actie op.
[Bind] Hiermee geeft u het voorvoegsel en de eigenschappen op die moeten worden opgenomen voor modelbinding.
[HttpGet] Identificeert een actie die ondersteuning biedt voor het HTTP GET-actiewoord.
[Consumes] Hiermee geeft u gegevenstypen op die een actie accepteert.
[Produces] Hiermee geeft u gegevenstypen op die een actie retourneert.

Zie de Microsoft.AspNetCore.Mvc naamruimte voor een lijst met de beschikbare kenmerken.

ApiController attribute

Het [ApiController] kenmerk kan worden toegepast op een controllerklasse om het volgende, api-specifieke gedrag mogelijk te maken:

Kenmerk op specifieke controllers

Het [ApiController] kenmerk kan worden toegepast op specifieke controllers, zoals in het volgende voorbeeld van de projectsjabloon:

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

Kenmerk op meerdere controllers

Een benadering voor het gebruik van het kenmerk op meer dan één controller is het maken van een aangepaste basiscontrollerklasse die is geannoteerd met het [ApiController] kenmerk. In het volgende voorbeeld ziet u een aangepaste basisklasse en een controller die hiervan is afgeleid:

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

Kenmerk voor een assembly

Het [ApiController] kenmerk kan worden toegepast op een assembly. Aantekening op deze manier past web-API-gedrag toe op alle controllers in de assembly. U kunt zich niet afmelden voor afzonderlijke controllers. Pas het kenmerk assemblyniveau toe op de naamruimtedeclaratie rond de Startup klasse:

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

Vereiste voor kenmerkroutering

Het [ApiController] kenmerk maakt kenmerkroutering een vereiste. For example:

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

Acties zijn niet toegankelijk via conventionele routes die zijn gedefinieerd door UseEndpoints, UseMvcof UseMvcWithDefaultRoute in Startup.Configure.

Automatische HTTP 400-antwoorden

Met [ApiController] het kenmerk worden modelvalidatiefouten automatisch een HTTP 400-antwoord geactiveerd. Daarom is de volgende code niet nodig in een actiemethode:

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

ASP.NET Core MVC gebruikt het ModelStateInvalidFilter actiefilter om de voorgaande controle uit te voeren.

Standaard BadRequest-antwoord

De volgende aanvraagbody is een voorbeeld van het geserialiseerde type:

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

Het standaardantwoordtype voor een HTTP 400-antwoord is ValidationProblemDetails. De volgende aanvraagbody is een voorbeeld van het geserialiseerde 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."
    ]
  }
}

Het ValidationProblemDetails type:

  • Biedt een door de machine leesbare indeling voor het opgeven van fouten in web-API-antwoorden.
  • Voldoet aan de RFC 7807-specificatie.

Als u automatische en aangepaste antwoorden consistent wilt maken, roept u de ValidationProblem methode aan in plaats van BadRequest. ValidationProblem retourneert een ValidationProblemDetails object en het automatische antwoord.

Automatische 400-antwoorden registreren

Als u automatische 400 antwoorden wilt registreren, stelt u de InvalidModelStateResponseFactory eigenschap gedelegeerde in om aangepaste verwerking uit te voeren.Startup.ConfigureServices Maakt ProblemDetailsFactory standaard InvalidModelStateResponseFactory een exemplaar van ValidationProblemDetails.

In het volgende voorbeeld ziet u hoe u een exemplaar ophaalt van het vastleggen van ILogger<TCategoryName> informatie over een automatische 400-respons:

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

Automatische 400-respons uitschakelen

Als u het automatische 400-gedrag wilt uitschakelen, stelt u de SuppressModelStateInvalidFilter eigenschap in op true. Voeg de volgende gemarkeerde code toe in 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;
    });

Deductie van bindingsbronparameter

Een bindingsbronkenmerk definieert de locatie waarop de waarde van een actieparameter wordt gevonden. De volgende bindingsbronkenmerken bestaan:

Attribute Binding source
[FromBody] Request body
[FromForm] Formuliergegevens in de hoofdtekst van de aanvraag
[FromHeader] Request header
[FromQuery] Queryreeksparameter aanvragen
[FromRoute] Gegevens routeren vanuit de huidige aanvraag
[FromServices] De aanvraagservice die is geïnjecteerd als een actieparameter

Warning

Gebruik niet wanneer waarden mogelijk bevatten %2f (dat wil /wel[FromRoute]). %2f zal niet ongezichtbaar zijn voor /. Gebruik [FromQuery] deze optie als de waarde mogelijk bevat %2f.

Zonder het kenmerk of de [ApiController] bindingsbronkenmerken, zoals [FromQuery], probeert de ASP.NET Core-runtime de binder van het complexe objectmodel te gebruiken. De binder voor het complexe objectmodel haalt gegevens op uit waardeproviders in een gedefinieerde volgorde.

In het volgende voorbeeld geeft het [FromQuery] kenmerk aan dat de discontinuedOnly parameterwaarde is opgegeven in de queryreeks van de aanvraag-URL:

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

Het [ApiController] kenmerk past deductieregels toe voor de standaardgegevensbronnen van actieparameters. Met deze regels hoeft u geen bindingsbronnen handmatig te identificeren door kenmerken toe te passen op de actieparameters. De regels voor bindingsbrondeductie gedragen zich als volgt:

  • [FromBody] wordt afgeleid voor complexe typeparameters. Een uitzondering op de deductieregel [FromBody] is een complex, ingebouwd type met een speciale betekenis, zoals IFormCollection en CancellationToken. De code voor bindingsbrondeductie negeert deze speciale typen.
  • [FromForm] wordt afgeleid voor actieparameters van het type IFormFile en IFormFileCollection. Het wordt niet afgeleid voor eenvoudige of door de gebruiker gedefinieerde typen.
  • [FromRoute] wordt afgeleid voor elke actieparameternaam die overeenkomt met een parameter in de routesjabloon. Wanneer meer dan één route overeenkomt met een actieparameter, wordt elke routewaarde als beschouwd [FromRoute].
  • [FromQuery] wordt afgeleid voor andere actieparameters.

VanBody-deductienotities

[FromBody] wordt niet afgeleid voor eenvoudige typen, zoals string of int. Daarom moet het [FromBody] kenmerk worden gebruikt voor eenvoudige typen wanneer die functionaliteit nodig is.

Wanneer een actie meer dan één parameter heeft die afhankelijk is van de aanvraagbody, wordt er een uitzondering gegenereerd. Alle handtekeningen van de volgende actiemethoden veroorzaken bijvoorbeeld een uitzondering:

  • [FromBody] afgeleid van beide omdat ze complexe typen zijn.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] kenmerk op de ene, afgeleid van het andere omdat het een complex type is.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] kenmerk op beide.

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

Deductieregels uitschakelen

Als u bindingsbrondeductie wilt uitschakelen, stelt u deze in SuppressInferBindingSourcesForParameters op true. Voeg de volgende code toe in 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;
    });

Deductie van aanvraag voor meerdere onderdelen/formuliergegevens

Het [ApiController] kenmerk past een deductieregel toe voor actieparameters van het type IFormFile en IFormFileCollection. Het inhoudstype van de multipart/form-data aanvraag wordt afgeleid voor deze typen.

Als u het standaardgedrag wilt uitschakelen, stelt u de SuppressConsumesConstraintForFormFileParameters eigenschap true in op :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;
    });

Probleemdetails voor foutcodes

MVC transformeert een foutresultaat (een resultaat met statuscode 400 of hoger) naar een resultaat met ProblemDetails. Het ProblemDetails type is gebaseerd op de RFC 7807-specificatie voor het leveren van machineleesbare foutdetails in een HTTP-antwoord.

Houd rekening met de volgende code in een controlleractie:

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

De NotFound methode produceert een HTTP 404-statuscode met een ProblemDetails hoofdtekst. For example:

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

ProblemDetails-antwoord uitschakelen

Het automatisch maken van een ProblemDetails voor foutcodes is uitgeschakeld wanneer de SuppressMapClientErrors eigenschap is ingesteld op true. Voeg de volgende code toe in 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;
    });

Ondersteunde aanvraaginhoudstypen definiëren met het kenmerk [Verbruikt]

Standaard ondersteunt een actie alle beschikbare aanvraaginhoudstypen. Als een app bijvoorbeeld is geconfigureerd ter ondersteuning van zowel JSON- als XML-invoerindelingen, ondersteunt een actie meerdere inhoudstypen, waaronder application/json en application/xml.

Met het kenmerk [Verbruiken] kan een actie de ondersteunde inhoudstypen voor aanvragen beperken. Pas het [Consumes] kenmerk toe op een actie of controller, waarbij een of meer inhoudstypen worden opgegeven:

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

In de voorgaande code geeft de CreateProduct actie het inhoudstype application/xmlop. Aanvragen die naar deze actie worden doorgestuurd, moeten een Content-Type header van application/xml. Aanvragen die geen header van het resultaat opgeven Content-Type in een reactie van application/xml415 niet-ondersteund mediatype .

Met [Consumes] het kenmerk kan een actie de selectie ervan beïnvloeden op basis van het inhoudstype van een binnenkomende aanvraag door een typebeperking toe te passen. Bekijk het volgende voorbeeld:

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

In de voorgaande code ConsumesController is geconfigureerd voor het verwerken van aanvragen die naar de https://localhost:5001/api/Consumes URL worden verzonden. Beide acties PostJson van de controller en PostFormverwerken POST-aanvragen met dezelfde URL. Zonder het [Consumes] kenmerk dat een typebeperking toepast, wordt er een dubbelzinnige overeenkomst-uitzondering gegenereerd.

Het [Consumes] kenmerk wordt toegepast op beide acties. De PostJson actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/json. De PostForm actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/x-www-form-urlencoded.

Additional resources

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

Maak geen web-API-controller door deze af te leiden van de Controller klasse. Controller is afgeleid van ControllerBase en voegt ondersteuning toe voor weergaven, dus voor het verwerken van webpagina's, niet voor web-API-aanvragen. Er is een uitzondering op deze regel: als u van plan bent dezelfde controller te gebruiken voor zowel weergaven als web-API's, afgeleid van Controller. De ControllerBase-klasse biedt veel eigenschappen en methoden die handig zijn voor het verwerken van HTTP-aanvragen. Retourneert bijvoorbeeld ControllerBase.CreatedAtAction een 201-statuscode:

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

Hier volgen nog enkele voorbeelden van methoden die ControllerBase het volgende bieden:

Method Notes
BadRequest Retourneert 400 statuscode.
NotFound Retourneert de 404-statuscode.
PhysicalFile Retourneert een bestand.
TryUpdateModelAsync Roept modelbinding aan.
TryValidateModel Roept modelvalidatie aan.

Zie voor een lijst met alle beschikbare methoden en eigenschappen ControllerBase.

Attributes

De Microsoft.AspNetCore.Mvc naamruimte bevat kenmerken die kunnen worden gebruikt om het gedrag van web-API-controllers en actiemethoden te configureren. In het volgende voorbeeld worden kenmerken gebruikt om het ondersteunde HTTP-actiewoord en eventuele bekende HTTP-statuscodes op te geven die kunnen worden geretourneerd:

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

Hier volgen nog enkele voorbeelden van kenmerken die beschikbaar zijn:

Attribute Notes
[Route] Hiermee geeft u een URL-patroon voor een controller of actie op.
[Bind] Hiermee geeft u het voorvoegsel en de eigenschappen op die moeten worden opgenomen voor modelbinding.
[HttpGet] Identificeert een actie die ondersteuning biedt voor het HTTP GET-actiewoord.
[Consumes] Hiermee geeft u gegevenstypen op die een actie accepteert.
[Produces] Hiermee geeft u gegevenstypen op die een actie retourneert.

Zie de Microsoft.AspNetCore.Mvc naamruimte voor een lijst met de beschikbare kenmerken.

ApiController attribute

Het [ApiController] kenmerk kan worden toegepast op een controllerklasse om het volgende, api-specifieke gedrag mogelijk te maken:

Kenmerk op specifieke controllers

Het [ApiController] kenmerk kan worden toegepast op specifieke controllers, zoals in het volgende voorbeeld van de projectsjabloon:

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

Kenmerk op meerdere controllers

Een benadering voor het gebruik van het kenmerk op meer dan één controller is het maken van een aangepaste basiscontrollerklasse die is geannoteerd met het [ApiController] kenmerk. In het volgende voorbeeld ziet u een aangepaste basisklasse en een controller die hiervan is afgeleid:

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

Kenmerk voor een assembly

Als de compatibiliteitsversie is ingesteld op 2.2 of hoger, kan het [ApiController] kenmerk worden toegepast op een assembly. Aantekening op deze manier past web-API-gedrag toe op alle controllers in de assembly. U kunt zich niet afmelden voor afzonderlijke controllers. Pas het kenmerk assemblyniveau toe op de naamruimtedeclaratie rond de Startup klasse:

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

Vereiste voor kenmerkroutering

Het [ApiController] kenmerk maakt kenmerkroutering een vereiste. For example:

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

Acties zijn niet toegankelijk via conventionele routes die zijn gedefinieerd door UseMvc of UseMvcWithDefaultRoute in Startup.Configure.

Automatische HTTP 400-antwoorden

Met [ApiController] het kenmerk worden modelvalidatiefouten automatisch een HTTP 400-antwoord geactiveerd. Daarom is de volgende code niet nodig in een actiemethode:

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

ASP.NET Core MVC gebruikt het ModelStateInvalidFilter actiefilter om de voorgaande controle uit te voeren.

Standaard BadRequest-antwoord

Met een compatibiliteitsversie van 2.1 is SerializableErrorhet standaardantwoordtype voor een HTTP 400-antwoord. De volgende aanvraagbody is een voorbeeld van het geserialiseerde type:

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

Met een compatibiliteitsversie van 2.2 of hoger is ValidationProblemDetailshet standaardantwoordtype voor een HTTP 400-antwoord. De volgende aanvraagbody is een voorbeeld van het geserialiseerde 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."
    ]
  }
}

Het ValidationProblemDetails type:

  • Biedt een door de machine leesbare indeling voor het opgeven van fouten in web-API-antwoorden.
  • Voldoet aan de RFC 7807-specificatie.

Als u automatische en aangepaste antwoorden consistent wilt maken, roept u de ValidationProblem methode aan in plaats van BadRequest. ValidationProblem retourneert een ValidationProblemDetails object en het automatische antwoord.

Automatische 400-antwoorden registreren

Zie Automatische 400 antwoorden registreren voor modelvalidatiefouten (dotnet/AspNetCore.Docs#12157).

Automatische 400-respons uitschakelen

Als u het automatische 400-gedrag wilt uitschakelen, stelt u de SuppressModelStateInvalidFilter eigenschap in op true. Voeg de volgende gemarkeerde code toe in Startup.ConfigureServices:

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

Deductie van bindingsbronparameter

Een bindingsbronkenmerk definieert de locatie waarop de waarde van een actieparameter wordt gevonden. De volgende bindingsbronkenmerken bestaan:

Attribute Binding source
[FromBody] Request body
[FromForm] Formuliergegevens in de hoofdtekst van de aanvraag
[FromHeader] Request header
[FromQuery] Queryreeksparameter aanvragen
[FromRoute] Gegevens routeren vanuit de huidige aanvraag
[FromServices] De aanvraagservice die is geïnjecteerd als een actieparameter

Warning

Gebruik niet wanneer waarden mogelijk bevatten %2f (dat wil /wel[FromRoute]). %2f zal niet ongezichtbaar zijn voor /. Gebruik [FromQuery] deze optie als de waarde mogelijk bevat %2f. Zonder het kenmerk of de [ApiController] bindingsbronkenmerken, zoals [FromQuery], probeert de ASP.NET Core-runtime de binder van het complexe objectmodel te gebruiken. De binder voor het complexe objectmodel haalt gegevens op uit waardeproviders in een gedefinieerde volgorde.

In het volgende voorbeeld geeft het [FromQuery] kenmerk aan dat de discontinuedOnly parameterwaarde is opgegeven in de queryreeks van de aanvraag-URL:

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

Het [ApiController] kenmerk past deductieregels toe voor de standaardgegevensbronnen van actieparameters. Met deze regels hoeft u geen bindingsbronnen handmatig te identificeren door kenmerken toe te passen op de actieparameters. De regels voor bindingsbrondeductie gedragen zich als volgt:

  • [FromBody] wordt afgeleid voor complexe typeparameters. Een uitzondering op de deductieregel [FromBody] is een complex, ingebouwd type met een speciale betekenis, zoals IFormCollection en CancellationToken. De code voor bindingsbrondeductie negeert deze speciale typen.
  • [FromForm] wordt afgeleid voor actieparameters van het type IFormFile en IFormFileCollection. Het wordt niet afgeleid voor eenvoudige of door de gebruiker gedefinieerde typen.
  • [FromRoute] wordt afgeleid voor elke actieparameternaam die overeenkomt met een parameter in de routesjabloon. Wanneer meer dan één route overeenkomt met een actieparameter, wordt elke routewaarde als beschouwd [FromRoute].
  • [FromQuery] wordt afgeleid voor andere actieparameters.

VanBody-deductienotities

[FromBody] wordt niet afgeleid voor eenvoudige typen, zoals string of int. Daarom moet het [FromBody] kenmerk worden gebruikt voor eenvoudige typen wanneer die functionaliteit nodig is.

Wanneer een actie meer dan één parameter heeft die afhankelijk is van de aanvraagbody, wordt er een uitzondering gegenereerd. Alle handtekeningen van de volgende actiemethoden veroorzaken bijvoorbeeld een uitzondering:

  • [FromBody] afgeleid van beide omdat ze complexe typen zijn.

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] kenmerk op de ene, afgeleid van het andere omdat het een complex type is.

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] kenmerk op beide.

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

Note

In ASP.NET Core 2.1 worden verzamelingstypeparameters zoals lijsten en matrices onjuist afgeleid als [FromQuery]. Het [FromBody] kenmerk moet worden gebruikt voor deze parameters als deze afhankelijk zijn van de hoofdtekst van de aanvraag. Dit gedrag wordt gecorrigeerd in ASP.NET Core 2.2 of hoger, waarbij standaard parameters van het verzamelingstype worden afgeleid van de hoofdtekst.

Deductieregels uitschakelen

Als u bindingsbrondeductie wilt uitschakelen, stelt u deze in SuppressInferBindingSourcesForParameters op true. Voeg de volgende code toe in Startup.ConfigureServices:

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

Deductie van aanvraag voor meerdere onderdelen/formuliergegevens

Het [ApiController] kenmerk past een deductieregel toe voor actieparameters van het type IFormFile en IFormFileCollection. Het inhoudstype van de multipart/form-data aanvraag wordt afgeleid voor deze typen. Als u het standaardgedrag wilt uitschakelen, stelt u de SuppressConsumesConstraintForFormFileParameters eigenschap true in op :Startup.ConfigureServices

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

Probleemdetails voor foutcodes

Wanneer de compatibiliteitsversie 2.2 of hoger is, transformeert MVC een foutresultaat (een resultaat met statuscode 400 of hoger) naar een resultaat met ProblemDetails. Het ProblemDetails type is gebaseerd op de RFC 7807-specificatie voor het leveren van machineleesbare foutdetails in een HTTP-antwoord. Houd rekening met de volgende code in een controlleractie:

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

De NotFound methode produceert een HTTP 404-statuscode met een ProblemDetails hoofdtekst. For example:

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

ProblemDetails-antwoord uitschakelen

Het automatisch maken van een ProblemDetails voor foutcodes is uitgeschakeld wanneer de SuppressMapClientErrors eigenschap is ingesteld op true. Voeg de volgende code toe in Startup.ConfigureServices:

Ondersteunde aanvraaginhoudstypen definiëren met het kenmerk [Verbruikt]

Standaard ondersteunt een actie alle beschikbare aanvraaginhoudstypen. Als een app bijvoorbeeld is geconfigureerd ter ondersteuning van zowel JSON- als XML-invoerindelingen, ondersteunt een actie meerdere inhoudstypen, waaronder application/json en application/xml.

Met het kenmerk [Verbruiken] kan een actie de ondersteunde inhoudstypen voor aanvragen beperken. Pas het [Consumes] kenmerk toe op een actie of controller, waarbij een of meer inhoudstypen worden opgegeven:

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

In de voorgaande code geeft de CreateProduct actie het inhoudstype application/xmlop. Aanvragen die naar deze actie worden doorgestuurd, moeten een Content-Type header van application/xml. Aanvragen die geen header van het resultaat opgeven Content-Type in een reactie van application/xml415 niet-ondersteund mediatype . Met [Consumes] het kenmerk kan een actie de selectie ervan beïnvloeden op basis van het inhoudstype van een binnenkomende aanvraag door een typebeperking toe te passen. Bekijk het volgende voorbeeld:

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

In de voorgaande code ConsumesController is geconfigureerd voor het verwerken van aanvragen die naar de https://localhost:5001/api/Consumes URL worden verzonden. Beide acties PostJson van de controller en PostFormverwerken POST-aanvragen met dezelfde URL. Zonder het [Consumes] kenmerk dat een typebeperking toepast, wordt er een dubbelzinnige overeenkomst-uitzondering gegenereerd. Het [Consumes] kenmerk wordt toegepast op beide acties. De PostJson actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/json. De PostForm actie verwerkt aanvragen die worden verzonden met een Content-Type header van application/x-www-form-urlencoded.

Additional resources