ASP.NET Web API'sini Kullanarak OData v4 Uç Noktası Oluşturma
Açık Veri Protokolü (OData), web için bir veri erişim protokolüdür. OData, CRUD işlemleri (oluşturma, okuma, güncelleştirme ve silme) aracılığıyla veri kümelerini sorgulamak ve işlemek için tekdüzen bir yol sağlar.
ASP.NET Web API'si protokolün hem v3 hem de v4'lerini destekler. Hatta v3 uç noktasıyla yan yana çalışan bir v4 uç noktanız bile olabilir.
Bu öğreticide CRUD işlemlerini destekleyen bir OData v4 uç noktasının nasıl oluşturulacağı gösterilmektedir.
Öğreticide kullanılan yazılım sürümleri
- Web API 5.2
- OData v4
- Visual Studio 2017 (Visual Studio 2017'i buradan indirin)
- Entity Framework 6
- .NET 4.7.2
Öğretici sürümleri
OData Sürüm 3 için bkz. OData v3 Uç Noktası Oluşturma.
Visual Studio Projesi Oluşturma
Visual Studio'da, Dosyamenüsünden Yeni Proje'yi> seçin.
Yüklü>Visual C#>Web'i genişletin ve ASP.NET Web Uygulaması (.NET Framework) şablonunu seçin. Projeyi "ProductService" olarak adlandırın.
Tamam’ı seçin.
Boş şablonu seçin. Klasör ve çekirdek başvuruları ekle:'nin altında Web API'sini seçin. Tamam’ı seçin.
OData paketlerini yükleme
Araçlar menüsünde NuGet Paket Yöneticisi Paket Yöneticisi>Konsolu'nu seçin. Paket Yöneticisi Konsolu penceresinde şunu yazın:
Install-Package Microsoft.AspNet.Odata
Bu komut en son OData NuGet paketlerini yükler.
Model sınıfı ekleme
Model, uygulamanızdaki bir veri varlığını temsil eden bir nesnedir.
Çözüm Gezgini'da Modeller klasörüne sağ tıklayın. Bağlam menüsündeSınıfEkle'yi> seçin.
Not
Kural gereği, model sınıfları Modeller klasörüne yerleştirilir, ancak kendi projelerinizde bu kuralı izlemeniz gerekmez.
sınıfını Product
adlandırın. Product.cs dosyasında ortak kodu aşağıdakilerle değiştirin:
namespace ProductService.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
}
Id
özelliği varlık anahtarıdır. İstemciler varlıkları anahtara göre sorgulayabilir. Örneğin, kimliği 5 olan ürünü almak için URI olur /Products(5)
. Id
özelliği, arka uç veritabanındaki birincil anahtar da olacaktır.
Entity Framework'i etkinleştirme
Bu öğreticide arka uç veritabanını oluşturmak için Entity Framework (EF) Code First kullanacağız.
Not
Web API OData ef gerektirmez. Veritabanı varlıklarını modellere çevirebilen herhangi bir veri erişim katmanını kullanın.
İlk olarak EF için NuGet paketini yükleyin. Araçlar menüsünde NuGet Paket Yöneticisi Paket Yöneticisi>Konsolu'nu seçin. Paket Yöneticisi Konsolu penceresinde şunu yazın:
Install-Package EntityFramework
Web.config dosyasını açın ve configSections öğesinden sonra yapılandırma öğesinin içine aşağıdaki bölümü ekleyin.
<configuration>
<configSections>
<!-- ... -->
</configSections>
<!-- Add this: -->
<connectionStrings>
<add name="ProductsContext" connectionString="Data Source=(localdb)\mssqllocaldb;
Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
AttachDbFilename=|DataDirectory|ProductsContext.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>
Bu ayar bir LocalDB veritabanı için bağlantı dizesi ekler. Uygulamayı yerel olarak çalıştırdığınızda bu veritabanı kullanılır.
Ardından Models klasörüne adlı ProductsContext
bir sınıf ekleyin:
using System.Data.Entity;
namespace ProductService.Models
{
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
}
}
Oluşturucuda bağlantı "name=ProductsContext"
dizesinin adını verir.
OData uç noktasını yapılandırma
App_Start/WebApiConfig.cs dosyasını açın. Aşağıdaki using deyimlerini ekleyin:
using ProductService.Models;
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;
Ardından Register yöntemine aşağıdaki kodu ekleyin:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
}
}
Bu kod iki işlem yapar:
- Varlık Veri Modeli (EDM) oluşturur.
- Bir yol ekler.
EDM, verilerin soyut bir modelidir. EDM, hizmet meta verisi belgesini oluşturmak için kullanılır. ODataConventionModelBuilder sınıfı, varsayılan adlandırma kurallarını kullanarak bir EDM oluşturur. Bu yaklaşım için en az kod gerekir. EDM üzerinde daha fazla denetim istiyorsanız, özellikleri, anahtarları ve gezinti özelliklerini açıkça ekleyerek EDM'yi oluşturmak için ODataModelBuilder sınıfını kullanabilirsiniz.
Yol, Web API'sine HTTP isteklerini uç noktaya nasıl yönlendireceklerini bildirir. OData v4 yolu oluşturmak için MapODataServiceRoute uzantısı yöntemini çağırın.
Uygulamanızın birden çok OData uç noktası varsa, her biri için ayrı bir yol oluşturun. Her yola benzersiz bir yol adı ve ön eki verin.
OData denetleyicisini ekleme
Denetleyici, HTTP isteklerini işleyen bir sınıftır. OData hizmetinizdeki her varlık kümesi için ayrı bir denetleyici oluşturursunuz. Bu öğreticide varlık için Product
bir denetleyici oluşturacaksınız.
Çözüm Gezgini'da Denetleyiciler klasörüne sağ tıklayın veSınıfEkle'yi> seçin. sınıfını ProductsController
adlandırın.
Not
OData v3 için bu öğreticinin sürümünde Denetleyici Ekle iskelesi kullanılır. Şu anda OData v4 için yapı iskelesi yoktur.
ProductsController.cs dosyasındaki ortak kodu aşağıdakiyle değiştirin.
using ProductService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.OData;
namespace ProductService.Controllers
{
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
private bool ProductExists(int key)
{
return db.Products.Any(p => p.Id == key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
Denetleyici, EF kullanarak veritabanına erişmek için sınıfını kullanır ProductsContext
. Denetleyicinin, ProductsContext'i atmak için Dispose yöntemini geçersiz kıldığını fark edin.
Bu, denetleyicinin başlangıç noktasıdır. Ardından, tüm CRUD işlemleri için yöntemler ekleyeceğiz.
Varlık kümesini sorgulama
aşağıdaki yöntemleri öğesine ProductsController
ekleyin.
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
IQueryable<Product> result = db.Products.Where(p => p.Id == key);
return SingleResult.Create(result);
}
yönteminin Get
parametresiz sürümü, Products koleksiyonunun tamamını döndürür. Get
Anahtar parametresine sahip yöntem, bir ürünü anahtarına göre arar (bu örnekte özelliğiId
).
[EnableQuery] özniteliği istemcilerin $filter, $sort ve $page gibi sorgu seçeneklerini kullanarak sorguyu değiştirmesine olanak tanır. Daha fazla bilgi için bkz . OData Sorgu Seçeneklerini Destekleme.
Varlık kümesine varlık ekleme
İstemcilerin veritabanına yeni bir ürün eklemesini sağlamak için aşağıdaki yöntemi öğesine ProductsController
ekleyin.
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
Varlığı güncelleştirme
OData, bir varlığı güncelleştirmek için PATCH ve PUT olmak üzere iki farklı semantiği destekler.
- PATCH kısmi bir güncelleştirme gerçekleştirir. İstemci yalnızca güncelleştirilecek özellikleri belirtir.
- PUT tüm varlığın yerini alır.
PUT'nin dezavantajı, istemcinin değişmeyen değerler de dahil olmak üzere varlıktaki tüm özellikler için değerler göndermesi gerektiğidir. OData belirtimi PATCH'in tercih edilir olduğunu belirtir.
Her durumda, hem PATCH hem de PUT yöntemlerinin kodu aşağıdadır:
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entity = await db.Products.FindAsync(key);
if (entity == null)
{
return NotFound();
}
product.Patch(entity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != update.Id)
{
return BadRequest();
}
db.Entry(update).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(update);
}
PATCH söz konusu olduğunda denetleyici değişiklikleri izlemek için Delta<T> türünü kullanır.
Bir varlığı silme
İstemcilerin veritabanından bir ürünü silmesini sağlamak için aşağıdaki yöntemi öğesine ProductsController
ekleyin.
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
var product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
db.Products.Remove(product);
await db.SaveChangesAsync();
return StatusCode(HttpStatusCode.NoContent);
}