Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
tarafından Mike Wasson
Kod örnekleriyle ilgili bu genel bakış, ASP.NET 4.x için ASP.NET Web API 2'de desteklenen OData Sorgu Seçeneklerini gösterir.
OData, bir OData sorgusunu değiştirmek için kullanılabilecek parametreleri tanımlar. İstemci bu parametreleri istek URI'sinin sorgu dizesinde gönderir. Örneğin, sonuçları sıralamak için istemci $orderby parametresini kullanır:
http://localhost/Products?$orderby=Name
OData belirtimi bu parametre sorgu seçeneklerini çağırır. Projenizdeki herhangi bir Web API denetleyicisi için OData sorgu seçeneklerini etkinleştirebilirsiniz; denetleyicinin OData uç noktası olması gerekmez. Bu, herhangi bir Web API'sine filtreleme ve sıralama gibi özellikler eklemek için kullanışlı bir yol sağlar.
Sorgu seçeneklerini etkinleştirmeden önce lütfen OData Güvenlik Kılavuzu konusunu okuyun.
- OData Sorgu Seçeneklerini Etkinleştirme
- Örnek Sorgular
- Sunucu Tarafından Yönlendirilen Sayfalama
- Sorgu Seçeneklerini Sınırlama
- Sorgu Seçeneklerini Doğrudan Çağırma
- Sorgu Doğrulama
OData Sorgu Seçeneklerini Etkinleştirme
Web API'si aşağıdaki OData sorgu seçeneklerini destekler:
| Seçenek | Açıklama |
|---|---|
| $expand | İlgili varlıkları satır içi olarak genişletir. |
| $filter | Boole koşuluna göre sonuçları filtreler. |
| $inlinecount | Sunucuya yanıta eşleşen varlıkların toplam sayısını dahil etmelerini söyler. (Sunucu tarafı sayfalama için kullanışlıdır.) |
| $orderby | Sonuçları sıralar. |
| $select | Yanıta eklenecek özellikleri seçer. |
| $skip | İlk n sonucu atlar. |
| $top | Yalnızca ilk n sonucu döndürür. |
OData sorgu seçeneklerini kullanmak için bunları açıkça etkinleştirmeniz gerekir. Bunları tüm uygulama için genel olarak etkinleştirebilir veya belirli denetleyiciler veya belirli eylemler için etkinleştirebilirsiniz.
OData sorgu seçeneklerini genel olarak etkinleştirmek için başlangıçta HttpConfiguration sınıfında EnableQuerySupport'u çağırın:
public static void Register(HttpConfiguration config)
{
// ...
config.EnableQuerySupport();
// ...
}
EnableQuerySupport yöntemi, IQueryable türü döndüren tüm denetleyici eylemleri için genel olarak sorgu seçeneklerini etkinleştirir. Tüm uygulama için sorgu seçeneklerinin etkinleştirilmesini istemiyorsanız, eylem yöntemine [Queryable] özniteliğini ekleyerek bunları belirli denetleyici eylemleri için etkinleştirebilirsiniz.
public class ProductsController : ApiController
{
[Queryable]
IQueryable<Product> Get() {}
}
Örnek Sorgular
Bu bölümde, OData sorgu seçenekleri kullanılarak mümkün olan sorgu türleri gösterilir. Sorgu seçenekleri hakkında belirli ayrıntılar için www.odata.orgkonumundaki OData belgelerine bakın.
$expand ve $select hakkında bilgi için bkz. ASP.NET Web API OData'da $select, $expand ve $value kullanma.
İstemci Tarafından Yönlendirilen Sayfalama
Büyük varlık kümeleri için istemci, sonuç sayısını sınırlamak isteyebilir. Örneğin, bir istemci aynı anda 10 kayıt gösterebilir ve bir sonraki sonuç sayfasına erişmek için "sonraki" bağlantılarını kullanabilir. Bunu yapmak için istemci $top ve $skip seçeneklerini kullanır.
http://localhost/Products?$top=10&$skip=20
$top seçeneği döndürülecek maksimum giriş sayısını, $skip seçeneği ise geçilecek giriş sayısını belirtir. Önceki örnek 21 ile 30 arasında girdileri getirir.
Filtreleme
$filter seçeneği, istemcinin Boole ifadesi uygulayarak sonuçları filtrelemesine olanak tanır. Filtre ifadeleri oldukça güçlü; bunlar mantıksal ve aritmetik işleçler, dize işlevleri ve tarih işlevlerini içerir.
| "Oyuncaklar" kategorisine eşit tüm ürünleri iade edin. |
http://localhost/Products?$filter=Category eq 'Oyuncaklar' |
|---|---|
| Fiyatı 10'dan az olan tüm ürünleri iade edin. |
http://localhost/Products?$filter=Price lt 10 |
| Mantıksal işleçler: Fiyat = 5 ve fiyat ><= 15 olan tüm ürünleri döndürür. |
http://localhost/Products?$filter=Price ge 5 ve Price le 15 |
| Dize işlevleri: Adında "zz" olan tüm ürünleri döndürür. | http://localhost/Products?$filter=substringof('zz',Name) |
| Tarih işlevleri: 2005'in ardından ReleaseDate ile tüm ürünleri döndürür. |
http://localhost/Products?$filter=year(ReleaseDate) gt 2005 |
Sıralama
Sonuçları sıralamak için $orderby filtresini kullanın.
| Fiyata göre sırala. | http://localhost/Products?$orderby=Price |
|---|---|
| Fiyata göre azalan düzende sıralayın (en yüksek ile en düşük arasında). | http://localhost/Products?$orderby=Price desc |
| Kategoriye göre sıralayın, ardından kategoriler içinde fiyata göre azalan düzende sıralayın. | http://localhost/odata/Products?$orderby=Category,Price desc |
Sunucu Tabanlı Sayfalama
Veritabanınız milyonlarca kayıt içeriyorsa, tümünü tek bir yükte göndermek istemezsiniz. Bunu önlemek için, sunucu tek bir yanıtta gönderdiği girdi sayısını sınırlayabilir. Sunucu sayfalamasını etkinleştirmek için Queryable özniteliğinde PageSize özelliğini ayarlayın. Değer, döndürülecek girdi sayısı üst sınırıdır.
[Queryable(PageSize=10)]
public IQueryable<Product> Get()
{
return products.AsQueryable();
}
Denetleyiciniz OData biçimini döndürürse, yanıt gövdesi sonraki veri sayfasına bir bağlantı içerir:
{
"odata.metadata":"http://localhost/$metadata#Products",
"value":[
{ "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
{ "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
// Others not shown
],
"odata.nextLink":"http://localhost/Products?$skip=10"
}
İstemci, sonraki sayfayı getirmek için bu bağlantıyı kullanabilir. Sonuç kümesindeki toplam girdi sayısını öğrenmek için istemci, "allpages" değeriyle $inlinecount sorgu seçeneğini ayarlayabilir.
http://localhost/Products?$inlinecount=allpages
"allpages" değeri sunucuya yanıta toplam sayıyı eklemesini söyler:
{
"odata.metadata":"http://localhost/$metadata#Products",
"odata.count":"50",
"value":[
{ "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
{ "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
// Others not shown
]
}
Uyarı
Sonraki sayfa bağlantıları ve satır içi sayıların her ikisi de OData biçimi gerektirir. Bunun nedeni, OData'nın bağlantıyı ve sayıyı tutmak için yanıt gövdesinde özel alanlar tanımlamasıdır.
OData olmayan biçimler için, sorgu sonuçlarını bir PageResult<T> nesnesine sarmalayarak sonraki sayfa bağlantılarını ve satır içi sayımı desteklemek mümkündür. Ancak, biraz daha kod gerektirir. Örnek aşağıda verilmiştir:
public PageResult<Product> Get(ODataQueryOptions<Product> options)
{
ODataQuerySettings settings = new ODataQuerySettings()
{
PageSize = 5
};
IQueryable results = options.ApplyTo(_products.AsQueryable(), settings);
return new PageResult<Product>(
results as IEnumerable<Product>,
Request.GetNextPageLink(),
Request.GetInlineCount());
}
Örnek bir JSON yanıtı aşağıda verilmiştir:
{
"Items": [
{ "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
{ "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
// Others not shown
],
"NextPageLink": "http://localhost/api/values?$inlinecount=allpages&$skip=10",
"Count": 50
}
Sorgu Seçeneklerini Sınırlama
Sorgu seçenekleri, istemciye sunucuda çalıştırılacak sorgu üzerinde çok fazla denetim sağlar. Bazı durumlarda, güvenlik veya performans nedenleriyle kullanılabilir seçenekleri sınırlamak isteyebilirsiniz. [Queryable] özniteliği bunun için bazı yerleşik özelliklere sahiptir. Aşağıda bazı örnekler verilmiştir.
Sayfalama ve başka bir şey için değil, yalnızca $skip ve $top destekleyin:
[Queryable(AllowedQueryOptions=
AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]
Veritabanında dizine alınmamış özelliklere göre sıralamayı önlemek için yalnızca belirli özelliklere göre sıralamaya izin verin:
[Queryable(AllowedOrderByProperties="Id")] // comma-separated list of properties
"eq" mantıksal işlevine izin verin, ancak başka hiçbir mantıksal işlevlere izin vermeyin.
[Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]
Aritmetik işleçlere izin verme:
[Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]
QueryableAttribute örneği oluşturup EnableQuerySupport işlevine geçirerek seçenekleri genel olarak kısıtlayabilirsiniz:
var queryAttribute = new QueryableAttribute()
{
AllowedQueryOptions = AllowedQueryOptions.Top | AllowedQueryOptions.Skip,
MaxTop = 100
};
config.EnableQuerySupport(queryAttribute);
Sorgu Seçeneklerini Doğrudan Çağırma
[Queryable] özniteliğini kullanmak yerine sorgu seçeneklerini doğrudan denetleyicinizde çağırabilirsiniz. Bunu yapmak için denetleyici yöntemine bir ODataQueryOptions parametresi ekleyin. Bu durumda ,[Queryable] özniteliğine ihtiyacınız yoktur.
public IQueryable<Product> Get(ODataQueryOptions opts)
{
var settings = new ODataValidationSettings()
{
// Initialize settings as needed.
AllowedFunctions = AllowedFunctions.AllMathFunctions
};
opts.Validate(settings);
IQueryable results = opts.ApplyTo(products.AsQueryable());
return results as IQueryable<Product>;
}
Web API,URI sorgu dizesinden ODataQueryOptions'ı doldurur. Sorguyu uygulamak için ApplyTo yöntemine bir IQueryable geçirin. yöntemi başka bir IQueryable döndürür.
Gelişmiş senaryolar için, IQueryable sorgu sağlayıcınız yoksa ODataQueryOptions'ı inceleyebilir ve sorgu seçeneklerini başka bir forma çevirebilirsiniz. (Örneğin, RaghuRam Nadiminti'nin OData sorgularını HQL'ye çevirme blog gönderisine bakın)
Sorgu Doğrulama
[Queryable] özniteliği sorguyu yürütmeden önce doğrular. Doğrulama adımı QueryableAttribute.ValidateQuery yönteminde gerçekleştirilir. Doğrulama işlemini de özelleştirebilirsiniz.
Ayrıca bkz. OData Güvenlik Kılavuzu.
İlk olarak, Web.Http.OData.Query.Validators ad alanında tanımlanan doğrulayıcı sınıflarından birini geçersiz kılın. Örneğin, aşağıdaki doğrulayıcı sınıfı $orderby seçeneği için 'desc' seçeneğini devre dışı bırakır.
public class MyOrderByValidator : OrderByQueryValidator
{
// Disallow the 'desc' parameter for $orderby option.
public override void Validate(OrderByQueryOption orderByOption,
ODataValidationSettings validationSettings)
{
if (orderByOption.OrderByNodes.Any(
node => node.Direction == OrderByDirection.Descending))
{
throw new ODataException("The 'desc' option is not supported.");
}
base.Validate(orderByOption, validationSettings);
}
}
ValidateQuery yöntemini geçersiz kılmak için [Queryable] özniteliğini alt sınıfa ekleyin.
public class MyQueryableAttribute : QueryableAttribute
{
public override void ValidateQuery(HttpRequestMessage request,
ODataQueryOptions queryOptions)
{
if (queryOptions.OrderBy != null)
{
queryOptions.OrderBy.Validator = new MyOrderByValidator();
}
base.ValidateQuery(request, queryOptions);
}
}
Ardından özel özniteliğinizi genel olarak veya denetleyici başına ayarlayın:
// Globally:
config.EnableQuerySupport(new MyQueryableAttribute());
// Per controller:
public class ValuesController : ApiController
{
[MyQueryable]
public IQueryable<Product> Get()
{
return products.AsQueryable();
}
}
ODataQueryOptions'ı doğrudan kullanıyorsanız, seçeneklerde doğrulayıcıyı ayarlayın:
public IQueryable<Product> Get(ODataQueryOptions opts)
{
if (opts.OrderBy != null)
{
opts.OrderBy.Validator = new MyOrderByValidator();
}
var settings = new ODataValidationSettings()
{
// Initialize settings as needed.
AllowedFunctions = AllowedFunctions.AllMathFunctions
};
// Validate
opts.Validate(settings);
IQueryable results = opts.ApplyTo(products.AsQueryable());
return results as IQueryable<Product>;
}