Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Mike Wasson
Dalam OData, tindakan dan fungsi adalah cara untuk menambahkan perilaku sisi server yang tidak mudah didefinisikan sebagai operasi CRUD pada entitas. Tutorial ini menunjukkan cara menambahkan tindakan dan fungsi ke titik akhir OData v4, menggunakan Web API 2.2. Tutorial ini dibangun pada tutorial Membuat Titik Akhir OData v4 Menggunakan ASP.NET Web API 2
Versi perangkat lunak yang digunakan dalam tutorial
- WEB API 2.2
- OData v4
- Visual Studio 2013 (unduh Visual Studio 2017 di sini)
- .NET 4.5
Versi tutorial
Untuk OData Versi 3, lihat Tindakan OData di ASP.NET Web API 2.
Perbedaan antara tindakan dan fungsi adalah bahwa tindakan dapat memiliki efek samping, dan fungsi tidak. Tindakan dan fungsi dapat mengembalikan data. Beberapa kegunaan untuk tindakan meliputi:
- Transaksi kompleks.
- Memanipulasi beberapa entitas sekaligus.
- Mengizinkan pembaruan hanya untuk properti entitas tertentu.
- Mengirim data yang bukan entitas.
Fungsi berguna untuk mengembalikan informasi yang tidak sesuai langsung dengan entitas atau koleksi.
Tindakan (atau fungsi) dapat menargetkan satu entitas atau koleksi. Dalam terminologi OData, ini adalah pengikatan. Anda juga dapat memiliki tindakan/fungsi "tidak terikat", yang disebut sebagai operasi statis pada layanan.
Contoh: Menambahkan Tindakan
Mari kita tentukan tindakan untuk menilai produk.
Catatan
Tutorial ini dibangun pada tutorial Membuat Titik Akhir OData v4 Menggunakan ASP.NET Web API 2
Pertama, tambahkan ProductRating model untuk mewakili peringkat.
namespace ProductService.Models
{
public class ProductRating
{
public int ID { get; set; }
public int Rating { get; set; }
public int ProductID { get; set; }
public virtual Product Product { get; set; }
}
}
Tambahkan juga DbSet ke ProductsContext kelas , sehingga EF akan membuat tabel Peringkat dalam database.
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
// New code:
public DbSet<ProductRating> Ratings { get; set; }
}
Menambahkan Tindakan ke EDM
Di WebApiConfig.cs, tambahkan kode berikut:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
// New code:
builder.Namespace = "ProductService";
builder.EntityType<Product>()
.Action("Rate")
.Parameter<int>("Rating");
Metode EntityTypeConfiguration.Action menambahkan tindakan ke model data entitas (EDM). Metode Parameter menentukan parameter yang ditik untuk tindakan.
Kode ini juga mengatur namespace layanan untuk EDM. Namespace penting karena URI untuk tindakan menyertakan nama tindakan yang sepenuhnya memenuhi syarat:
http://localhost/Products(1)/ProductService.Rate
Catatan
Dalam konfigurasi IIS biasa, titik dalam URL ini akan menyebabkan IIS mengembalikan kesalahan 404. Anda dapat mengatasinya dengan menambahkan bagian berikut ke file Web.Config Anda:
<system.webServer>
<handlers>
<clear/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*"
verb="*" type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Menambahkan Metode Pengontrol untuk Tindakan
Untuk mengaktifkan tindakan "Rate", tambahkan metode berikut ke ProductsController:
[HttpPost]
public async Task<IHttpActionResult> Rate([FromODataUri] int key, ODataActionParameters parameters)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
int rating = (int)parameters["Rating"];
db.Ratings.Add(new ProductRating
{
ProductID = key,
Rating = rating
});
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException e)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
Perhatikan bahwa nama metode cocok dengan nama tindakan. Atribut [HttpPost] menentukan metode adalah metode HTTP POST.
Untuk memanggil tindakan, klien mengirim permintaan HTTP POST seperti berikut ini:
POST http://localhost/Products(1)/ProductService.Rate HTTP/1.1
Content-Type: application/json
Content-Length: 12
{"Rating":5}
Tindakan "Laju" terikat ke instans Produk, sehingga URI untuk tindakan adalah nama tindakan yang sepenuhnya memenuhi syarat ditambahkan ke URI entitas. (Ingat bahwa kami mengatur namespace layanan EDM ke "ProductService", sehingga nama tindakan yang sepenuhnya memenuhi syarat adalah "ProductService.Rate".)
Isi permintaan berisi parameter tindakan sebagai payload JSON. WEB API secara otomatis mengonversi payload JSON menjadi objek ODataActionParameters , yang hanya merupakan kamus nilai parameter. Gunakan kamus ini untuk mengakses parameter dalam metode pengontrol Anda.
Jika klien mengirim parameter tindakan dalam format yang salah, nilai ModelState.IsValid adalah false. Periksa bendera ini di metode pengontrol Anda dan kembalikan kesalahan jika IsValid salah.
if (!ModelState.IsValid)
{
return BadRequest();
}
Contoh: Menambahkan Fungsi
Sekarang mari kita tambahkan fungsi OData yang mengembalikan produk termahal. Seperti sebelumnya, langkah pertama adalah menambahkan fungsi ke EDM. Di WebApiConfig.cs, tambahkan kode berikut.
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
builder.EntitySet<Supplier>("Suppliers");
// New code:
builder.Namespace = "ProductService";
builder.EntityType<Product>().Collection
.Function("MostExpensive")
.Returns<double>();
Dalam hal ini, fungsi ini terikat pada koleksi Produk, bukan instans Produk individual. Klien memanggil fungsi dengan mengirim permintaan GET:
GET http://localhost:38479/Products/ProductService.MostExpensive
Berikut adalah metode pengontrol untuk fungsi ini:
public class ProductsController : ODataController
{
[HttpGet]
public IHttpActionResult MostExpensive()
{
var product = db.Products.Max(x => x.Price);
return Ok(product);
}
// Other controller methods not shown.
}
Perhatikan bahwa nama metode cocok dengan nama fungsi. Atribut [HttpGet] menentukan metode adalah metode HTTP GET.
Berikut adalah respons HTTP:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
OData-Version: 4.0
Date: Sat, 28 Jun 2014 00:44:07 GMT
Content-Length: 85
{
"@odata.context":"http://localhost:38479/$metadata#Edm.Decimal","value":50.00
}
Contoh: Menambahkan Fungsi Tidak Terikat
Contoh sebelumnya adalah fungsi yang terikat ke koleksi. Dalam contoh berikutnya ini, kita akan membuat fungsi yang tidak terikat . Fungsi yang tidak terikat disebut sebagai operasi statis pada layanan. Fungsi dalam contoh ini akan mengembalikan pajak penjualan untuk kode pos tertentu.
Dalam file WebApiConfig, tambahkan fungsi ke EDM:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
// New code:
builder.Function("GetSalesTaxRate")
.Returns<double>()
.Parameter<int>("PostalCode");
Perhatikan bahwa kami memanggil Fungsi langsung di ODataModelBuilder, bukan jenis entitas atau koleksi. Ini memberi tahu penyusun model bahwa fungsi tidak terikat.
Berikut adalah metode pengontrol yang mengimplementasikan fungsi :
[HttpGet]
[ODataRoute("GetSalesTaxRate(PostalCode={postalCode})")]
public IHttpActionResult GetSalesTaxRate([FromODataUri] int postalCode)
{
double rate = 5.6; // Use a fake number for the sample.
return Ok(rate);
}
Tidak masalah pengontrol API Web tempat Anda menempatkan metode ini. Anda dapat memasukkannya ke dalam ProductsController, atau menentukan pengontrol terpisah. Atribut [ODataRoute] mendefinisikan templat URI untuk fungsi tersebut.
Berikut adalah contoh permintaan klien:
GET http://localhost:38479/GetSalesTaxRate(PostalCode=10) HTTP/1.1
Respons HTTP:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
OData-Version: 4.0
Date: Sat, 28 Jun 2014 01:05:32 GMT
Content-Length: 82
{
"@odata.context":"http://localhost:38479/$metadata#Edm.Double","value":5.6
}