Akcje kontrolera interfejsu API próbują wywnioskować parametry z di
Mechanizm wnioskowania źródeł powiązań parametrów akcji kontrolera interfejsu API oznacza teraz parametry, które mają być powiązane z kontenera wstrzykiwania zależności (DI), gdy typ jest zarejestrowany w kontenerze. W rzadkich przypadkach może to uszkodzić aplikacje, które mają typ di, który jest również akceptowany w metodach akcji kontrolera interfejsu API.
Wprowadzona wersja
ASP.NET Core 7.0
Poprzednie zachowanie
Jeśli chcesz powiązać typ zarejestrowany w kontenerze DI, musi zostać jawnie ozdobiony za pomocą atrybutu implementujący IFromServiceMetadataelement , taki jak FromServicesAttribute:
Services.AddScoped<SomeCustomType>();
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public ActionResult Get([FromServices]SomeCustomType service) => Ok();
}
Jeśli atrybut nie został określony, parametr został rozpoznany z treści żądania wysłanej przez klienta:
Services.AddScoped<SomeCustomType>();
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
// Bind from the request body
[HttpPost]
public ActionResult Post(SomeCustomType service) => Ok();
}
Nowe zachowanie
Typy w di są sprawdzane podczas uruchamiania aplikacji przy użyciu, IServiceProviderIsService aby określić, czy argument w akcji kontrolera interfejsu API pochodzi z di lub z innych źródeł.
W poniższym przykładzie założono, że używasz domyślnego kontenera DI, SomeCustomType
pochodzi z kontenera DI:
Services.AddScoped<SomeCustomType>();
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
// Bind from DI
[HttpPost]
public ActionResult Post(SomeCustomType service) => Ok();
}
Mechanizm wnioskowania źródeł powiązań parametrów akcji kontrolera interfejsu API jest zgodny z następującymi regułami:
- Wcześniej określony BindingInfo.BindingSource element nigdy nie został zastąpiony.
- Przypisano BindingSource.Servicesparametr typu złożonego zarejestrowanego w kontenerze DI .
- Przypisano BindingSource.Bodyparametr typu złożonego, który nie został zarejestrowany w kontenerze DI.
- Parametr o nazwie, która jest wyświetlana jako wartość trasy w dowolnym szablonie trasy, jest przypisany BindingSource.Path.
- Wszystkie inne parametry są przypisane BindingSource.Query.
Typ zmiany powodującej niezgodność
Ta zmiana ma wpływ na zgodność ze źródłem.
Przyczyna wprowadzenia zmiany
To samo zachowanie jest już zaimplementowane w minimalnych interfejsach API.
Prawdopodobieństwo przerwania działania aplikacji jest niskie, ponieważ nie jest powszechne posiadanie typu di i jako argument w akcji kontrolera interfejsu API w tym samym czasie.
Zalecana akcja
Jeśli ta zmiana zostanie przerwana, możesz wyłączyć tę funkcję, ustawiając wartość DisableImplicitFromServicesParameters
true:
Services.Configure<ApiBehaviorOptions>(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
Jeśli zmiana została przerwana, ale chcesz powiązać z di dla określonych parametrów akcji kontrolera interfejsu API, możesz wyłączyć tę funkcję, jak pokazano powyżej, i użyć atrybutu, który implementuje IFromServiceMetadataelement , taki jak FromServicesAttribute:
Services.AddScoped<SomeCustomType>();
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
// Bind from DI
[HttpPost]
public ActionResult Post([FromServices]SomeCustomType service) => Ok();
}
Dotyczy interfejsów API
Akcje kontrolera interfejsu API