Web API'sinde denetleyici eylemi ASP.NET Core türleri

Scott Addie tarafından

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

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

Bu belgede, her bir dönüş türünün ne zaman en uygun olduğu açık bir şekilde açık bir şekilde açık bir şekilde ekleyebilirsiniz.

Belirli tür

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

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

Eylem yürütme sırasında koruma sağlamak için bilinen koşullar olmadan, belirli bir türün geri alınması yeterli olabilir. Yukarıdaki eylem parametre kabul etmez, bu nedenle parametre kısıtlama doğrulaması gerekli değildir.

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

Dönüş IEnumerable <T> veya IAsyncEnumerable<T>

2 ASP.NET Core 2.2 ve önceki sürümlerinde, bir eylemden geri dönmek seri hale getirici tarafından zaman IEnumerable<T> uyumlu koleksiyon yinelemesine neden olur. Sonuç olarak çağrıların engellenmesi ve iş parçacığı havuzu açıkları olabilir. Web API'sinde Entity Framework erişim ihtiyaçları için Entity Framework (EF) Core'un kullan gerektiğini düşünün. Aşağıdaki eylemin dönüş türü, serileştirme sırasında zaman uyumlu olarak numaralandı:

public IEnumerable<Product> GetOnSaleProducts() =>
    _context.Products.Where(p => p.IsOnSale);

2.2 ve önceki sürümlerde veritabanında zaman uyumlu numaralama ve bekleme ASP.NET Core önlemek için ToListAsync çağırın:

public async Task<IEnumerable<Product>> GetOnSaleProducts() =>
    await _context.Products.Where(p => p.IsOnSale).ToListAsync();

3 ASP.NET Core 3.0 ve sonraki bir süre içinde bir IAsyncEnumerable<T> eylemden geri dönerek:

  • Artık zaman uyumlu yinelemeye neden olmaz.
  • döndüren kadar verimli hale IEnumerable<T> gelir.

ASP.NET Core 3.0 ve sonrası, seri hale getiriciye sağlamadan önce aşağıdaki eylemin sonucu arabelleğe asıtır:

public IEnumerable<Product> GetOnSaleProducts() =>
    _context.Products.Where(p => p.IsOnSale);

Zaman uyumsuz yinelemeyi garanti etmek için eylem imzasının dönüş türünü olarak IAsyncEnumerable<T> bildirebilirsiniz. Sonuç olarak yineleme modu, döndürülen temel alınan somut türü temel alır. MVC, uygulayan herhangi bir somut türü otomatik olarak arabelleğe IAsyncEnumerable<T> almaktadır.

Satış fiyatıyla fiyatlandırarak ürün kayıtlarını olarak döndüren aşağıdaki eylemi göz önünde IEnumerable<Product> bulundurabilirsiniz:

[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 şu şekildedir:

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

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

Yukarıdaki eylemlerin ikisi de 3.0'dan ASP.NET Core engellemez.

IActionResult türü

Bir IActionResult eylemde birden çok dönüş ActionResult türü mümkün olduğunda dönüş türü uygundur. Türler ActionResult çeşitli HTTP durum kodlarını temsil ediyor. 'den türetilmeyen herhangi bir soyut ActionResult sınıf, geçerli bir dönüş türü olarak niteler. Bu kategorideki bazı yaygın dönüş türleri BadRequestResult (400), NotFoundResult (404) ve OkObjectResult (200) türleridir. Alternatif olarak, sınıfındaki kolaylık ControllerBase yöntemleri bir eylemden ActionResult türler dönmek için kullanılabilir. Örneğin, return BadRequest(); bir kısa return new BadRequestResult(); biçimidir.

Bu tür bir eylemde birden çok dönüş türü ve yol olduğundan özniteliğinin bir kez [ProducesResponseType] daha kullanımı gerekir. Bu öznitelik, Swaggergibi 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ülen bilinen türleri ve HTTP durum kodlarını gösterir.

Zaman uyumlu eylem

İki olası dönüş türü olduğu aşağıdaki zaman uyumlu eylemi düşünün:

[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);
}
[HttpGet("{id}")]
[ProducesResponseType(typeof(Product), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return Ok(product);
}

Yukarıdaki eylemde:

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

Zaman uyumsuz eylem

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

[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);
}
[HttpPost]
[Consumes("application/json")]
[ProducesResponseType(typeof(Product), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateAsync([FromBody] Product product)
{
    if (product.Description.Contains("XYZ Widget"))
    {
        return BadRequest();
    }

    await _repository.AddProductAsync(product);

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

Yukarıdaki eylemde:

  • Ürün açıklaması "XYZ Pencere Öğesi" içerdiğinde 400 durum kodu döndürülür. kolaylık BadRequest yöntemi için shorthand olarak çağrılır. return new BadRequestResult();
  • Ürün oluşturulduğunda kolaylık yöntemi tarafından bir 201 CreatedAtAction durum kodu oluşturulur. çağrısına alternatif olarak CreatedAtAction : return new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product); . Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Yeni Location 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 özelliklerini içermesi Name gerektiğini Description gösterir. Sağlanamadı ve Name Description istekte model doğrulamasının başarısız olması.

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

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

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

ASP.NET Core 2.1 veya sonraki bir sonraki bir yıl içinde özniteliği uygulanırsa model doğrulama hataları [ApiController] 400 durum koduyla sonuçlanmasına neden olur. Daha fazla bilgi için bkz. Otomatik HTTP 400 yanıtları.

ActionResult ve IActionResult karşılaştırması

Aşağıdaki bölüm ile ActionResult karşılaştırıldığında IActionResult

ActionResult <T> türü

ASP.NET Core web API denetleyicisi <T> eylemleri için ActionResult dönüş türünü içerir. türünden türetilen bir tür veya belirli bir ActionResult türü geri dönmeniz olanak sağlar. ActionResult<T>IActionResult türüne göre aşağıdaki avantajları sunar:

  • [ProducesResponseType]Özniteliğin Type özelliği hariç tutulabilirsiniz. Örneğin, olarak [ProducesResponseType(200, Type = typeof(Product))] [ProducesResponseType(200)] basitleştirilmiştir. Eylemin beklenen dönüş türü, bunun yerine içinde 'den T (). ActionResult<T>
  • Örtülü tür dönüştürme işleçleri hem hem de 'ye T dönüştürmeyi ActionResult ActionResult<T> destekler. T, 'a ObjectResult dönüştürülür; başka bir return new ObjectResult(T); ifadeyle basitleştirilmiştir. return T;

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

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

Önceki kodu düzeltmenin bir yolu, 'i geri _repository.GetProducts().ToList(); dönmektir.

Ç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 tür döndürülz. Ö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ün dönmesi yaygındır.

Zaman uyumlu eylem

İki olası dönüş türü olan zaman uyumlu bir eylemi 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;
}

Yukarıdaki eylemde:

  • Ürün veritabanında mevcut olmayan bir 404 durum kodu döndürülür.
  • Ürün mevcut olduğunda karşılık gelen nesneyle birlikte 200 Product durum kodu döndürülür. 2.1 ASP.NET Core önce return product; satırın olması gerekirdi. return Ok(product);

Zaman uyumsuz eylem

İki olası dönüş türü olan zaman uyumsuz bir eylemi 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);
}

Yukarıdaki eylemde:

  • 400 durum kodu ( BadRequest ) aşağıdaki olduğunda ASP.NET Core döndürülür:
    • Özniteliği [ApiController] 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 bir 201 CreatedAtAction durum kodu oluşturulur. Bu kod yolunda nesnesi Product yanıt gövdesinde sağlanır. Yeni Location oluşturulan ürünün URL'sini içeren bir yanıt üst bilgisi sağlanır.

Ek kaynaklar