Erstellen von Web-APIs mit ASP.NET Core
ASP.NET Core unterstützt das Erstellen von Web-APIs mithilfe von Controllern oder minimalen APIs. Controller in einer Web-API sind von ControllerBase abgeleitete Klassen. Controller werden auf Anforderungsbasis aktiviert und verworfen.
In diesem Artikel wird beschrieben, wie Sie Controller für die Verarbeitung von Web-API-Anforderungen verwenden. Informationen zum Erstellen von Web-APIs ohne Controller finden Sie im Tutorial: Erstellen einer minimalen API mit ASP.NET Core.
ControllerBase-Klasse
Eine controllerbasierte Web-API besteht aus mindestens einer Controllerklasse, die von ControllerBase abgeleitet ist. Die Web-API-Projektvorlage stellt einen Startercontroller bereit:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Web-API-Controller sollten in der Regel eher von ControllerBase als von Controller ableiten. Controller
wird von ControllerBase abgeleitet und fügt Unterstützung für Ansichten hinzu, wird also für die Verarbeitung von Webseiten verwendet und nicht für Web-API-Anforderungen. Wenn derselbe Controller Ansichten und Web-APIs unterstützen muss, leiten Sie von Controller
ab.
Die ControllerBase
-Klasse bietet viele Eigenschaften und Methoden, die für die Verarbeitung von HTTP-Anforderungen hilfreich sind. CreatedAtAction gibt beispielsweise Statuscode 201 zurück:
[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);
}
Die folgende Tabelle enthält Beispiele für gängige Methoden in ControllerBase
.
Methode | Hinweise |
---|---|
BadRequest | Gibt Statuscode 400 zurück. |
NotFound | Gibt Statuscode 404 zurück. |
PhysicalFile | Gibt eine Datei zurück. |
TryUpdateModelAsync | Ruft die Modellbindung auf. |
TryValidateModel | Ruft die Modellvalidierung auf. |
Eine Liste aller verfügbaren Methoden und Eigenschaften finden Sie unter ControllerBase.
Attribute
Der Microsoft.AspNetCore.Mvc-Namespace enthält Attribute, mit denen das Verhalten von Web-API-Controllern und Aktionsmethoden konfiguriert werden kann. Im folgenden Beispiel werden Attribute verwendet, um das unterstützte HTTP-Aktionsverb und alle bekannten HTTP-Statuscodes, die zurückgegeben werden können, anzugeben:
[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 einige weitere Beispiele für die verfügbaren Attribute.
Attribut | Hinweise |
---|---|
[Route] |
Gibt ein URL-Muster für einen Controller oder eine Aktion an. |
[Bind] |
Gibt Präfixe und Eigenschaften an, die in die Modellbindung einbezogen werden sollen. |
[HttpGet] |
Identifiziert eine Aktion, die das HTTP GET-Aktionsverb unterstützt. |
[Consumes] |
Gibt die von einer Aktion akzeptierten Datentypen an. |
[Produces] |
Gibt die von einer Aktion zurückgegebenen Datentypen an. |
Eine Liste mit den verfügbaren Attributen finden Sie im Microsoft.AspNetCore.Mvc-Namespace.
ApiController-Attribut
Das [ApiController]
-Attribut kann auf eine Controllerklasse angewendet werden, um folgende API-spezifische Verhalten mit einigen vordefinierten Konfigurationen zu aktivieren:
- Anforderung für das Attributrouting
- Automatische HTTP 400-Antworten
- Rückschluss auf Bindungsquellparameter
- Ableiten der Multipart/form-data-Anforderung
- Problemdetails für Fehlerstatuscodes
Attribut für bestimmte Controller
Das [ApiController]
-Attribut kann, wie im folgenden Beispiel der Projektvorlage ersichtlich, auf bestimmte Controller angewendet werden:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Attribut für mehrere Controller
Eine Möglichkeit, das Attribut für mehr als einen Controller zu verwenden, besteht darin, eine benutzerdefinierte Basiscontrollerklasse zu erstellen, die mit dem [ApiController]
-Attribut kommentiert ist. Im folgenden Beispiel wird eine benutzerdefinierte Basisklasse und ein Controller, der von ihr abgeleitet wird, gezeigt:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Attribut für eine Assembly
Auf Assemblys kann das [ApiController]
-Attribut angewendet werden. Wenn das [ApiController]
-Attribut auf eine Assembly angewendet wird, wird auf alle Controller in der Assembly das [ApiController]
-Attribut angewendet. Es gibt keine Möglichkeit, einzelne Controller auszuschließen. Wenden Sie das Attribut auf Assemblyebene auf die Program.cs
-Datei an:
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();
Anforderung für das Attributrouting
Durch das [ApiController]
-Attribut wird das Attributrouting zu einer Anforderung. Zum Beispiel:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Sie können über konventionelle Routen, die durch UseEndpoints
, UseMvc oder UseMvcWithDefaultRoute definiert sind, nicht auf Aktionen zugreifen.
Automatische HTTP 400-Antwort
Durch das [ApiController]
-Attribut wird bei Modellvalidierungsfehlern automatisch eine HTTP 400-Antwort ausgelöst. Deshalb ist der folgende Code in einer Aktionsmethode überflüssig:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC verwendet den ModelStateInvalidFilter-Aktionsfilter, um die vorherige Überprüfung durchzuführen.
Standardmäßige BadRequest-Antwort
Für eine HTTP 400-Antwort wird standardmäßig der Antworttyp ValidationProblemDetails verwendet. Der folgende Antworttext ist ein Beispiel für den serialisierten Typ:
{
"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."
]
}
}
Der ValidationProblemDetails
-Typ:
- Bietet ein vom Computer lesbares Format zum Angeben von Fehlern in Web-API-Antworten.
- Entspricht der RFC 7807-Spezifikation.
Rufen Sie die ValidationProblem-Methode anstelle von BadRequest auf, um automatische und benutzerdefinierte Antworten konsistent zu machen. ValidationProblem
gibt sowohl ein ValidationProblemDetails-Objekt als auch die automatische Antwort zurück.
Protokollieren automatischer 400-Antworten
Um automatische 400-Antworten zu protokollieren, legen Sie die InvalidModelStateResponseFactory-Delegateneigenschaft fest, um benutzerdefinierte Verarbeitung auszuführen. Zum Erstellen einer Instanz von ValidationProblemDetails verwendet InvalidModelStateResponseFactory
standardmäßig ProblemDetailsFactory.
Im folgenden Beispiel wird gezeigt, wie Sie eine Instanz von ILogger<TCategoryName> abrufen, um Informationen zu einer automatischen 400-Antwort zu protokollieren:
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();
Deaktivieren automatischer 400-Antwort
Um das automatische Verhalten bei Statuscode 400 zu deaktivieren, legen Sie die SuppressModelStateInvalidFilter-Eigenschaft auf true
fest. Fügen Sie folgenden hervorgehobenen Code hinzu:
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();
Rückschluss auf Bindungsquellparameter
Ein Bindungsquellenattribut definiert den Speicherort, an dem der Wert eines Aktionsparameters vorhanden ist. Es gibt die folgenden Bindungsquellattribute:
Attribut | Bindungsquelle |
---|---|
[FromBody] |
Anforderungstext |
[FromForm] |
Formulardaten im Anforderungstext |
[FromHeader] |
Anforderungsheader |
[FromQuery] |
Abfragezeichenfolge-Parameter der Anforderung |
[FromRoute] |
Routendaten aus aktuellen Anforderungen |
[FromServices] |
Der als Aktionsparameter eingefügte Anforderungsdienst. |
[AsParameters] |
Methodenparameter |
Warnung
Verwenden Sie [FromRoute]
nicht, wenn Werte möglicherweise %2f
enthalten (d.h. /
). %2f
wird nicht durch Entfernen von Escapezeichen zu /
. Verwenden Sie [FromQuery]
, wenn der Wert %2f
enthalten könnte.
Ohne das [ApiController]
-Attribut oder Bindungsquellenattribute wie [FromQuery]
versucht die ASP.NET Core-Runtime, die Modellbindung für komplexe Objekte zu verwenden. Bei der Modellbindung für komplexe Objekte werden Daten aus Wertanbietern in einer festgelegten Reihenfolge abgerufen.
Im folgenden Beispiel gibt das [FromQuery]
-Attribut an, dass der Parameterwert discontinuedOnly
in der Abfragezeichenfolge der Anforderungs-URL bereitgestellt wird:
[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;
}
Das [ApiController]
-Attribut wendet Rückschlussregeln auf die Standarddatenquellen von Aktionsparametern an. Da durch diese Regeln Attribute auf die Aktionsparameter angewendet werden, müssen Sie Bindungsquellen nicht manuell identifizieren. Die Rückschlussregeln für Bindungsquellen verhalten sich wie folgt:
[FromServices]
wird für komplexe Typparameter abgeleitet, die im DI-Container registriert sind.[FromBody]
wird für komplexe Typparameter abgeleitet, die nicht im DI-Container registriert sind. Jeder komplexe integrierte Typ mit spezieller Bedeutung, z. B. IFormCollection und CancellationToken, stellt eine Ausnahme von der[FromBody]
-Rückschlussregel dar. Der Rückschlusscode der Bindungsquelle ignoriert diese Typen.[FromForm]
wird für Aktionsparameter des Typs IFormFile und IFormFileCollection abgeleitet. Es wird für keine einfachen oder benutzerdefinierte Typen abgeleitet.[FromRoute]
wird für jeden Namen von Aktionsparametern abgeleitet, der mit einem Parameter in der Routenvorlage übereinstimmt. Wenn mehr als eine Route mit einem Aktionsparameter übereinstimmt, gilt jeder Routenwert als[FromRoute]
.[FromQuery]
wird für alle anderen Aktionsparameter abgeleitet.
Hinweise zum FromBody-Rückschluss
[FromBody]
wird für einfache Typen wie string
oder int
nicht abgeleitet. Deshalb sollte das [FromBody]
-Attribut für einfache Typen verwendet werden, wenn diese Funktionsweise benötigt wird.
Wenn an eine Aktion mehr als ein Parameter aus dem Anforderungstext gebunden ist, wird eine Ausnahme ausgelöst. Beispielsweise lösen alle Signaturen der folgenden Aktionsmethoden eine Ausnahme aus:
[FromBody]
wird für beide abgeleitet, da sie komplexe Typen darstellen.[HttpPost] public IActionResult Action1(Product product, Order order)
Das
[FromBody]
-Attribut für einen Typ wird für den anderen abgeleitet, da es sich um einen komplexen Typ handelt.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Das
[FromBody]
-Attribut für beide.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
FromServices-Rückschlusshinweise
Parameterbindung bindet Parameter durch Abhängigkeitsinjektion (Dependency Injection, DI), wenn der Typ als Dienst konfiguriert wird. Dies bedeutet, dass es nicht erforderlich ist, das [FromServices]
-Attribut explizit auf einen Parameter anzuwenden. Im folgenden Code geben beide Aktionen die Uhrzeit zurück:
[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 seltenen Fällen kann die automatische DI Apps zum Scheitern bringen, die einen Typ in DI haben, der auch in den Aktionsmethoden eines API-Controllers akzeptiert wird. Es ist nicht üblich, einen Typ in DI und als Argument in einer API-Controlleraktion zu verwenden.
Um den [FromServices]
-Rückschluss für einen einzelnen Aktionsparameter zu deaktivieren, wenden Sie das gewünschte Bindungsquellenattribut auf den Parameter an. Wenden Sie beispielsweise das [FromBody]
-Attribut auf einen Aktionsparameter an, der vom Textkörper der Anforderung gebunden werden soll.
Um den [FromServices]
-Rückschluss global zu deaktivieren, setzen Sie DisableImplicitFromServicesParameters auf 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 werden beim App-Start mit IServiceProviderIsService überprüft, um festzustellen, ob ein Argument in einer API-Controlleraktion aus DI oder den anderen Quellen stammt.
Der Mechanismus zur Ableitung der Bindungsquelle von Aktionsparametern des API-Controllers verwendet die folgenden Regeln:
- Ein zuvor angegebenes
BindingInfo.BindingSource
-Element wird nie überschrieben. - Einem komplexen Typparameter, der im DI-Container registriert ist, wird
BindingSource.Services
zugewiesen. - Einem komplexen Typparameter, der nicht im DI-Container registriert ist, wird
BindingSource.Body
zugewiesen. - Einem Parameter mit einem Namen, der als Routenwert in jeder beliebigen Routenvorlage angezeigt wird, wird
BindingSource.Path
zugewiesen. - Alle anderen Parameter sind
BindingSource.Query
.
Deaktivieren von Rückschlussregeln
Legen Sie SuppressInferBindingSourcesForParameters auf true
fest, um den Rückschluss auf Bindungsquellen zu deaktivieren:
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();
Ableiten der Multipart/form-data-Anforderung
Das [ApiController]
-Attribut wendet eine Rückschlussregel für Aktionsparameter des Typs IFormFile und IFormFileCollection an. Der multipart/form-data
-Anforderungsinhaltstyp wird für diese Typen abgeleitet.
Legen Sie die SuppressConsumesConstraintForFormFileParameters-Eigenschaft auf true
fest, um das Standardverhalten zu deaktivieren:
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();
Problemdetails für Fehlerstatuscodes
MVC wandelt ein Fehlerergebnis (ein Ergebnis mit dem Statuscode 400 oder höher) in ein Ergebnis mit ProblemDetails um. Die ProblemDetails
-Typ basiert auf der RFC 7807-Spezifikation für die Bereitstellung maschinenlesbarer Fehlerdetails in einer HTTP-Antwort.
Betrachten Sie den folgenden Code in einer Controlleraktion:
if (pet == null)
{
return NotFound();
}
Die NotFound
-Methode erzeugt einen HTTP-404-Statuscode mit einem ProblemDetails
-Text. Zum Beispiel:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Deaktivieren der ProblemDetails-Antwort
Die automatische Erstellung einer ProblemDetails
-Antwort für Fehlerstatuscodes ist deaktiviert, wenn die SuppressMapClientErrors-Eigenschaft auf true
festgelegt ist. Fügen Sie den folgenden Code hinzu:
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();
Definieren unterstützter Anforderungsinhaltstypen mit dem [Consumes]-Attribut
Standardmäßig unterstützt eine Aktion alle verfügbaren Anforderungsinhaltstypen. Wenn eine App beispielsweise zur Unterstützung von JSON- und XML-Eingabeformatierern konfiguriert ist, unterstützt eine Aktion mehrere Inhaltstypen, wie etwa application/json
und application/xml
.
Das [Consumes]-Attribut ermöglicht es einer Aktion, die unterstützten Anforderungsinhaltstypen einzuschränken. Wenden Sie das [Consumes]
-Attribut auf eine Aktion oder einen Controller an, und geben Sie mindestens einen Inhaltstyp an:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Im obigen Code gibt die CreateProduct
-Aktion den Inhaltstyp application/xml
an. Anforderungen, die an diese Aktion weitergeleitet werden, müssen den Content-Type
-Header application/xml
angeben. Für Anforderungen, die den Content-Type
-Header application/xml
nicht angeben, wird die Antwort 415 – Nicht unterstützter Medientyp zurückgegeben.
Das [Consumes]
-Attribut ermöglicht es einer Aktion auch, eine Typeinschränkung anzuwenden, um die Auswahl basierend auf dem Inhaltstyp einer eingehenden Anforderung zu beeinflussen. Betrachten Sie das folgende Beispiel:
[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 });
}
Im obigen Code ist ConsumesController
zur Verarbeitung von Anforderungen konfiguriert, die an die URL https://localhost:5001/api/Consumes
gesendet werden. Beide Controlleraktionen – PostJson
und PostForm
– verarbeiten POST-Anforderungen mit derselben URL. Wenn das [Consumes]
-Attribut keine Typeinschränkung anwendet, wird eine Ausnahme in Bezug auf eine mehrdeutige Übereinstimmung ausgelöst.
Das [Consumes]
-Attribut wird auf beide Aktionen angewendet. Die PostJson
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/json
gesendet werden. Die PostForm
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/x-www-form-urlencoded
gesendet werden.
Zusätzliche Ressourcen
- Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen)
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Behandeln von Fehlern in ASP.NET Core-controllerbasierten Web-APIs
- Benutzerdefinierte Formatierer in Web-APIs in ASP.NET Core
- Formatieren von Antwortdaten in Web-APIs in ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Routing zu Controlleraktionen in ASP.NET Core
- Verwenden von Porttunneln in Visual Studio zum Debuggen von Web-APIs
- Erstellen einer Web-API mit ASP.NET Core
ASP.NET Core unterstützt das Erstellen von Web-APIs mithilfe von Controllern oder minimalen APIs. Controller in einer Web-API sind von ControllerBase abgeleitete Klassen. In diesem Artikel wird beschrieben, wie Sie Controller für die Verarbeitung von Web-API-Anforderungen verwenden. Informationen zum Erstellen von Web-APIs ohne Controller finden Sie im Tutorial: Erstellen einer minimalen API mit ASP.NET Core.
ControllerBase-Klasse
Eine controllerbasierte Web-API besteht aus mindestens einer Controllerklasse, die von ControllerBase abgeleitet ist. Die Web-API-Projektvorlage stellt einen Startercontroller bereit:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Web-API-Controller sollten in der Regel eher von ControllerBase als von Controller ableiten. Controller
wird von ControllerBase abgeleitet und fügt Unterstützung für Ansichten hinzu, wird also für die Verarbeitung von Webseiten verwendet und nicht für Web-API-Anforderungen. Wenn derselbe Controller Ansichten und Web-APIs unterstützen muss, leiten Sie von Controller
ab.
Die ControllerBase
-Klasse bietet viele Eigenschaften und Methoden, die für die Verarbeitung von HTTP-Anforderungen hilfreich sind. CreatedAtAction gibt beispielsweise Statuscode 201 zurück:
[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);
}
Die folgende Tabelle enthält Beispiele für gängige Methoden in ControllerBase
.
Methode | Hinweise |
---|---|
BadRequest | Gibt Statuscode 400 zurück. |
NotFound | Gibt Statuscode 404 zurück. |
PhysicalFile | Gibt eine Datei zurück. |
TryUpdateModelAsync | Ruft die Modellbindung auf. |
TryValidateModel | Ruft die Modellvalidierung auf. |
Eine Liste aller verfügbaren Methoden und Eigenschaften finden Sie unter ControllerBase.
Attribute
Der Microsoft.AspNetCore.Mvc-Namespace enthält Attribute, mit denen das Verhalten von Web-API-Controllern und Aktionsmethoden konfiguriert werden kann. Im folgenden Beispiel werden Attribute verwendet, um das unterstützte HTTP-Aktionsverb und alle bekannten HTTP-Statuscodes, die zurückgegeben werden können, anzugeben:
[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 einige weitere Beispiele für die verfügbaren Attribute.
Attribut | Hinweise |
---|---|
[Route] |
Gibt ein URL-Muster für einen Controller oder eine Aktion an. |
[Bind] |
Gibt Präfixe und Eigenschaften an, die in die Modellbindung einbezogen werden sollen. |
[HttpGet] |
Identifiziert eine Aktion, die das HTTP GET-Aktionsverb unterstützt. |
[Consumes] |
Gibt die von einer Aktion akzeptierten Datentypen an. |
[Produces] |
Gibt die von einer Aktion zurückgegebenen Datentypen an. |
Eine Liste mit den verfügbaren Attributen finden Sie im Microsoft.AspNetCore.Mvc-Namespace.
ApiController-Attribut
Das [ApiController]
-Attribut kann auf eine Controllerklasse angewendet werden, um folgende API-spezifische Verhalten mit einigen vordefinierten Konfigurationen zu aktivieren:
- Anforderung für das Attributrouting
- Automatische HTTP 400-Antworten
- Rückschluss auf Bindungsquellparameter
- Ableiten der Multipart/form-data-Anforderung
- Problemdetails für Fehlerstatuscodes
Attribut für bestimmte Controller
Das [ApiController]
-Attribut kann, wie im folgenden Beispiel der Projektvorlage ersichtlich, auf bestimmte Controller angewendet werden:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Attribut für mehrere Controller
Eine Möglichkeit, das Attribut für mehr als einen Controller zu verwenden, besteht darin, eine benutzerdefinierte Basiscontrollerklasse zu erstellen, die mit dem [ApiController]
-Attribut kommentiert ist. Im folgenden Beispiel wird eine benutzerdefinierte Basisklasse und ein Controller, der von ihr abgeleitet wird, gezeigt:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Attribut für eine Assembly
Auf Assemblys kann das [ApiController]
-Attribut angewendet werden. Wenn das [ApiController]
-Attribut auf eine Assembly angewendet wird, wird auf alle Controller in der Assembly das [ApiController]
-Attribut angewendet. Es gibt keine Möglichkeit, einzelne Controller auszuschließen. Wenden Sie das Attribut auf Assemblyebene auf die Program.cs
-Datei an:
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();
Anforderung für das Attributrouting
Durch das [ApiController]
-Attribut wird das Attributrouting zu einer Anforderung. Zum Beispiel:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Sie können über konventionelle Routen, die durch UseEndpoints
, UseMvc oder UseMvcWithDefaultRoute definiert sind, nicht auf Aktionen zugreifen.
Automatische HTTP 400-Antwort
Durch das [ApiController]
-Attribut wird bei Modellvalidierungsfehlern automatisch eine HTTP 400-Antwort ausgelöst. Deshalb ist der folgende Code in einer Aktionsmethode überflüssig:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC verwendet den ModelStateInvalidFilter-Aktionsfilter, um die vorherige Überprüfung durchzuführen.
Standardmäßige BadRequest-Antwort
Der folgende Antworttext ist ein Beispiel für den serialisierten Typ:
{
"": [
"A non-empty request body is required."
]
}
Für eine HTTP 400-Antwort wird standardmäßig der Antworttyp ValidationProblemDetails verwendet. Der folgende Antworttext ist ein Beispiel für den serialisierten Typ:
{
"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."
]
}
}
Der ValidationProblemDetails
-Typ:
- Bietet ein vom Computer lesbares Format zum Angeben von Fehlern in Web-API-Antworten.
- Entspricht der RFC 7807-Spezifikation.
Rufen Sie die ValidationProblem-Methode anstelle von BadRequest auf, um automatische und benutzerdefinierte Antworten konsistent zu machen. ValidationProblem
gibt sowohl ein ValidationProblemDetails-Objekt als auch die automatische Antwort zurück.
Protokollieren automatischer 400-Antworten
Um automatische 400-Antworten zu protokollieren, legen Sie die InvalidModelStateResponseFactory-Delegateneigenschaft fest, um benutzerdefinierte Verarbeitung auszuführen. Zum Erstellen einer Instanz von ValidationProblemDetails verwendet InvalidModelStateResponseFactory
standardmäßig ProblemDetailsFactory.
Im folgenden Beispiel wird gezeigt, wie Sie eine Instanz von ILogger<TCategoryName> abrufen, um Informationen zu einer automatischen 400-Antwort zu protokollieren:
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();
Deaktivieren automatischer 400-Antwort
Um das automatische Verhalten bei Statuscode 400 zu deaktivieren, legen Sie die SuppressModelStateInvalidFilter-Eigenschaft auf true
fest. Fügen Sie folgenden hervorgehobenen Code hinzu:
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();
Rückschluss auf Bindungsquellparameter
Ein Bindungsquellenattribut definiert den Speicherort, an dem der Wert eines Aktionsparameters vorhanden ist. Es gibt die folgenden Bindungsquellattribute:
Attribut | Bindungsquelle |
---|---|
[FromBody] |
Anforderungstext |
[FromForm] |
Formulardaten im Anforderungstext |
[FromHeader] |
Anforderungsheader |
[FromQuery] |
Abfragezeichenfolge-Parameter der Anforderung |
[FromRoute] |
Routendaten aus aktuellen Anforderungen |
[FromServices] |
Der als Aktionsparameter eingefügte Anforderungsdienst. |
Warnung
Verwenden Sie [FromRoute]
nicht, wenn Werte möglicherweise %2f
enthalten (d.h. /
). %2f
wird nicht durch Entfernen von Escapezeichen zu /
. Verwenden Sie [FromQuery]
, wenn der Wert %2f
enthalten könnte.
Ohne das [ApiController]
-Attribut oder Bindungsquellenattribute wie [FromQuery]
versucht die ASP.NET Core-Runtime, die Modellbindung für komplexe Objekte zu verwenden. Bei der Modellbindung für komplexe Objekte werden Daten aus Wertanbietern in einer festgelegten Reihenfolge abgerufen.
Im folgenden Beispiel gibt das [FromQuery]
-Attribut an, dass der Parameterwert discontinuedOnly
in der Abfragezeichenfolge der Anforderungs-URL bereitgestellt wird:
[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;
}
Das [ApiController]
-Attribut wendet Rückschlussregeln auf die Standarddatenquellen von Aktionsparametern an. Da durch diese Regeln Attribute auf die Aktionsparameter angewendet werden, müssen Sie Bindungsquellen nicht manuell identifizieren. Die Rückschlussregeln für Bindungsquellen verhalten sich wie folgt:
[FromBody]
wird für komplexe Typparameter abgeleitet, die nicht im DI-Container registriert sind. Jeder komplexe integrierte Typ mit spezieller Bedeutung, z. B. IFormCollection und CancellationToken, stellt eine Ausnahme von der[FromBody]
-Rückschlussregel dar. Der Rückschlusscode der Bindungsquelle ignoriert diese Typen.[FromForm]
wird für Aktionsparameter des Typs IFormFile und IFormFileCollection abgeleitet. Es wird für keine einfachen oder benutzerdefinierte Typen abgeleitet.[FromRoute]
wird für jeden Namen von Aktionsparametern abgeleitet, der mit einem Parameter in der Routenvorlage übereinstimmt. Wenn mehr als eine Route mit einem Aktionsparameter übereinstimmt, gilt jeder Routenwert als[FromRoute]
.[FromQuery]
wird für alle anderen Aktionsparameter abgeleitet.
Hinweise zum FromBody-Rückschluss
[FromBody]
wird für einfache Typen wie string
oder int
nicht abgeleitet. Deshalb sollte das [FromBody]
-Attribut für einfache Typen verwendet werden, wenn diese Funktionsweise benötigt wird.
Wenn an eine Aktion mehr als ein Parameter aus dem Anforderungstext gebunden ist, wird eine Ausnahme ausgelöst. Beispielsweise lösen alle Signaturen der folgenden Aktionsmethoden eine Ausnahme aus:
[FromBody]
wird für beide abgeleitet, da sie komplexe Typen darstellen.[HttpPost] public IActionResult Action1(Product product, Order order)
Das
[FromBody]
-Attribut für einen Typ wird für den anderen abgeleitet, da es sich um einen komplexen Typ handelt.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Das
[FromBody]
-Attribut für beide.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Deaktivieren von Rückschlussregeln
Legen Sie SuppressInferBindingSourcesForParameters auf true
fest, um den Rückschluss auf Bindungsquellen zu deaktivieren:
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();
Ableiten der Multipart/form-data-Anforderung
Das [ApiController]
-Attribut wendet eine Rückschlussregel für Aktionsparameter des Typs IFormFile und IFormFileCollection an. Der multipart/form-data
-Anforderungsinhaltstyp wird für diese Typen abgeleitet.
Legen Sie die SuppressConsumesConstraintForFormFileParameters-Eigenschaft auf true
fest, um das Standardverhalten zu deaktivieren:
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();
Problemdetails für Fehlerstatuscodes
MVC wandelt ein Fehlerergebnis (ein Ergebnis mit dem Statuscode 400 oder höher) in ein Ergebnis mit ProblemDetails um. Die ProblemDetails
-Typ basiert auf der RFC 7807-Spezifikation für die Bereitstellung maschinenlesbarer Fehlerdetails in einer HTTP-Antwort.
Betrachten Sie den folgenden Code in einer Controlleraktion:
if (pet == null)
{
return NotFound();
}
Die NotFound
-Methode erzeugt einen HTTP-404-Statuscode mit einem ProblemDetails
-Text. Zum Beispiel:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Deaktivieren der ProblemDetails-Antwort
Die automatische Erstellung einer ProblemDetails
-Antwort für Fehlerstatuscodes ist deaktiviert, wenn die SuppressMapClientErrors-Eigenschaft auf true
festgelegt ist:
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();
Definieren unterstützter Anforderungsinhaltstypen mit dem [Consumes]-Attribut
Standardmäßig unterstützt eine Aktion alle verfügbaren Anforderungsinhaltstypen. Wenn eine App beispielsweise zur Unterstützung von JSON- und XML-Eingabeformatierern konfiguriert ist, unterstützt eine Aktion mehrere Inhaltstypen, wie etwa application/json
und application/xml
.
Das [Consumes]-Attribut ermöglicht es einer Aktion, die unterstützten Anforderungsinhaltstypen einzuschränken. Wenden Sie das [Consumes]
-Attribut auf eine Aktion oder einen Controller an, und geben Sie mindestens einen Inhaltstyp an:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Im obigen Code gibt die CreateProduct
-Aktion den Inhaltstyp application/xml
an. Anforderungen, die an diese Aktion weitergeleitet werden, müssen den Content-Type
-Header application/xml
angeben. Für Anforderungen, die den Content-Type
-Header application/xml
nicht angeben, wird die Antwort 415 – Nicht unterstützter Medientyp zurückgegeben.
Das [Consumes]
-Attribut ermöglicht es einer Aktion auch, eine Typeinschränkung anzuwenden, um die Auswahl basierend auf dem Inhaltstyp einer eingehenden Anforderung zu beeinflussen. Betrachten Sie das folgende Beispiel:
[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 });
}
Im obigen Code ist ConsumesController
zur Verarbeitung von Anforderungen konfiguriert, die an die URL https://localhost:5001/api/Consumes
gesendet werden. Beide Controlleraktionen – PostJson
und PostForm
– verarbeiten POST-Anforderungen mit derselben URL. Wenn das [Consumes]
-Attribut keine Typeinschränkung anwendet, wird eine Ausnahme in Bezug auf eine mehrdeutige Übereinstimmung ausgelöst.
Das [Consumes]
-Attribut wird auf beide Aktionen angewendet. Die PostJson
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/json
gesendet werden. Die PostForm
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/x-www-form-urlencoded
gesendet werden.
Zusätzliche Ressourcen
- Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen)
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Behandeln von Fehlern in ASP.NET Core-controllerbasierten Web-APIs
- Benutzerdefinierte Formatierer in Web-APIs in ASP.NET Core
- Formatieren von Antwortdaten in Web-APIs in ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Routing zu Controlleraktionen in ASP.NET Core
- Verwenden von Porttunneln in Visual Studio zum Debuggen von Web-APIs
- Erstellen einer Web-API mit ASP.NET Core
ASP.NET Core unterstützt das Erstellen von RESTful-Diensten mit C#, die auch als Web-APIs bekannt sind. Eine Web-API verwendet Controller, um Anforderungen zu verarbeiten. Controller in einer Web-API sind von ControllerBase
abgeleitete Klassen. In diesem Artikel wird beschrieben, wie Sie Controller für die Verarbeitung von Web-API-Anforderungen verwenden.
Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen)
ControllerBase-Klasse
Eine Web-API besteht aus mindestens einer Controllerklasse, die von ControllerBase abgeleitet ist. Die Web-API-Projektvorlage stellt einen Startercontroller bereit:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Erstellen Sie einen Web-API-Controller nicht durch Ableitung aus der Controller-Klasse. Controller
wird von ControllerBase
abgeleitet und fügt Unterstützung für Ansichten hinzu, wird also für die Verarbeitung von Webseiten verwendet und nicht für Web-API-Anforderungen. Es gibt eine Ausnahme von dieser Regel: Wenn Sie denselben Controller sowohl für Ansichten als auch für Web-APIs verwenden möchten, leiten Sie ihn von Controller
ab.
Die ControllerBase
-Klasse bietet viele Eigenschaften und Methoden, die für die Verarbeitung von HTTP-Anforderungen hilfreich sind. ControllerBase.CreatedAtAction
gibt beispielsweise Statuscode 201 zurück:
[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 einige weitere Beispiele für die von ControllerBase
bereitgestellten Methoden.
Methode | Hinweise |
---|---|
BadRequest | Gibt Statuscode 400 zurück. |
NotFound | Gibt Statuscode 404 zurück. |
PhysicalFile | Gibt eine Datei zurück. |
TryUpdateModelAsync | Ruft die Modellbindung auf. |
TryValidateModel | Ruft die Modellvalidierung auf. |
Eine Liste aller verfügbaren Methoden und Eigenschaften finden Sie unter ControllerBase.
Attribute
Der Microsoft.AspNetCore.Mvc-Namespace enthält Attribute, mit denen das Verhalten von Web-API-Controllern und Aktionsmethoden konfiguriert werden kann. Im folgenden Beispiel werden Attribute verwendet, um das unterstützte HTTP-Aktionsverb und alle bekannten HTTP-Statuscodes, die zurückgegeben werden können, anzugeben:
[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 einige weitere Beispiele für die verfügbaren Attribute.
Attribut | Hinweise |
---|---|
[Route] |
Gibt ein URL-Muster für einen Controller oder eine Aktion an. |
[Bind] |
Gibt Präfixe und Eigenschaften an, die in die Modellbindung einbezogen werden sollen. |
[HttpGet] |
Identifiziert eine Aktion, die das HTTP GET-Aktionsverb unterstützt. |
[Consumes] |
Gibt die von einer Aktion akzeptierten Datentypen an. |
[Produces] |
Gibt die von einer Aktion zurückgegebenen Datentypen an. |
Eine Liste mit den verfügbaren Attributen finden Sie im Microsoft.AspNetCore.Mvc-Namespace.
ApiController-Attribut
Das [ApiController]
-Attribut kann auf eine Controllerklasse angewendet werden, um folgende API-spezifische Verhalten mit einigen vordefinierten Konfigurationen zu aktivieren:
- Anforderung für das Attributrouting
- Automatische HTTP 400-Antworten
- Rückschluss auf Bindungsquellparameter
- Ableiten der Multipart/form-data-Anforderung
- Problemdetails für Fehlerstatuscodes
Attribut für bestimmte Controller
Das [ApiController]
-Attribut kann, wie im folgenden Beispiel der Projektvorlage ersichtlich, auf bestimmte Controller angewendet werden:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Attribut für mehrere Controller
Eine Möglichkeit, das Attribut für mehr als einen Controller zu verwenden, besteht darin, eine benutzerdefinierte Basiscontrollerklasse zu erstellen, die mit dem [ApiController]
-Attribut kommentiert ist. Im folgenden Beispiel wird eine benutzerdefinierte Basisklasse und ein Controller, der von ihr abgeleitet wird, gezeigt:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
Attribut für eine Assembly
Auf Assemblys kann das [ApiController]
-Attribut angewendet werden. Auf diese Weise wendet die Anmerkung das Web-API-Verhalten auf alle Controller in der Assembly an. Es gibt keine Möglichkeit, einzelne Controller auszuschließen. Wenden Sie das Attribut auf Assemblyebene auf die Namespacedeklaration an, die die Startup
-Klasse umgibt:
[assembly: ApiController]
namespace WebApiSample
{
public class Startup
{
...
}
}
Anforderung für das Attributrouting
Durch das [ApiController]
-Attribut wird das Attributrouting zu einer Anforderung. Zum Beispiel:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Sie können über konventionelle Routen, die durch UseEndpoints
, UseMvc oder UseMvcWithDefaultRoute in Startup.Configure
definiert sind, nicht auf Aktionen zugreifen.
Automatische HTTP 400-Antwort
Durch das [ApiController]
-Attribut wird bei Modellvalidierungsfehlern automatisch eine HTTP 400-Antwort ausgelöst. Deshalb ist der folgende Code in einer Aktionsmethode überflüssig:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC verwendet den ModelStateInvalidFilter-Aktionsfilter, um die vorherige Überprüfung durchzuführen.
Standardmäßige BadRequest-Antwort
Der folgende Anforderungstext ist ein Beispiel für den serialisierten Typ:
{
"": [
"A non-empty request body is required."
]
}
Für eine HTTP 400-Antwort wird standardmäßig der Antworttyp ValidationProblemDetails verwendet. Der folgende Anforderungstext ist ein Beispiel für den serialisierten Typ:
{
"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."
]
}
}
Der ValidationProblemDetails
-Typ:
- Bietet ein vom Computer lesbares Format zum Angeben von Fehlern in Web-API-Antworten.
- Entspricht der RFC 7807-Spezifikation.
Rufen Sie die ValidationProblem-Methode anstelle von BadRequest auf, um automatische und benutzerdefinierte Antworten konsistent zu machen. ValidationProblem
gibt sowohl ein ValidationProblemDetails-Objekt als auch die automatische Antwort zurück.
Protokollieren automatischer 400-Antworten
Um automatische 400-Antworten zu protokollieren, legen Sie die InvalidModelStateResponseFactory-Delegateneigenschaft in Startup.ConfigureServices
fest, um benutzerdefinierte Verarbeitung auszuführen. Zum Erstellen einer Instanz von ValidationProblemDetails verwendet InvalidModelStateResponseFactory
standardmäßig ProblemDetailsFactory.
Im folgenden Beispiel wird gezeigt, wie Sie eine Instanz von ILogger<TCategoryName> abrufen, um Informationen zu einer automatischen 400-Antwort zu protokollieren:
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);
};
});
Deaktivieren automatischer 400-Antwort
Um das automatische Verhalten bei Statuscode 400 zu deaktivieren, legen Sie die SuppressModelStateInvalidFilter-Eigenschaft auf true
fest. Fügen Sie folgenden hervorgehobenen Code in Startup.ConfigureServices
hinzu:
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;
});
Rückschluss auf Bindungsquellparameter
Ein Bindungsquellenattribut definiert den Speicherort, an dem der Wert eines Aktionsparameters vorhanden ist. Es gibt die folgenden Bindungsquellattribute:
Attribut | Bindungsquelle |
---|---|
[FromBody] |
Anforderungstext |
[FromForm] |
Formulardaten im Anforderungstext |
[FromHeader] |
Anforderungsheader |
[FromQuery] |
Abfragezeichenfolge-Parameter der Anforderung |
[FromRoute] |
Routendaten aus aktuellen Anforderungen |
[FromServices] |
Der als Aktionsparameter eingefügte Anforderungsdienst. |
Warnung
Verwenden Sie [FromRoute]
nicht, wenn Werte möglicherweise %2f
enthalten (d.h. /
). %2f
wird nicht durch Entfernen von Escapezeichen zu /
. Verwenden Sie [FromQuery]
, wenn der Wert %2f
enthalten könnte.
Ohne das [ApiController]
-Attribut oder Bindungsquellenattribute wie [FromQuery]
versucht die ASP.NET Core-Runtime, die Modellbindung für komplexe Objekte zu verwenden. Bei der Modellbindung für komplexe Objekte werden Daten aus Wertanbietern in einer festgelegten Reihenfolge abgerufen.
Im folgenden Beispiel gibt das [FromQuery]
-Attribut an, dass der Parameterwert discontinuedOnly
in der Abfragezeichenfolge der Anforderungs-URL bereitgestellt wird:
[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;
}
Das [ApiController]
-Attribut wendet Rückschlussregeln auf die Standarddatenquellen von Aktionsparametern an. Da durch diese Regeln Attribute auf die Aktionsparameter angewendet werden, müssen Sie Bindungsquellen nicht manuell identifizieren. Die Rückschlussregeln für Bindungsquellen verhalten sich wie folgt:
[FromBody]
wird für komplexe Typparameter abgeleitet. Jeder komplexe integrierte Typ mit spezieller Bedeutung, z. B. IFormCollection und CancellationToken, stellt eine Ausnahme von der[FromBody]
-Rückschlussregel dar. Der Rückschlusscode der Bindungsquelle ignoriert diese Typen.[FromForm]
wird für Aktionsparameter des Typs IFormFile und IFormFileCollection abgeleitet. Es wird für keine einfachen oder benutzerdefinierte Typen abgeleitet.[FromRoute]
wird für jeden Namen von Aktionsparametern abgeleitet, der mit einem Parameter in der Routenvorlage übereinstimmt. Wenn mehr als eine Route mit einem Aktionsparameter übereinstimmt, gilt jeder Routenwert als[FromRoute]
.[FromQuery]
wird für alle anderen Aktionsparameter abgeleitet.
Hinweise zum FromBody-Rückschluss
[FromBody]
wird für einfache Typen wie string
oder int
nicht abgeleitet. Deshalb sollte das [FromBody]
-Attribut für einfache Typen verwendet werden, wenn diese Funktionsweise benötigt wird.
Wenn an eine Aktion mehr als ein Parameter aus dem Anforderungstext gebunden ist, wird eine Ausnahme ausgelöst. Beispielsweise lösen alle Signaturen der folgenden Aktionsmethoden eine Ausnahme aus:
[FromBody]
wird für beide abgeleitet, da sie komplexe Typen darstellen.[HttpPost] public IActionResult Action1(Product product, Order order)
Das
[FromBody]
-Attribut für einen Typ wird für den anderen abgeleitet, da es sich um einen komplexen Typ handelt.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Das
[FromBody]
-Attribut für beide.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Deaktivieren von Rückschlussregeln
Legen Sie SuppressInferBindingSourcesForParameters auf true
fest, um den Rückschluss auf Bindungsquellen zu deaktivieren. Fügen Sie den folgenden Code zu Startup.ConfigureServices
hinzu:
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;
});
Ableiten der Multipart/form-data-Anforderung
Das [ApiController]
-Attribut wendet eine Rückschlussregel für Aktionsparameter des Typs IFormFile und IFormFileCollection an. Der multipart/form-data
-Anforderungsinhaltstyp wird für diese Typen abgeleitet.
Legen Sie die SuppressConsumesConstraintForFormFileParameters-Eigenschaft auf true
in Startup.ConfigureServices
fest, um das Standardverhalten zu deaktivieren.
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;
});
Problemdetails für Fehlerstatuscodes
MVC wandelt ein Fehlerergebnis (ein Ergebnis mit dem Statuscode 400 oder höher) in ein Ergebnis mit ProblemDetails um. Die ProblemDetails
-Typ basiert auf der RFC 7807-Spezifikation für die Bereitstellung maschinenlesbarer Fehlerdetails in einer HTTP-Antwort.
Betrachten Sie den folgenden Code in einer Controlleraktion:
if (pet == null)
{
return NotFound();
}
Die NotFound
-Methode erzeugt einen HTTP-404-Statuscode mit einem ProblemDetails
-Text. Zum Beispiel:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Deaktivieren der ProblemDetails-Antwort
Die automatische Erstellung einer ProblemDetails
-Antwort für Fehlerstatuscodes ist deaktiviert, wenn die SuppressMapClientErrors-Eigenschaft auf true
festgelegt ist. Fügen Sie den folgenden Code zu Startup.ConfigureServices
hinzu:
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;
});
Definieren unterstützter Anforderungsinhaltstypen mit dem [Consumes]-Attribut
Standardmäßig unterstützt eine Aktion alle verfügbaren Anforderungsinhaltstypen. Wenn eine App beispielsweise zur Unterstützung von JSON- und XML-Eingabeformatierern konfiguriert ist, unterstützt eine Aktion mehrere Inhaltstypen, wie etwa application/json
und application/xml
.
Das [Consumes]-Attribut ermöglicht es einer Aktion, die unterstützten Anforderungsinhaltstypen einzuschränken. Wenden Sie das [Consumes]
-Attribut auf eine Aktion oder einen Controller an, und geben Sie mindestens einen Inhaltstyp an:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Im obigen Code gibt die CreateProduct
-Aktion den Inhaltstyp application/xml
an. Anforderungen, die an diese Aktion weitergeleitet werden, müssen den Content-Type
-Header application/xml
angeben. Für Anforderungen, die den Content-Type
-Header application/xml
nicht angeben, wird die Antwort 415 – Nicht unterstützter Medientyp zurückgegeben.
Das [Consumes]
-Attribut ermöglicht es einer Aktion auch, eine Typeinschränkung anzuwenden, um die Auswahl basierend auf dem Inhaltstyp einer eingehenden Anforderung zu beeinflussen. Betrachten Sie das folgende Beispiel:
[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 });
}
Im obigen Code ist ConsumesController
zur Verarbeitung von Anforderungen konfiguriert, die an die URL https://localhost:5001/api/Consumes
gesendet werden. Beide Controlleraktionen – PostJson
und PostForm
– verarbeiten POST-Anforderungen mit derselben URL. Wenn das [Consumes]
-Attribut keine Typeinschränkung anwendet, wird eine Ausnahme in Bezug auf eine mehrdeutige Übereinstimmung ausgelöst.
Das [Consumes]
-Attribut wird auf beide Aktionen angewendet. Die PostJson
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/json
gesendet werden. Die PostForm
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/x-www-form-urlencoded
gesendet werden.
Zusätzliche Ressourcen
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Behandeln von Fehlern in ASP.NET Core-controllerbasierten Web-APIs
- Benutzerdefinierte Formatierer in Web-APIs in ASP.NET Core
- Formatieren von Antwortdaten in Web-APIs in ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Routing zu Controlleraktionen in ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Erstellen Sie einen Web-API-Controller nicht durch Ableitung aus der Controller-Klasse. Controller
wird von ControllerBase
abgeleitet und fügt Unterstützung für Ansichten hinzu, wird also für die Verarbeitung von Webseiten verwendet und nicht für Web-API-Anforderungen. Es gibt eine Ausnahme von dieser Regel: Wenn Sie denselben Controller sowohl für Ansichten als auch für Web-APIs verwenden möchten, leiten Sie ihn von Controller
ab.
Die ControllerBase
-Klasse bietet viele Eigenschaften und Methoden, die für die Verarbeitung von HTTP-Anforderungen hilfreich sind. ControllerBase.CreatedAtAction
gibt beispielsweise Statuscode 201 zurück:
[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 sind einige weitere Beispiele für die von ControllerBase
bereitgestellten Methoden:
Methode | Hinweise |
---|---|
BadRequest | Gibt Statuscode 400 zurück. |
NotFound | Gibt Statuscode 404 zurück. |
PhysicalFile | Gibt eine Datei zurück. |
TryUpdateModelAsync | Ruft die Modellbindung auf. |
TryValidateModel | Ruft die Modellvalidierung auf. |
Eine Liste aller verfügbaren Methoden und Eigenschaften finden Sie unter ControllerBase.
Attribute
Der Microsoft.AspNetCore.Mvc-Namespace enthält Attribute, mit denen das Verhalten von Web-API-Controllern und Aktionsmethoden konfiguriert werden kann. Im folgenden Beispiel werden Attribute verwendet, um das unterstützte HTTP-Aktionsverb und alle bekannten HTTP-Statuscodes, die zurückgegeben werden können, anzugeben:
[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 sind einige weitere Beispiele für die verfügbaren Attribute:
Attribut | Hinweise |
---|---|
[Route] |
Gibt ein URL-Muster für einen Controller oder eine Aktion an. |
[Bind] |
Gibt Präfixe und Eigenschaften an, die in die Modellbindung einbezogen werden sollen. |
[HttpGet] |
Identifiziert eine Aktion, die das HTTP GET-Aktionsverb unterstützt. |
[Consumes] |
Gibt die von einer Aktion akzeptierten Datentypen an. |
[Produces] |
Gibt die von einer Aktion zurückgegebenen Datentypen an. |
Eine Liste mit den verfügbaren Attributen finden Sie im Microsoft.AspNetCore.Mvc-Namespace.
ApiController-Attribut
Das [ApiController]
-Attribut kann auf eine Controllerklasse angewendet werden, um folgende API-spezifische Verhalten mit einigen vordefinierten Konfigurationen zu aktivieren:
- Anforderung für das Attributrouting
- Automatische HTTP 400-Antworten
- Rückschluss auf Bindungsquellparameter
- Ableiten der Multipart/form-data-Anforderung
- Problemdetails für Fehlerstatuscodes Das Feature Problemdetails für Fehlerstatuscodes erfordert mindestens die Kompatibilitätsversion 2.2. Die anderen Features erfordern mindestens Kompatibilitätsversion 2.1.
- Anforderung für das Attributrouting
- Automatische HTTP 400-Antworten
- Rückschluss auf Bindungsquellparameter
- Multipart/form-data-Anforderungsrückschluss Diese Features erfordern eine Kompatibilitätsversion von 2.1 oder höher.
Attribut für bestimmte Controller
Das [ApiController]
-Attribut kann, wie im folgenden Beispiel der Projektvorlage ersichtlich, auf bestimmte Controller angewendet werden:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Attribut für mehrere Controller
Eine Möglichkeit, das Attribut für mehr als einen Controller zu verwenden, besteht darin, eine benutzerdefinierte Basiscontrollerklasse zu erstellen, die mit dem [ApiController]
-Attribut kommentiert ist. Im folgenden Beispiel wird eine benutzerdefinierte Basisklasse und ein Controller, der von ihr abgeleitet wird, gezeigt:
[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase
Attribut für eine Assembly
Wenn die Kompatibilitätsversion auf 2.2 oder höher festgelegt ist, kann das [ApiController]
-Attribut auf eine Assembly angewendet werden. Auf diese Weise wendet die Anmerkung das Web-API-Verhalten auf alle Controller in der Assembly an. Es gibt keine Möglichkeit, einzelne Controller auszuschließen. Wenden Sie das Attribut auf Assemblyebene auf die Namespacedeklaration an, die die Startup
-Klasse umgibt:
[assembly: ApiController]
namespace WebApiSample
{
public class Startup
{
...
}
}
Anforderung für das Attributrouting
Durch das [ApiController]
-Attribut wird das Attributrouting zu einer Anforderung. Zum Beispiel:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
Sie können über konventionelle Routen, die durch UseMvc oder UseMvcWithDefaultRoute in Startup.Configure
definiert sind, nicht auf Aktionen zugreifen.
Automatische HTTP 400-Antwort
Durch das [ApiController]
-Attribut wird bei Modellvalidierungsfehlern automatisch eine HTTP 400-Antwort ausgelöst. Deshalb ist der folgende Code in einer Aktionsmethode überflüssig:
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ASP.NET Core MVC verwendet den ModelStateInvalidFilter-Aktionsfilter, um die vorherige Überprüfung durchzuführen.
Standardmäßige BadRequest-Antwort
Bei Kompatibilitätsversion 2.1 wird für eine HTTP 400-Antwort standardmäßig der Antworttyp SerializableError verwendet. Der folgende Anforderungstext ist ein Beispiel für den serialisierten Typ:
{
"": [
"A non-empty request body is required."
]
}
Bei Kompatibilitätsversion 2.2 oder höher wird für eine HTTP 400-Antwort standardmäßig der Antworttyp ValidationProblemDetails verwendet. Der folgende Anforderungstext ist ein Beispiel für den serialisierten Typ:
{
"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."
]
}
}
Der ValidationProblemDetails
-Typ:
- Bietet ein vom Computer lesbares Format zum Angeben von Fehlern in Web-API-Antworten.
- Entspricht der RFC 7807-Spezifikation.
Rufen Sie die ValidationProblem-Methode anstelle von BadRequest auf, um automatische und benutzerdefinierte Antworten konsistent zu machen. ValidationProblem
gibt sowohl ein ValidationProblemDetails-Objekt als auch die automatische Antwort zurück.
Protokollieren automatischer 400-Antworten
Informationen finden Sie unter Protokollieren automatischer 400-Antworten auf Modellvalidierungsfehler, (dotnet/AspNetCore.Docs#12157).
Deaktivieren automatischer 400-Antwort
Um das automatische Verhalten bei Statuscode 400 zu deaktivieren, legen Sie die SuppressModelStateInvalidFilter-Eigenschaft auf true
fest. Fügen Sie folgenden hervorgehobenen Code in Startup.ConfigureServices
hinzu:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Rückschluss auf Bindungsquellparameter
Ein Bindungsquellenattribut definiert den Speicherort, an dem der Wert eines Aktionsparameters vorhanden ist. Es gibt die folgenden Bindungsquellattribute:
Attribut | Bindungsquelle |
---|---|
[FromBody] |
Anforderungstext |
[FromForm] |
Formulardaten im Anforderungstext |
[FromHeader] |
Anforderungsheader |
[FromQuery] |
Abfragezeichenfolge-Parameter der Anforderung |
[FromRoute] |
Routendaten aus aktuellen Anforderungen |
[FromServices] |
Der als Aktionsparameter eingefügte Anforderungsdienst. |
Warnung
Verwenden Sie [FromRoute]
nicht, wenn Werte möglicherweise %2f
enthalten (d.h. /
). %2f
wird nicht durch Entfernen von Escapezeichen zu /
. Verwenden Sie [FromQuery]
, wenn der Wert %2f
enthalten könnte.
Ohne das [ApiController]
-Attribut oder Bindungsquellenattribute wie [FromQuery]
versucht die ASP.NET Core-Runtime, die Modellbindung für komplexe Objekte zu verwenden. Bei der Modellbindung für komplexe Objekte werden Daten aus Wertanbietern in einer festgelegten Reihenfolge abgerufen.
Im folgenden Beispiel gibt das [FromQuery]
-Attribut an, dass der Parameterwert discontinuedOnly
in der Abfragezeichenfolge der Anforderungs-URL bereitgestellt wird:
[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;
}
Das [ApiController]
-Attribut wendet Rückschlussregeln auf die Standarddatenquellen von Aktionsparametern an. Da durch diese Regeln Attribute auf die Aktionsparameter angewendet werden, müssen Sie Bindungsquellen nicht manuell identifizieren. Die Rückschlussregeln für Bindungsquellen verhalten sich wie folgt:
[FromBody]
wird für komplexe Typparameter abgeleitet. Jeder komplexe integrierte Typ mit spezieller Bedeutung, z. B. IFormCollection und CancellationToken, stellt eine Ausnahme von der[FromBody]
-Rückschlussregel dar. Der Rückschlusscode der Bindungsquelle ignoriert diese Typen.[FromForm]
wird für Aktionsparameter des Typs IFormFile und IFormFileCollection abgeleitet. Es wird für keine einfachen oder benutzerdefinierte Typen abgeleitet.[FromRoute]
wird für jeden Namen von Aktionsparametern abgeleitet, der mit einem Parameter in der Routenvorlage übereinstimmt. Wenn mehr als eine Route mit einem Aktionsparameter übereinstimmt, gilt jeder Routenwert als[FromRoute]
.[FromQuery]
wird für alle anderen Aktionsparameter abgeleitet.
Hinweise zum FromBody-Rückschluss
[FromBody]
wird für einfache Typen wie string
oder int
nicht abgeleitet. Deshalb sollte das [FromBody]
-Attribut für einfache Typen verwendet werden, wenn diese Funktionsweise benötigt wird.
Wenn an eine Aktion mehr als ein Parameter aus dem Anforderungstext gebunden ist, wird eine Ausnahme ausgelöst. Beispielsweise lösen alle Signaturen der folgenden Aktionsmethoden eine Ausnahme aus:
[FromBody]
wird für beide abgeleitet, da sie komplexe Typen darstellen.[HttpPost] public IActionResult Action1(Product product, Order order)
Das
[FromBody]
-Attribut für einen Typ wird für den anderen abgeleitet, da es sich um einen komplexen Typ handelt.[HttpPost] public IActionResult Action2(Product product, [FromBody] Order order)
Das
[FromBody]
-Attribut für beide.[HttpPost] public IActionResult Action3([FromBody] Product product, [FromBody] Order order)
Hinweis
In ASP.NET Core 2.1 werden Sammlungstypparameter wie Listen und Arrays fälschlicherweise als [FromQuery]
abgeleitet. Für diese Parameter sollte das [FromBody]
-Attribut verwendet werden, wenn sie aus dem Anforderungstext gebunden werden sollen. Dieses Verhalten wurde bei ASP.NET Core 2.2 oder höher behoben. Hier werden Sammlungstypparameter standardmäßig als „[FromBody]“ abgeleitet.
Deaktivieren von Rückschlussregeln
Legen Sie SuppressInferBindingSourcesForParameters auf true
fest, um den Rückschluss auf Bindungsquellen zu deaktivieren. Fügen Sie den folgenden Code zu Startup.ConfigureServices
hinzu:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Ableiten der Multipart/form-data-Anforderung
Das [ApiController]
-Attribut wendet eine Rückschlussregel für Aktionsparameter des Typs IFormFile und IFormFileCollection an. Der multipart/form-data
-Anforderungsinhaltstyp wird für diese Typen abgeleitet.
Legen Sie die SuppressConsumesConstraintForFormFileParameters-Eigenschaft auf true
in Startup.ConfigureServices
fest, um das Standardverhalten zu deaktivieren.
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
});
Problemdetails für Fehlerstatuscodes
Bei Kompatibilitätsversion 2.2 oder höher wandelt MVC ein Fehlerergebnis (ein Ergebnis mit dem Statuscode 400 oder höher) in ein Ergebnis mit ProblemDetails um. Die ProblemDetails
-Typ basiert auf der RFC 7807-Spezifikation für die Bereitstellung maschinenlesbarer Fehlerdetails in einer HTTP-Antwort.
Betrachten Sie den folgenden Code in einer Controlleraktion:
if (pet == null)
{
return NotFound();
}
Die NotFound
-Methode erzeugt einen HTTP-404-Statuscode mit einem ProblemDetails
-Text. Zum Beispiel:
{
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
}
Deaktivieren der ProblemDetails-Antwort
Die automatische Erstellung einer ProblemDetails
-Antwort für Fehlerstatuscodes ist deaktiviert, wenn die SuppressMapClientErrors-Eigenschaft auf true
festgelegt ist. Fügen Sie den folgenden Code zu Startup.ConfigureServices
hinzu:
Definieren unterstützter Anforderungsinhaltstypen mit dem [Consumes]-Attribut
Standardmäßig unterstützt eine Aktion alle verfügbaren Anforderungsinhaltstypen. Wenn eine App beispielsweise zur Unterstützung von JSON- und XML-Eingabeformatierern konfiguriert ist, unterstützt eine Aktion mehrere Inhaltstypen, wie etwa application/json
und application/xml
.
Das [Consumes]-Attribut ermöglicht es einer Aktion, die unterstützten Anforderungsinhaltstypen einzuschränken. Wenden Sie das [Consumes]
-Attribut auf eine Aktion oder einen Controller an, und geben Sie mindestens einen Inhaltstyp an:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
Im obigen Code gibt die CreateProduct
-Aktion den Inhaltstyp application/xml
an. Anforderungen, die an diese Aktion weitergeleitet werden, müssen den Content-Type
-Header application/xml
angeben. Für Anforderungen, die den Content-Type
-Header application/xml
nicht angeben, wird die Antwort 415 – Nicht unterstützter Medientyp zurückgegeben.
Das [Consumes]
-Attribut ermöglicht es einer Aktion auch, eine Typeinschränkung anzuwenden, um die Auswahl basierend auf dem Inhaltstyp einer eingehenden Anforderung zu beeinflussen. Betrachten Sie das folgende Beispiel:
[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 });
}
Im obigen Code ist ConsumesController
zur Verarbeitung von Anforderungen konfiguriert, die an die URL https://localhost:5001/api/Consumes
gesendet werden. Beide Controlleraktionen – PostJson
und PostForm
– verarbeiten POST-Anforderungen mit derselben URL. Wenn das [Consumes]
-Attribut keine Typeinschränkung anwendet, wird eine Ausnahme in Bezug auf eine mehrdeutige Übereinstimmung ausgelöst.
Das [Consumes]
-Attribut wird auf beide Aktionen angewendet. Die PostJson
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/json
gesendet werden. Die PostForm
-Aktion verarbeitet Anforderungen, die mit dem Content-Type
-Header application/x-www-form-urlencoded
gesendet werden.
Zusätzliche Ressourcen
- Rückgabetypen von Controlleraktion in ASP.NET Core-Web-API
- Behandeln von Fehlern in ASP.NET Core-controllerbasierten Web-APIs
- Benutzerdefinierte Formatierer in Web-APIs in ASP.NET Core
- Formatieren von Antwortdaten in Web-APIs in ASP.NET Core
- ASP.NET Core-Web-API-Dokumentation mit Swagger/OpenAPI
- Routing zu Controlleraktionen in ASP.NET Core
- Erstellen einer Web-API mit ASP.NET Core
ASP.NET Core