Udostępnij za pośrednictwem


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:

  1. Wcześniej określony BindingInfo.BindingSource element nigdy nie został zastąpiony.
  2. Przypisano BindingSource.Servicesparametr typu złożonego zarejestrowanego w kontenerze DI .
  3. Przypisano BindingSource.Bodyparametr typu złożonego, który nie został zarejestrowany w kontenerze DI.
  4. Parametr o nazwie, która jest wyświetlana jako wartość trasy w dowolnym szablonie trasy, jest przypisany BindingSource.Path.
  5. 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.

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