ASP.NET Core web API'sinde denetleyici eylemi dönüş türleri

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Örnek kodu görüntüleme veya indirme (indirme)

ASP.NET Core, web API denetleyicisi eylem dönüş türleri için aşağıdaki seçenekleri sağlar:

Bu makalede, her dönüş türünü kullanmanın en uygun olduğu zamanlar açıklanmaktadır.

Belirli tür

En temel eylem, örneğin string ilkel veya karmaşık bir veri türü ya da özel bir nesne döndürür. Özel Product nesne koleksiyonunu döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet]
public Task<List<Product>> Get() =>
    _productContext.Products.OrderBy(p => p.Name).ToListAsync();

Korunacak bilinen koşullar olmadan, belirli bir türü döndürmek yeterli olabilir. Yukarıdaki eylem parametre kabul etmediğinden parametre kısıtlamaları doğrulaması gerekmez.

Birden çok dönüş türü mümkün olduğunda, bir dönüş türünü ilkel veya karmaşık dönüş türüyle karıştırmak ActionResult yaygındır. Bu eylem türünü barındırmak için IActionResult veya ActionResult<T> gereklidir. Bu makalede birden çok dönüş türüne ait çeşitli örnekler sağlanmıştır.

IEnumerable<T> veya IAsyncEnumerable<T döndürme>

Performansla ilgili dikkat edilmesi gerekenler için bkz . Dönüş IEnumerable<T> veya IAsyncEnumerable<T> .

ASP.NET Core, yanıta yazmadan önce döndürülen IEnumerable<T> eylemlerin sonucunu arabelleğe alır. Zaman uyumsuz yinelemeyi garanti etmek için eylem imzasının dönüş türünü olarak IAsyncEnumerable<T> bildirmeyi göz önünde bulundurun. Sonuç olarak, yineleme modu döndürülen temel somut türü temel alır ve seçilen biçimlendirici sonucun nasıl işlendiğini etkiler:

  • Biçimlendirici kullanılırken System.Text.Json MVC, sonucu akışa almak için eklenen desteğe System.Text.Jsondayanır.
  • Biçimlendiricilerle veya XML-based kullanırken Newtonsoft.Json sonuç arabelleğe alınıyor.

Satış fiyatına sahip ürün kayıtlarını olarak IEnumerable<Product>döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
    var products = _productContext.Products.OrderBy(p => p.Name).ToList();

    foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Yukarıdaki IAsyncEnumerable<Product> eylemin eşdeğeri:

[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
    var products = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();

    await foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

IActionResult türü

Bir IActionResult eylemde birden çok ActionResult dönüş türü mümkün olduğunda dönüş türü uygundur. Türler ActionResult çeşitli HTTP durum kodlarını temsil ediyor. öğesinden ActionResult türetilen soyut olmayan tüm sınıflar geçerli bir dönüş türü olarak niteler. Bu kategorideki bazı yaygın dönüş türleri şunlardır BadRequestResult : (400), NotFoundResult (404) ve OkObjectResult (200). Alternatif olarak, bir eylemden türleri döndürmek ActionResult için sınıftaki ControllerBase kolaylık yöntemleri kullanılabilir. Örneğin, return BadRequest(); kısaltma biçimidir return new BadRequestResult();.

Bu tür eylemlerde birden çok dönüş türü ve yolu olduğundan, özniteliğin [ProducesResponseType] liberal kullanımı gereklidir. Bu öznitelik, Swagger gibi araçlar tarafından oluşturulan web API'si yardım sayfaları için daha açıklayıcı yanıt ayrıntıları oluşturur. [ProducesResponseType] , eylem tarafından döndürülecek bilinen türleri ve HTTP durum kodlarını gösterir.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumlu eylemi göz önünde bulundurun:

[HttpGet("{id}")]
[ProducesResponseType<Product>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById_IActionResult(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? NotFound() : Ok(product);
}

Önceki eylemde:

  • tarafından temsil edilen id ürün temel alınan veri deposunda mevcut olmadığında 404 durum kodu döndürülür. kolaylık NotFound yöntemi için return new NotFoundResult();kısaltma olarak çağrılır.
  • Ürün mevcut olduğunda nesnesiyle birlikte Product 200 durum kodu döndürülür. kolaylık Ok yöntemi için return new OkObjectResult(product);kısaltma olarak çağrılır.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumsuz eylemi göz önünde bulundurun:

[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync_IActionResult(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    return CreatedAtAction(nameof(CreateAsync_IActionResult), new { id = product.Id }, product);
}

Önceki eylemde:

  • Ürün açıklamasında "XYZ Pencere Öğesi" bulunduğunda 400 durum kodu döndürülür. kolaylık BadRequest yöntemi için return new BadRequestResult();kısaltma olarak çağrılır.

  • Bir ürün oluşturulduğunda kolaylık yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Aşağıdaki kod çağrısı CreatedAtActionyapmak için bir alternatiftir:

    return new CreatedAtActionResult(nameof(CreateAsync), 
                                    "Products", 
                                    new { id = product.Id }, 
                                    product);
    

    Yukarıdaki kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Örneğin, aşağıdaki model isteklerin ve Description özelliklerini içermesi Name gerektiğini gösterir. İstekte ve Description sağlanamaması Name model doğrulamasının başarısız olmasına neden olur.

public class Product
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; } = string.Empty;

    [Required]
    public string Description { get; set; } = string.Empty;

    public bool IsOnSale { get; set; }
}

[ApiController] Öznitelik uygulanırsa model doğrulama hataları 400 durum koduyla sonuçlanır. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

ActionResult vs IActionResult

Aşağıdaki bölüm ile karşılaştırır ActionResultIActionResult

ActionResult<T> türü

ASP.NET Core, web API denetleyicisi eylemleri için ActionResult<T> dönüş türünü içerir. Belirli bir türden türetilen ActionResult veya döndüren bir türü döndürmeyi etkinleştirir. ActionResult<T>IActionResult türüne göre aşağıdaki avantajları sunar:

  • Özniteliğin [ProducesResponseType]Type özelliği dışlanabilir. Örneğin, [ProducesResponseType(200, Type = typeof(Product))] olarak basitleştirilmiştir [ProducesResponseType(200)]. Eylemin beklenen dönüş türü dosyasından TActionResult<T>çıkarılır.
  • Örtük atama işleçleri hem hem ActionResult de T dönüştürmesini ActionResult<T>destekler. TObjectResult, olarak dönüştürülür; bu da basitleştirilmiş return T;olduğu anlamına gelirreturn new ObjectResult(T);.

C# arabirimlerde örtük atama işleçlerini desteklemez. Sonuç olarak, kullanmak ActionResult<T>için arabirimin somut bir türe dönüştürülmesi gerekir. Örneğin, aşağıdaki örnekte öğesinin IEnumerable kullanımı çalışmıyor:

[HttpGet]
public ActionResult<IEnumerable<Product>> Get() =>
    _repository.GetProducts();

Önceki kodu düzeltmek için bir seçenek döndürmektir _repository.GetProducts().ToList();.

Çoğu eylemin belirli bir dönüş türü vardır. Eylem yürütme sırasında beklenmeyen koşullar oluşabilir ve bu durumda belirli bir tür döndürülemez. Örneğin, bir eylemin giriş parametresi model doğrulamasında başarısız olabilir. Böyle bir durumda, belirli bir tür yerine uygun ActionResult türü döndürmek yaygın bir durum olur.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu zaman uyumlu bir eylem düşünün:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById_ActionResultOfT(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? NotFound() : product;
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte 200 durum kodu döndürülür.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu zaman uyumsuz bir eylem düşünün:

[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync_ActionResultOfT(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    return CreatedAtAction(nameof(CreateAsync_ActionResultOfT), new { id = product.Id }, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda ASP.NET Core çalışma zamanı tarafından 400 durum kodu (BadRequest) döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oluyor.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

HttpResults türü

MVC'ye özgü yerleşik sonuç türlerine (IActionResult ve ActionResult<T>) ek olarak, ASP.NET Core hem En Az API'lerde hem de Web API'sinde kullanılabilen HttpResults türlerini içerir.

MVC'ye özgü sonuç türlerinden farklı olarak HttpResults, :

  • IResult.ExecuteAsync çağrısı tarafından işlenen bir sonuç uygulamasıdır.

  • Yapılandırılan Biçimlendiriciler'i kullanmaz. Yapılandırılan biçimlendiricilerden yararlanılmaması şu anlama gelir:

    • gibi Content negotiation bazı özellikler kullanılamaz.
    • Üretilen Content-Type , uygulama tarafından HttpResults belirlenir.

, HttpResults Minimum API'ler ve Web API'leri arasında kod paylaşırken yararlı olabilir.

IResult türü

Ad Microsoft.AspNetCore.Http.HttpResults alanı arabirimini IResult uygulayan sınıfları içerir. Arabirimi, IResult HTTP uç noktasının sonucunu temsil eden bir sözleşme tanımlar. Statik Results sınıfı, farklı yanıt türlerini temsil eden farklı IResult nesneler oluşturmak için kullanılır.

Yerleşik sonuçlar tablosu, ortak sonuç yardımcılarını gösterir.

Aşağıdaki kodu inceleyin:

[HttpGet("{id}")]
[ProducesResponseType<Product>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IResult GetById(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? Results.NotFound() : Results.Ok(product);
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte results.Ok<T>() tarafından oluşturulan 200 durum kodu döndürülür.

Aşağıdaki kodu inceleyin:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType<Product>(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IResult> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return Results.BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    var location = Url.Action(nameof(CreateAsync), new { id = product.Id }) ?? $"/{product.Id}";
    return Results.Created(location, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda 400 durum kodu döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oluyor.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından Results.Create 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Sonuçlar<TResult1, TResultN> türü

Statik TypedResults sınıfı, dönüş türü olarak kullanılmasına IResult izin veren somut IResult uygulamayı döndürür. Somut IResult uygulamanın kullanımı IResult türüne göre aşağıdaki avantajı sunar:

  • [ProducesResponseType] Uygulama, uç nokta meta verilerine otomatik olarak katkıda bulunacağı HttpResult için tüm öznitelikler dışlanabilir.

Birden çok IResult dönüş türü gerektiğinde, döndürülmesi yerine döndürülmesi Results<TResult1, TResultN>IResulttercih edilir. Genel birleşim türleri uç nokta meta verilerini otomatik olarak koruduğundan, döndürme Results<TResult1, TResultN> tercih edilir.

Birleşim Results<TResult1, TResultN> türleri, derleyicinin genel bağımsız değişkenlerde belirtilen türleri otomatik olarak birleşim türünün bir örneğine dönüştürebilmesi için örtük atama işleçleri uygular. Bu, bir yol işleyicisinin aslında yalnızca bildirdiği sonuçları döndürdüğüne ilişkin derleme zamanı denetimi sağlamanın ek avantajına sahiptir. Derleme hatasıyla sonuçlanması için genel bağımsız değişkenlerden biri olarak bildirlenmemiş bir tür döndürülmeye Results<> çalışılıyor.

Aşağıdaki kodu inceleyin:

[HttpGet("{id}")]
public Results<NotFound, Ok<Product>> GetById(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? TypedResults.NotFound() : TypedResults.Ok(product);
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte 200 durum kodu döndürülür ve TypedResults.Ok<T> tarafından oluşturulur.
[HttpPost]
public async Task<Results<BadRequest, Created<Product>>> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return TypedResults.BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    var location = Url.Action(nameof(CreateAsync), new { id = product.Id }) ?? $"/{product.Id}";
    return TypedResults.Created(location, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda 400 durum kodu döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oldu.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından TypedResults.Created 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Ek kaynaklar

Örnek kodu görüntüleme veya indirme (indirme)

ASP.NET Core, web API denetleyicisi eylem dönüş türleri için aşağıdaki seçenekleri sağlar:

Bu makalede, her dönüş türünü kullanmanın en uygun olduğu zamanlar açıklanmaktadır.

Belirli tür

En temel eylem, örneğin string ilkel veya karmaşık bir veri türü ya da özel bir nesne döndürür. Özel Product nesne koleksiyonunu döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet]
public Task<List<Product>> Get() =>
    _productContext.Products.OrderBy(p => p.Name).ToListAsync();

Korunacak bilinen koşullar olmadan, belirli bir türü döndürmek yeterli olabilir. Yukarıdaki eylem parametre kabul etmediğinden parametre kısıtlamaları doğrulaması gerekmez.

Birden çok dönüş türü mümkün olduğunda, bir dönüş türünü ilkel veya karmaşık dönüş türüyle karıştırmak ActionResult yaygındır. Bu eylem türünü barındırmak için IActionResult veya ActionResult<T> gereklidir. Bu makalede birden çok dönüş türüne ait çeşitli örnekler sağlanmıştır.

IEnumerable<T> veya IAsyncEnumerable<T döndürme>

Performansla ilgili dikkat edilmesi gerekenler için bkz . Dönüş IEnumerable<T> veya IAsyncEnumerable<T> .

ASP.NET Core, yanıta yazmadan önce döndürülen IEnumerable<T> eylemlerin sonucunu arabelleğe alır. Zaman uyumsuz yinelemeyi garanti etmek için eylem imzasının dönüş türünü olarak IAsyncEnumerable<T> bildirmeyi göz önünde bulundurun. Sonuç olarak, yineleme modu döndürülen temel somut türü temel alır ve seçilen biçimlendirici sonucun nasıl işlendiğini etkiler:

  • Biçimlendirici kullanılırken System.Text.Json MVC, sonucu akışa almak için eklenen desteğe System.Text.Jsondayanır.
  • Biçimlendiricilerle veya XML-based kullanırken Newtonsoft.Json sonuç arabelleğe alınıyor.

Satış fiyatına sahip ürün kayıtlarını olarak IEnumerable<Product>döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
    var products = _productContext.Products.OrderBy(p => p.Name).ToList();

    foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Yukarıdaki IAsyncEnumerable<Product> eylemin eşdeğeri:

[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
    var products = _productContext.Products.OrderBy(p => p.Name).AsAsyncEnumerable();

    await foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

IActionResult türü

Bir IActionResult eylemde birden çok ActionResult dönüş türü mümkün olduğunda dönüş türü uygundur. Türler ActionResult çeşitli HTTP durum kodlarını temsil ediyor. öğesinden ActionResult türetilen soyut olmayan tüm sınıflar geçerli bir dönüş türü olarak niteler. Bu kategorideki bazı yaygın dönüş türleri şunlardır BadRequestResult : (400), NotFoundResult (404) ve OkObjectResult (200). Alternatif olarak, bir eylemden türleri döndürmek ActionResult için sınıftaki ControllerBase kolaylık yöntemleri kullanılabilir. Örneğin, return BadRequest(); kısaltma biçimidir return new BadRequestResult();.

Bu tür eylemlerde birden çok dönüş türü ve yolu olduğundan, özniteliğin [ProducesResponseType] liberal kullanımı gereklidir. Bu öznitelik, Swagger gibi araçlar tarafından oluşturulan web API'si yardım sayfaları için daha açıklayıcı yanıt ayrıntıları oluşturur. [ProducesResponseType] , eylem tarafından döndürülecek bilinen türleri ve HTTP durum kodlarını gösterir.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumlu eylemi göz önünde bulundurun:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById_IActionResult(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? NotFound() : Ok(product);
}

Önceki eylemde:

  • tarafından temsil edilen id ürün temel alınan veri deposunda mevcut olmadığında 404 durum kodu döndürülür. kolaylık NotFound yöntemi için return new NotFoundResult();kısaltma olarak çağrılır.
  • Ürün mevcut olduğunda nesnesiyle birlikte Product 200 durum kodu döndürülür. kolaylık Ok yöntemi için return new OkObjectResult(product);kısaltma olarak çağrılır.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumsuz eylemi göz önünde bulundurun:

[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync_IActionResult(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    return CreatedAtAction(nameof(GetById_IActionResult), new { id = product.Id }, product);
}

Önceki eylemde:

  • Ürün açıklamasında "XYZ Pencere Öğesi" bulunduğunda 400 durum kodu döndürülür. kolaylık BadRequest yöntemi için return new BadRequestResult();kısaltma olarak çağrılır.

  • Bir ürün oluşturulduğunda kolaylık yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Aşağıdaki kod çağrısı CreatedAtActionyapmak için bir alternatiftir:

    return new CreatedAtActionResult(nameof(GetById), 
                                    "Products", 
                                    new { id = product.Id }, 
                                    product);
    

    Yukarıdaki kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Örneğin, aşağıdaki model isteklerin ve Description özelliklerini içermesi Name gerektiğini gösterir. İstekte ve Description sağlanamaması Name model doğrulamasının başarısız olmasına neden olur.

public class Product
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; } = string.Empty;

    [Required]
    public string Description { get; set; } = string.Empty;

    public bool IsOnSale { get; set; }
}

[ApiController] Öznitelik uygulanırsa model doğrulama hataları 400 durum koduyla sonuçlanır. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

ActionResult vs IActionResult

Aşağıdaki bölüm ile karşılaştırır ActionResultIActionResult

ActionResult<T> türü

ASP.NET Core, web API denetleyicisi eylemleri için ActionResult<T> dönüş türünü içerir. Belirli bir türden türetilen ActionResult veya döndüren bir türü döndürmeyi etkinleştirir. ActionResult<T>IActionResult türüne göre aşağıdaki avantajları sunar:

  • Özniteliğin [ProducesResponseType]Type özelliği dışlanabilir. Örneğin, [ProducesResponseType(200, Type = typeof(Product))] olarak basitleştirilmiştir [ProducesResponseType(200)]. Eylemin beklenen dönüş türü dosyasından TActionResult<T>çıkarılır.
  • Örtük atama işleçleri hem hem ActionResult de T dönüştürmesini ActionResult<T>destekler. TObjectResult, olarak dönüştürülür; bu da basitleştirilmiş return T;olduğu anlamına gelirreturn new ObjectResult(T);.

C# arabirimlerde örtük atama işleçlerini desteklemez. Sonuç olarak, kullanmak ActionResult<T>için arabirimin somut bir türe dönüştürülmesi gerekir. Örneğin, aşağıdaki örnekte öğesinin IEnumerable kullanımı çalışmıyor:

[HttpGet]
public ActionResult<IEnumerable<Product>> Get() =>
    _repository.GetProducts();

Önceki kodu düzeltmek için bir seçenek döndürmektir _repository.GetProducts().ToList();.

Çoğu eylemin belirli bir dönüş türü vardır. Eylem yürütme sırasında beklenmeyen koşullar oluşabilir ve bu durumda belirli bir tür döndürülemez. Örneğin, bir eylemin giriş parametresi model doğrulamasında başarısız olabilir. Böyle bir durumda, belirli bir tür yerine uygun ActionResult türü döndürmek yaygın bir durum olur.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu zaman uyumlu bir eylem düşünün:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById_ActionResultOfT(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? NotFound() : product;
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte 200 durum kodu döndürülür.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu zaman uyumsuz bir eylem düşünün:

[HttpPost()]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync_ActionResultOfT(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    return CreatedAtAction(nameof(GetById_ActionResultOfT), new { id = product.Id }, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda ASP.NET Core çalışma zamanı tarafından 400 durum kodu (BadRequest) döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oluyor.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

HttpResults türü

MVC'ye özgü yerleşik sonuç türlerine (IActionResult ve ActionResult<T>) ek olarak, ASP.NET Core hem En Az API'lerde hem de Web API'sinde kullanılabilen HttpResults türlerini içerir.

MVC'ye özgü sonuç türlerinden farklı olarak HttpResults, :

  • IResult.ExecuteAsync çağrısı tarafından işlenen bir sonuç uygulamasıdır.

  • Yapılandırılan Biçimlendiriciler'i kullanmaz. Yapılandırılan biçimlendiricilerden yararlanılmaması şu anlama gelir:

    • gibi Content negotiation bazı özellikler kullanılamaz.
    • Üretilen Content-Type , uygulama tarafından HttpResults belirlenir.

, HttpResults Minimum API'ler ve Web API'leri arasında kod paylaşırken yararlı olabilir.

IResult türü

Ad Microsoft.AspNetCore.Http.HttpResults alanı arabirimini IResult uygulayan sınıfları içerir. Arabirimi, IResult HTTP uç noktasının sonucunu temsil eden bir sözleşme tanımlar. Statik Results sınıfı, farklı yanıt türlerini temsil eden farklı IResult nesneler oluşturmak için kullanılır.

Yerleşik sonuçlar tablosu, ortak sonuç yardımcılarını gösterir.

Aşağıdaki kodu inceleyin:

[HttpGet("{id}")]
[ProducesResponseType(typeof(Product), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IResult GetById(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? Results.NotFound() : Results.Ok(product);
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte results.Ok<T>() tarafından oluşturulan 200 durum kodu döndürülür.

Aşağıdaki kodu inceleyin:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(Product), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IResult> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return Results.BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    var location = Url.Action(nameof(GetById), new { id = product.Id }) ?? $"/{product.Id}";
    return Results.Created(location, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda 400 durum kodu döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oluyor.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından Results.Create 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Sonuçlar<TResult1, TResultN> türü

Statik TypedResults sınıfı, dönüş türü olarak kullanılmasına IResult izin veren somut IResult uygulamayı döndürür. Somut IResult uygulamanın kullanımı IResult türüne göre aşağıdaki avantajı sunar:

  • [ProducesResponseType] Uygulama, uç nokta meta verilerine otomatik olarak katkıda bulunacağı HttpResult için tüm öznitelikler dışlanabilir.

Birden çok IResult dönüş türü gerektiğinde, döndürülmesi yerine döndürülmesi Results<TResult1, TResultN>IResulttercih edilir. Genel birleşim türleri uç nokta meta verilerini otomatik olarak koruduğundan, döndürme Results<TResult1, TResultN> tercih edilir.

Birleşim Results<TResult1, TResultN> türleri, derleyicinin genel bağımsız değişkenlerde belirtilen türleri otomatik olarak birleşim türünün bir örneğine dönüştürebilmesi için örtük atama işleçleri uygular. Bu, bir yol işleyicisinin aslında yalnızca bildirdiği sonuçları döndürdüğüne ilişkin derleme zamanı denetimi sağlamanın ek avantajına sahiptir. Derleme hatasıyla sonuçlanması için genel bağımsız değişkenlerden biri olarak bildirlenmemiş bir tür döndürülmeye Results<> çalışılıyor.

Aşağıdaki kodu inceleyin:

[HttpGet("{id}")]
public Results<NotFound, Ok<Product>> GetById(int id)
{
    var product = _productContext.Products.Find(id);
    return product == null ? TypedResults.NotFound() : TypedResults.Ok(product);
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte 200 durum kodu döndürülür ve TypedResults.Ok<T> tarafından oluşturulur.
[HttpPost]
public async Task<Results<BadRequest, Created<Product>>> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return TypedResults.BadRequest();
    }

    _productContext.Products.Add(product);
    await _productContext.SaveChangesAsync();

    var location = Url.Action(nameof(GetById), new { id = product.Id }) ?? $"/{product.Id}";
    return TypedResults.Created(location, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda 400 durum kodu döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oldu.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından TypedResults.Create 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Ek kaynaklar

Örnek kodu görüntüleme veya indirme (indirme)

ASP.NET Core, web API denetleyicisi eylem dönüş türleri için aşağıdaki seçenekleri sunar:

Bu belge, her dönüş türünü kullanmanın en uygun olduğu zamanı açıklar.

Belirli tür

En basit eylem, ilkel veya karmaşık bir veri türü (örneğin, string veya özel bir nesne türü) döndürür. Özel Product nesne koleksiyonunu döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet]
public List<Product> Get() =>
    _repository.GetProducts();

Eylem yürütme sırasında korunacak bilinen koşullar olmadan, belirli bir türü döndürmek yeterli olabilir. Yukarıdaki eylem parametre kabul etmediğinden parametre kısıtlamaları doğrulaması gerekmez.

Birden çok dönüş türü mümkün olduğunda, bir dönüş türünü ilkel veya karmaşık dönüş türüyle karıştırmak ActionResult yaygındır. Bu eylem türünü barındırmak için IActionResult veya ActionResult<T> gereklidir. Bu belgede birden çok dönüş türüne ait çeşitli örnekler sağlanmıştır.

IEnumerable<T> veya IAsyncEnumerable<T döndürme>

ASP.NET Core, yanıta yazmadan önce döndürülen IEnumerable<T> eylemlerin sonucunu arabelleğe alır. Zaman uyumsuz yinelemeyi garanti etmek için eylem imzasının dönüş türünü olarak IAsyncEnumerable<T> bildirmeyi göz önünde bulundurun. Sonuçta yineleme modu, döndürülen temel beton türü temel alır. MVC, uygulayan tüm somut türleri otomatik olarak arabelleğe alır IAsyncEnumerable<T>.

Satış fiyatına sahip ürün kayıtlarını olarak IEnumerable<Product>döndüren aşağıdaki eylemi göz önünde bulundurun:

[HttpGet("syncsale")]
public IEnumerable<Product> GetOnSaleProducts()
{
    var products = _repository.GetProducts();

    foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

Yukarıdaki IAsyncEnumerable<Product> eylemin eşdeğeri:

[HttpGet("asyncsale")]
public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
{
    var products = _repository.GetProductsAsync();

    await foreach (var product in products)
    {
        if (product.IsOnSale)
        {
            yield return product;
        }
    }
}

IActionResult türü

Bir IActionResult eylemde birden çok ActionResult dönüş türü mümkün olduğunda dönüş türü uygundur. Türler ActionResult çeşitli HTTP durum kodlarını temsil ediyor. öğesinden ActionResult türetilen soyut olmayan tüm sınıflar geçerli bir dönüş türü olarak niteler. Bu kategorideki bazı yaygın dönüş türleri şunlardır BadRequestResult : (400), NotFoundResult (404) ve OkObjectResult (200). Alternatif olarak, bir eylemden türleri döndürmek ActionResult için sınıftaki ControllerBase kolaylık yöntemleri kullanılabilir. Örneğin, return BadRequest(); kısaltma biçimidir return new BadRequestResult();.

Bu tür eylemlerde birden çok dönüş türü ve yolu olduğundan, özniteliğin [ProducesResponseType] liberal kullanımı gereklidir. Bu öznitelik, Swagger gibi araçlar tarafından oluşturulan web API'si yardım sayfaları için daha açıklayıcı yanıt ayrıntıları oluşturur. [ProducesResponseType] , eylem tarafından döndürülecek bilinen türleri ve HTTP durum kodlarını gösterir.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumlu eylemi göz önünde bulundurun:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return Ok(product);
}

Önceki eylemde:

  • tarafından temsil edilen id ürün temel alınan veri deposunda mevcut olmadığında 404 durum kodu döndürülür. kolaylık NotFound yöntemi için return new NotFoundResult();kısaltma olarak çağrılır.
  • Ürün mevcut olduğunda nesnesiyle birlikte Product 200 durum kodu döndürülür. kolaylık Ok yöntemi için return new OkObjectResult(product);kısaltma olarak çağrılır.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu aşağıdaki zaman uyumsuz eylemi göz önünde bulundurun:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

    return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}

Önceki eylemde:

  • Ürün açıklamasında "XYZ Pencere Öğesi" bulunduğunda 400 durum kodu döndürülür. kolaylık BadRequest yöntemi için return new BadRequestResult();kısaltma olarak çağrılır.
  • Bir ürün oluşturulduğunda kolaylık yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Çağrısının CreatedAtAction alternatifi ise şeklindedir return new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product);. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Örneğin, aşağıdaki model isteklerin ve Description özelliklerini içermesi Name gerektiğini gösterir. İstekte ve Description sağlanamaması Name model doğrulamasının başarısız olmasına neden olur.

public class Product
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Description { get; set; }

    public bool IsOnSale { get; set; }
}

[ApiController] Öznitelik uygulanırsa model doğrulama hataları 400 durum koduyla sonuçlanır. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

ActionResult vs IActionResult

Aşağıdaki bölüm ile karşılaştırır ActionResultIActionResult

ActionResult<T> türü

ASP.NET Core, web API denetleyicisi eylemleri için ActionResult<T> dönüş türünü içerir. Belirli bir türden türetilen ActionResult veya döndüren bir tür döndürmenizi sağlar. ActionResult<T>IActionResult türüne göre aşağıdaki avantajları sunar:

  • Özniteliğin [ProducesResponseType]Type özelliği dışlanabilir. Örneğin, [ProducesResponseType(200, Type = typeof(Product))] olarak basitleştirilmiştir [ProducesResponseType(200)]. Eylemin beklenen dönüş türü bunun yerine dosyasından TActionResult<T>çıkarılır.
  • Örtük atama işleçleri hem hem ActionResult de T dönüştürmesini ActionResult<T>destekler. TObjectResult, olarak dönüştürülür; bu da basitleştirilmiş return T;olduğu anlamına gelirreturn new ObjectResult(T);.

C# arabirimlerde örtük atama işleçlerini desteklemez. Sonuç olarak, kullanmak ActionResult<T>için arabirimin somut bir türe dönüştürülmesi gerekir. Örneğin, aşağıdaki örnekte öğesinin IEnumerable kullanımı çalışmıyor:

[HttpGet]
public ActionResult<IEnumerable<Product>> Get() =>
    _repository.GetProducts();

Önceki kodu düzeltmek için bir seçenek döndürmektir _repository.GetProducts().ToList();.

Çoğu eylemin belirli bir dönüş türü vardır. Eylem yürütme sırasında beklenmeyen koşullar oluşabilir ve bu durumda belirli bir tür döndürülemez. Örneğin, bir eylemin giriş parametresi model doğrulamasında başarısız olabilir. Böyle bir durumda, belirli bir tür yerine uygun ActionResult türü döndürmek yaygın bir durum olur.

Zaman uyumlu eylem

İki olası dönüş türünün bulunduğu zaman uyumlu bir eylem düşünün:

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return product;
}

Önceki eylemde:

  • Ürün veritabanında mevcut olmadığında 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda ilgili Product nesneyle birlikte 200 durum kodu döndürülür.

Zaman uyumsuz eylem

İki olası dönüş türünün bulunduğu zaman uyumsuz bir eylem düşünün:

[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync(Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

    return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}

Önceki eylemde:

  • Aşağıdaki durumlarda ASP.NET Core çalışma zamanı tarafından 400 durum kodu (BadRequest) döndürülür:
    • [ApiController] Özniteliği uygulandı ve model doğrulaması başarısız oluyor.
    • Ürün açıklaması "XYZ Pencere Öğesi" içerir.
  • Bir ürün oluşturulduğunda yöntemi tarafından CreatedAtAction 201 durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Location Yeni oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Ek kaynaklar