Ana içeriğe atla

ListRequestHandler


Bu, istemci tarafından, örneğin ızgaralardan kaynaklanan Liste isteklerini işleyen temel sınıftır.

Öncelikle bu sınıfın liste isteklerini ne zaman ve nasıl ele aldığını örnekleyelim:

  1. Öncelikle istemci tarafından bir liste isteği tetiklenmelidir. Olası seçenekler şunlardır:

    a) Izgara içeren bir liste sayfası açarsınız. Izgara nesneniz oluşturulduktan hemen sonra, o anda görünen sütunlara, ilk sıralama düzenine, filtrelere vb. dayalı olarak bir ListRequest nesnesi oluşturur ve bunu sunucu tarafına gönderir.

    b) Kullanıcı, A seçeneğinde aynı olayları tetiklemek için sıralamak için bir sütun başlığına tıklar, sayfalama düğmelerine veya yenileme düğmesine tıklar.

    c) XYZService.List yöntemini kullanarak bir liste hizmetini manuel olarak arayabilirsiniz.

  2. Sunucuya MVC XYZController'a (XYZEndpoint.cs dosyasında) bir hizmet isteği (AJAX) gelir. İstek parametreleri JSON'dan bir ListRequest nesnesine seri durumdan çıkarılır.

  3. XYZEndpoint, alınan ListRequest nesnesiyle XYZRepository.List yöntemini çağırır.

  4. XYZRepository.List yöntemi, ListRequestHandler'ın (XYZRepository.MyListHandler) bir alt sınıfını oluşturur ve ListRequest ile Process yöntemini çağırır.

  5. ListRequestHandler.Process yöntemi, ListRequest'i, varlık türündeki (Row) meta verileri ve diğer bilgileri temel alarak dinamik bir SQL sorgusu oluşturur ve onu yürütür.

  6. ListRequestHandler.Process, döndürülecek satırları içeren bir ListResponse with Entities üyesini döndürür.

  7. XYZEndpoint bu ListResponse'u alır ve eylemden döndürür.

  8. ListResponse JSON'a serileştirilir ve istemciye geri gönderilir

  9. Izgara varlıkları alır, görüntülenen satırlarını ve sayfalama durumu gibi diğer parçaları günceller.

Başka bir bölümde ızgaraların nasıl liste isteği oluşturup gönderdiğini ele alacağız. Şimdilik ListRequestHandler'a odaklanalım.

İstek Nesnesini Listele

Öncelikle ListRequest nesnesinin hangi üyelere sahip olduğuna bir göz atmalıyız:

  public class ListRequest : ServiceRequest, IIncludeExcludeColumns
  {
      public int Skip { get; set; }
      public int Take { get; set; }
      public SortBy[] Sort { get; set; }
      public string ContainsText { get; set; }
      public string ContainsField { get; set; }
      public Dictionary<string, object> EqualityFilter { get; set; }
      [JsonConverter(typeof(JsonSafeCriteriaConverter))]
      public BaseCriteria Criteria { get; set; }
      public bool IncludeDeleted { get; set; }
      public bool ExcludeTotalCount { get; set; }
      public ColumnSelection ColumnSelection { get; set; }
      [JsonConverter(typeof(JsonStringHashSetConverter))]
      public HashSet<string> IncludeColumns { get; set; }
      [JsonConverter(typeof(JsonStringHashSetConverter))]
      public HashSet<string> ExcludeColumns { get; set; }
  }

ListRequest.Skip ve ListRequest.Take Parametreleri

Bu seçenekler sayfalama için kullanılır ve LINQ'daki Atla ve Sayfa uzantılarına benzer.

Take ile ilgili küçük bir fark var. Take(0) seçeneğini belirlerseniz, LINQ size sıfır kayıt döndürürken Serenity TÜM kayıtları döndürür. LIST servisini çağırıp 0 kayıt istemenin bir anlamı yok.

Dolayısıyla, SKIP ve TAKE'in varsayılan değerleri 0'dır ve 0 / tanımsız olduğunda bunlar basitçe göz ardı edilir.

// returns all customers as Skip and Take are 0 by default 
CustomerService.List(new ListRequest
{
}, response => {});

Sayfa boyutu 50 olan bir ızgaranız varsa ve 4 numaralı sayfaya geçerseniz, SKIP 200, TAKE ise 50 olacaktır.

// returns customers between row numbers 201 and 250 (in some default order)
CustomerService.List(new ListRequest
{
    Skip = 200,
    Take = 50
}, response => {});

Bu parametreler, SQL lehçesine dayalı olarak ilgili SQL sayfalama ifadelerine dönüştürülür.

ListRequest.Sort Parametresi

Bu parametre, sonuçların sıralanacağı bir dizi alır. Sıralama SQL üretilerek gerçekleştirilir.

SortBy parametresi SortBy nesnelerinin bir listesini bekler :

[JsonConverter(typeof(JsonSortByConverter))]
public class SortBy
{
    public SortBy()
    {
    }

    public SortBy(string field)
    {
        Field = field;
    }

    public SortBy(string field, bool descending)
    {
        Field = field;
        Descending = descending;
    }

    public string Field { get; set; }
    public bool Descending { get; set; }
}

Ülkeye, ardından Şehire göre azalan şekilde sıralamak için XYZRepository sunucu tarafının Liste yöntemini çağırırken, bunu şu şekilde yapabilirsiniz:

new CustomerRepository().List(connection, new ListRequest
{
    SortBy = new[] { 
        new SortBy("Country"),
        new SortBy("City", descending: true)
    }
});

SortBy sınıfının özel bir JsonConverter'ı vardır, bu nedenle istemci tarafında bir liste isteği oluştururken basit bir dize dizisi kullanmalısınız:

// CustomerEndpoint and thus CustomerRepository is accessed from 
// client side (YourProject.Script) through CustomerService class static methods 
// which is generated by ServiceContracts.tt
CustomerService.List(connection, new ListRequest
{
    SortBy = new[] { "Country", "City DESC" }
}, response => {});

Bunun nedeni, istemci tarafındaki ListRequest sınıfı tanımının biraz farklı bir yapıya sahip olmasıdır:

    [Imported, Serializable, PreserveMemberCase]
    public class ListRequest : ServiceRequest
    {
        public int Skip { get; set; }
        public int Take { get; set; }
        public string[] Sort { get; set; }
        // ...
    }

Burada kullanılan sütun adları karşılık gelen alanların Özellik adları olmalıdır. İfadeler kabul edilmez. Örneğin bu işe yaramayacak!:

CustomerService.List(connection, new ListRequest
{
    SortBy = new[] { "t0.FirstName + ' ' + t0.LastName" }
}, response => {});

ListRequest.ContainsText ve ListRequest.ContainsField Parametreleri

Bu parametreler, ızgaraların sol üst köşesindeki arama girişi olan hızlı arama işlevi tarafından kullanılır.

Yalnızca ContainerText belirtildiğinde ve ContainerField boş olduğunda, [QuickSearch] özelliğinin bulunduğu tüm alanlarda arama gerçekleştirilir.

GetQuickSearchField() yöntemlerini geçersiz kılarak, ızgara istemci tarafında aramalar gerçekleştirmek için bazı özel alan listeleri tanımlamak mümkündür. Yani hızlı arama girişinde böyle bir alan seçildiğinde sadece o sütunda arama yapılıyor.

ContainerField'ı üzerinde QuickSearch özelliği bulunmayan bir alan adına ayarlarsanız sistem bir istisna oluşturacaktır. Bu güvenlik amaçlıdır.

Arama her zamanki gibi dinamik SQL ile LIKE ifadeleriyle yapılır.

CustomerService.List(connection, new ListRequest
{
    ContainsText = "the",
    ContainsField = "CompanyName"
}, response => {});
SELECT ... FROM Customers t0 WHERE t0.CompanyName LIKE '%the%' 

ContainerText null veya boş bir dize ise basitçe yok sayılır.

ListRequest.EqualityFilter Parametresi

EqualityFilter, bazı alanlara göre hızlı eşitlik filtrelemesine olanak tanıyan bir sözlüktür. Izgaralardaki (AddEqualityFilter yardımcısıyla tanımlananlar) hızlı filtre açılır menüleri tarafından kullanılır.

CustomerService.List(connection, new ListRequest
{
    EqualityFilter = new JsDictionary<string, object> {
        { "Country", "Germany" }
    }
}, response => {});
SELECT * FROM Customers t0 WHERE t0.Country = "Germany" 

Yine özellik adlarını ifadeler olarak değil, eşitlik alanı anahtarları olarak kullanmalısınız. Serenity, SQL enjeksiyonlarını önlemek için istemci tarafından rastgele SQL ifadelerine izin vermez.

İçerenText'e benzer şekilde boş ve boş dize değerlerinin basitçe yok sayıldığını, dolayısıyla EqualityFilter ile boş veya boş değerleri filtrelemenin mümkün olmadığını lütfen unutmayın. Böyle bir istek tüm kayıtları döndürür:

CustomerService.List(connection, new ListRequest
{
    EqualityFilter = new JsDictionary<string, object> {
        { "Country", "" }, // won't work, empty string is ignored
        { "City", null }, // won't work, null is ignored
    }
}, response => {});

Müşterileri boş ülkelerle filtrelemek istiyorsanız Kriter parametresini kullanın.

ListRequest.Criteria

Bu parametre, Fluent SQL bölümünde bahsettiğimiz sunucu tarafı Criteria nesnelerine benzer kriter nesnelerini kabul eder. Tek fark, bu kriter nesneleri istemci tarafından gönderildiğinden, doğrulanmaları gerekir ve herhangi bir rastgele SQL ifadesi içeremezler.

Aşağıdaki hizmet isteği yalnızca boş ülke veya boş şehir değerlerine sahip müşterileri döndürecektir

CustomerService.List(connection, new ListRequest
{
    Criteria = new Criteria("Country") == "" | 
        new Criteria("City").IsNull()
}, response => {});

XYZGrid.cs dosyanızda gönderilmek üzere olan oluşturulan ListRequest'in Criteria parametresini aşağıdaki gibi ayarlayabilirsiniz:

protected override bool OnViewSubmit()
{
    // only continue if base class didn't cancel request
    if (!base.OnViewSubmit())
        return false;

    // view object is the data source for grid (SlickRemoteView)
    // this is an EntityGrid so view.Params is a ListRequest
    var request = (ListRequest)view.Params;

    // we use " &= " here because otherwise we might clear 
    // filter set by an edit filter dialog if any.

    request.Criteria &=
        new Criteria(ProductRow.Fields.UnitsInStock) > 10 &
        new Criteria(ProductRow.Fields.CategoryName) != "Condiments" &
        new Criteria(ProductRow.Fields.Discontinued) == 0;

    return true;
}

Izgaralarınızda ListRequest'in diğer parametrelerini de benzer şekilde ayarlayabilirsiniz.

ListRequest.IncludeDeleted

Bu parametre yalnızca IIsActiveDeletedRow arayüzünü uygulayan satırlarda kullanışlıdır. Satırın böyle bir arayüzü varsa, liste işleyicisi varsayılan olarak yalnızca silinmemiş satırları döndürür (IsActive != -1). Bu aslında satırları silmenin değil, silinmiş olarak işaretlemenin bir yoludur.

Bu parametre True ise liste işleyicisi IsActive sütununa bakmadan tüm satırları döndürecektir.

Bu tür satırlara ait bazı ızgaraların sağ üst kısmında bu bayrağı değiştirmek için küçük bir silgi simgesi bulunur, böylece silinen kayıtları gösterir veya gizler (varsayılan).

ListRequest.ColumnSelection Parametresi

Serenity, SQL Server < - > WEB Sunucusu arasındaki ağ trafiğini minimumda tutmak ve böylece istemciye aktarılan veri boyutunu mümkün olduğunca düşük tutmak için varlıklarınızın yalnızca gerekli sütunlarını SQL sunucusundan yüklemek için çok çalışır.

ListRequest, SQL'den yüklenen sütun kümesini kontrol etmeniz için bir ColumnSelection parametresine sahiptir.

ColumnSelection numaralandırması tanımlanmış aşağıdaki değerlere sahiptir:

public enum ColumnSelection
{
    List = 0,
    KeyOnly = 1,
    Details = 2,
}

Varsayılan olarak ızgara, "ColumnSelection.List" modunda Liste hizmetinden kayıt ister (değiştirilebilir). Böylece liste isteği şuna benzer:

new ListRequest
{
    ColumnSelection = ColumnSelection.List
}

ColumnSelection.List modunda , ListRequestHandler tablo alanlarını döndürür ; dolayısıyla, birleştirilmiş tablolardan kaynaklanan alanları görüntülemez, aslında tabloya ait olan alanları döndürür.

Yalnızca tablo alanlarına başvuru içeren ifade alanları bir istisnadır ; örneğin (t0.FirstName + '' + t0.LastName) . ListRequestHandler da bu tür alanları yükler.

ColumnSelection.KeyOnly yalnızca kimlik/birincil anahtar alanlarını içerir.

ColumnSelection.Details , bir alan açıkça hariç tutulmadığı veya örneğin bir şifre alanı gibi "hassas" olarak işaretlenmediği sürece, görünüm alanları da dahil olmak üzere tüm alanları içerir.

İletişim kutuları, düzenlenen kayıtları Ayrıntılar modunda yükler, dolayısıyla görünüm alanlarını da içerir.

ListRequest.IncludeColumns Parametresi

Grid'in Liste modunda kayıt istediğini, yani sadece tablo alanlarını yüklediğini, ardından diğer tablolardan gelen sütunları nasıl gösterebileceğini anlattık .

Grid, görünen sütunların listesini IncludeColumns ile List servisine gönderir , böylece bu sütunlar görünüm alanları olsa bile seçime dahil edilir .

Bellek ızgaralarında bunu yapamaz. Hizmetleri doğrudan çağırmadıklarından, bellek ayrıntı ızgaralarında yüklemek istemediğiniz alanları görüntülemek için [MinSelectLevel(SelectLevel.List)] koymanız gerekir.

TedarikçiAdı sütununu gösteren bir ProductGrid'iniz varsa, gerçek ListRequest şu şekilde görünür:

new ListRequest
{
    ColumnSelection = ColumnSelection.List,
    IncludeColumns = new List<string> {
        "ProductID",
        "ProductName",
        "SupplierName",
        "..."
    }
}

Böylece bu ekstra görünüm alanları da seçime dahil edilir .

Performans nedenleriyle yalnızca görünür sütunları yüklemesi gereken bir ızgaranız varsa ColumnSelection düzeyini KeyOnly olarak geçersiz kılın. Görünmeyen tablo alanlarının istemci tarafı satırında kullanılamayacağını unutmayın.

ListRequest.ExcludeColumns Parametresi

IncludeColumns'un karşısında ExcludeColumns bulunur. Diyelim ki satırınızda ızgarada hiçbir zaman gösterilmeyen bir nvarchar(max) Notes alanınız var. Ağ trafiğini azaltmak için bu alanı ürün kılavuzuna YÜKLEMEYİ seçebilirsiniz:

new ListRequest
{
    ColumnSelection = ColumnSelection.List,
    IncludeColumns = new List<string> {
        "ProductID",
        "ProductName",
        "SupplierName",
        "..."
    },
    ExcludeColumns = new List<string> {
        "Notes"
    }
}

OnViewSubmit bu parametreyi (ve diğerlerini) ayarlamak için iyi bir yerdir:

protected override bool OnViewSubmit()
{
    if (!base.OnViewSubmit())
        return false;

    var request = (ListRequest)view.Params;
    request.ExcludeColumns = new List<string> { "Notes" }
    return true;
}

Sunucu Tarafında Yüklemeyi Kontrol Etme

Notes gibi bazı alanları ColumnSelection.List'in dışında tutmak isteyebilirsiniz , ancak bunları ızgarada açıkça hariç tutmayınız. Bu MinSelectLevel özelliği ile mümkündür:

[MinSelectLevel(SelectLevel.Details)]
public String Note
{
    get { return Fields.Note[this]; }
    set { Fields.Note[this] = value; }
}

Farklı ColumnSelection düzeyleri için bir alanın ne zaman yüklendiğini denetleyen bir SelectLevel numaralandırması vardır:

public enum SelectLevel
{
    Default = 0,
    Always = 1,
    Lookup = 2,
    List = 3,
    Details = 4,
    Explicit = 5,
    Never = 6
}

Varsayılan değer olan SelectLevel.Default , tablo alanları için SelectLevel.List'e ve görünüm alanları için SelectLevel.Details'a karşılık gelir .

Varsayılan olarak tablo alanlarında SelectLevel.List seçme düzeyi bulunurken görünüm alanlarında SelectLevel.Details bulunur .

SelectLevel.Always, ExcludeColumns kullanılarak açıkça hariç tutulsa bile böyle bir alanın herhangi bir sütun seçim modu için seçildiği anlamına gelir .

SelectLevel.Lookup artık kullanılmıyor, kullanmaktan kaçının. Arama sütunları [LookupInclude] özelliği ile belirlenir.

SelectLevel.List, böyle bir alanın ColumnSelection.List ve ColumnSelection.Details modları için seçildiği veya açıkça IncludeColumns parametresine dahil edildiği anlamına gelir.

SelectLevel.Details, böyle bir alanın ColumnSelection.Details modu için seçildiği veya açıkça IncludeColumns parametresine dahil edildiği anlamına gelir.

SelectLevel.Explicit , IncludeColumns parametresine açıkça dahil edilmediği sürece böyle bir alanın hiçbir modda seçilmemesi gerektiği anlamına gelir. Izgaralar veya düzenleme diyalogları için anlamlı olmayan alanlar için bunu kullanın.

SelectLevel.Never bu alanı asla yüklemeyeceğiniz anlamına gelir! Parola karması gibi istemci tarafına gönderilmemesi gereken alanlar için kullanın.

Bu blogdaki popüler yayınlar

Code generetor ile oluşturulan dosyaların açıklamaları

  1. Sunum (Presentation/UI) Katmanı (Kullanıcı arayüzü - HTML, TypeScript, Dialog, Grid) 🔹 XYZPage.ts 📌 Ne İşe Yarar? Kullanıcı arayüzünün TypeScript tarafındaki tanımıdır. Serenity'nin Dialog ve Grid bileşenlerini içeren bir TypeScript sınıfıdır. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kullanıcıdan veri almak ve göstermek için kullanılır. 🔹 XYZGrid.ts 📌 Ne İşe Yarar? Tablo (Grid) yapısını oluşturur ve verileri listeler. Filtreleme, sıralama ve sayfalama işlemleri için kullanılır. columnsKey ile hangi kolonların gösterileceğini belirler. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kullanıcının verileri listelediği ve etkileşimde bulunduğu yerdir. 🔹 XYZDialog.ts 📌 Ne İşe Yarar? CRUD (Create, Read, Update, Delete) işlemlerini yöneten pencere (modal) bileşeni Kullanıcı form aracılığıyla veri ekler, günceller veya siler. XYZForm.cs ile birlikte çalışır. 📌 Çok Katmanlı Mimarideki Yeri: Sunum Katmanı (Presentation Layer) Kull...

Serenity Web Nedir?

   Serenity  , açık kaynak teknolojileri üzerine kurulu bir ASP.NET Core/TypeScript uygulama platformudur. Standart kodlardan kaçınarak, tekrarlanan görevlere harcanan zamanı azaltarak ve en iyi yazılım tasarımı uygulamalarını uygulayarak bakım maliyetlerini düşürürken geliştirmeyi kolaylaştırmayı amaçlamaktadır. Serene  , Serenity platformunu temel alan ücretsiz, açık kaynaklı başlangıç ​​uygulama şablonumuzdur.  Bu dokümantasyon aracılığıyla eğitimimiz ve diğer örnekler için esas olarak Serene'yi kullanacağız. StartSharp  , ücretli müşterilerimize sunduğumuz premium uygulama şablonudur.  Daha gösterişli bir temaya ve bazı ekstra özelliklere  ek olarak Serene'deki her şeyi içerir  .  İkisi de Serenity platformunu temel alıyor. Adında Ne Var Serenity'nin sözlük anlamları  barış  ,  rahatlık  ve  sakinliktir  . Serenity ile bunu başarmaya çalışıyoruz.  Umarız yükledikten ve kullandıktan sonra siz de bu ş...