مطالب
جزئیات برنامه نویسی افزونه فارسی به پارسی

این افزونه با استفاده از ابزار Visual Studio Tools for Office که به VSTO مشهور شده است، تهیه شد. در بسته به روز رسانی سیستم که در ذیل (معرفی افزونه) نیز معرفی شد نگارش sp1 vsto3.0 آن به صورت خودکار نصب خواهد شد.
برای ایجاد این پروژه در VS.Net 2008 ، تنها کافی است یک پروژه جدید Word add-in را آغاز نمائیم. (شکل زیر)





قبل از ادامه بحث، بهتر است در مورد بانک اطلاعاتی مورد استفاده نیز توضیح داده شود. در اینجا از SQLite استفاده شد. (بسیار سبک، کم حجم و سریع است و اساسا یک کاربر نهایی برای تنظیمات آن نیازی نیست اطلاعاتی داشته باشد). بسته به روز رسانی سیستم (در مطلب قبلی)، این مورد را نیز به صورت خودکار نصب خواهد کرد (در GAC باید نصب شود وگرنه افزونه قادر به یافتن آن نخواهد شد).
برای ایجاد این بانک اطلاعاتی، از افزونه SQLite manager برای فایرفاکس استفاده شد. (این افزونه رایگان شما را از هر ابزار جانبی برای مدیریت یک بانک اطلاعاتی SQLite بی‌نیاز می‌کند)
برای مثال فایل ErrorsBank.sqlite برنامه افزونه فارسی به پارسی را توسط افزونه SQLite manager فایرفاکس باز کنید (این فایل را در محل نصب افزونه می‌توانید پیدا کنید). در اینجا می‌توان جداول جدید را ایجاد کرد، کوئری‌های دلخواه را اجرا نمود و یا اطلاعات را مرور کرده، حذف یا ویرایش کرد (شکل زیر).




و خوشبختانه این بانک اطلاعاتی و محصور کننده‌های آن با اطلاعات یونیکد فارسی هیچ مشکلی ندارند و برای کارهایی با وسعت کم و تعداد رکورد پائین یکی از بهترین انتخاب‌ها به‌شمار می‌روند.
نحوه استفاده از SQLite نیز در دات نت بسیار ساده است. اگر با ADO.Net کار کرده باشید، پس از افزودن ارجاعی از اسمبلی System.Data.SQLite.DLL به پروژه و معرفی فضای نام آن به پروژه، تنها کافی است در کدهای قبلی خود برای مثال SqlConnection را به SQLiteConnectionتغییر دهید و امثال آن. یعنی دانش ADO.Net شما در اینجا نیز کاملا قابل استفاده خواهد بود و نیازی نیست مدتی را صرف آشنا شدن با کلاس‌ها و مفاهیم جدید نمائید (البته این تنها زمانی معنا خواهد داشت که به ویزاردها عادت نکرده باشید و کارهای خود را با کد نویسی انجام داده باشید).
تنها یک نکته را باید به‌خاطر داشت و آن هم مربوط است به ساز و کار درونی SQLite . هنگام انجام عملیات update یا insert حتما از transaction استفاده کنید تا سرعت کوئری‌های شما در SQLite به نحو شگفت انگیزی افزایش یابد. مثالی در این مورد را در فایل chm راهنمای SQLite.NET می‌توانید پیدا کنید.

مطلب دیگری که پیش از پرداختن به کد نویسی افزونه باید با آن آشنا شویم، مفهوم smart tags در مجموعه آفیس است که در این پروژه از آن استفاده گردید.
smart tags در مجموعه آفیس برچسب‌هایی هستند که به صورت خودکار توسط یکی از محصولات آفیس مثلا ورد یا اکسل و امثال آن، پس از تشخیص یک کلمه خاص ایجاد می‌شوند و می‌توان اعمالی را به این برچسب ایجاد شده انتساب داد. برای مثال در اینجا امکان جایگزین کردن کلمه فارسی با معادل پارسی در نظر گرفته شد.
ویدیویی در مورد نحوه ایجاد اسمارت تگ‌ها در VS.Net و یا مثالی پیشرفته‌تر در مورد تشخیص دمای فارنهایت در یک متن و ایجاد smart tag مخصوص به آن برای تبدیل به سلسیوس. (از regular expressions جهت یافتن یک الگو در متن استفاده شده است)

در این پروژه، حدود 3800 واژه فارسی به‌ یک smart tag انتساب داده می‌شود (در روال استاندارد ThisAddIn_Startup). سپس در هنگام نمایش آن، معادل پارسی کلمه نیز به منوی باز شده افزوده گشته و در روال رخداد کلیک آن، تعویض کلمه تشخیص داده شده با واژه پیدا شده صورت خواهد گرفت.

در ادامه فرض بر این است که یک پروژه جدید word add-in را در VS.Net ایجاد کرده‌اید و همچنین ارجاعی را به فایل System.Data.SQLite.DLL افزوده‌اید.

using System;
using System.Diagnostics;
using Microsoft.Office.Tools.Word;
using Action = Microsoft.Office.Tools.Word.Action;

private SmartTag _st;
private void init()
{
try
{
//Enable Smart Tags in Word
if (!Application.Options.LabelSmartTags)
{
//ممکن است اسمارت تگ‌ها در ورد غیرفعال باشند. به این صورت می‌شود آنها را فعال کرد
Application.Options.LabelSmartTags = true;
}

_st = new SmartTag(@"www.microsoft.com/Demo#FarsiSmartTag", @"فارسی به پارسی");

//دریافت واژه‌های فارسی از دیتابیس و افزودن خودکار آنها به اسمارت تگ‌ها
if (!DBhelper.AddSmartTagItems(_st, "select distinct farsi from tblFarsiToParsi")) return;

Action stActions = new Action("تبدیل");//تعریف یک اکشن جدید
stActions.Click += stActions_Click;//انتساب روال‌های رخداد گردان
stActions.BeforeCaptionShow += stActions_BeforeCaptionShow;
_st.Actions = new[] { stActions };
VstoSmartTags.Add(_st);//افزودن اسمارت تگ به مجموعه
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

private void ThisAddIn_Startup(object sender, EventArgs e)
{
init();
}

دو روال رخداد گردان زیر نیز جهت تغییر عنوان پیش فرض به واژه یافته شده در لحظه نمایش منو و روال کلیک نیز ایجاد خواهد شد:

static void stActions_BeforeCaptionShow(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
string parsi = DBhelper.FindParsi(e.Text);//معادل پارسی از دیتابیس دریافت می‌شود
clickedAction.Caption = (parsi == string.Empty ? e.Text : parsi);
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

static void stActions_Click(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
e.Range.Text = clickedAction.Caption;//جایگزینی متن موجود با عنوانی که پیشتر پارسی شده است
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

نکته‌ای را که در اینجا باید حتما رعایت کرد بحث exception handling‌ است. خصوصا در روال استاندارد ThisAddIn_Startup . اگر در این روال خطایی مدیریت نشده رخ دهد، word افزودنی شما را به صورت غیرفعال به مجموعه اضافه خواهد کرد و فعال سازی بعدی آن پس از اصلاح کد واقعا مشکل خواهد بود. همانطور که ملاحظه می‌کنید تمامی خطاها در event log‌ ویندوز نوشته می‌شوند.
همچنین باید دقت داشت که اگر متغیری در سطح کلاس تعریف نشود به احتمال زیاد تا دقایقی بعد توسط garbage collector به دیار باقی خواهد شتافت (تعریف st_ در اینجا). اینجاست که شاید ساعت‌ها وقت صرف کنید که چرا روال‌های رخ‌داد گردان دیگر اجرا نمی‌شوند. چرا افزونه دیگر کار نمی‌کند.

همین! کل سورس این add-in منهای بحث دریافت اطلاعات از دیتابیس همین بود! وظیفه‌ی تشخیص کلمات معرفی شده به ms-word به‌عهده‌ی خود آن است و این‌کار را نیز به‌خوبی انجام می‌دهد. در گذشته‌های نچندان دور ایجاد یک افزونه برای word واقعا مشکل بود که با این روش بسیاری از موانع برطرف شده است.

کلاس DBHelper که کار دریافت اطلاعات واژه‌ها را از دیتابیس SQLite انجام می‌دهد به شرح زیر است:

using System;
using System.Data.SQLite;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Office.Tools.Word;

namespace Farsi2Parsi
{
class DBhelper
{
#region Methods (2)

// Public Methods (2)

public static bool AddSmartTagItems(SmartTag st, string strSQL)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
bool ret = false;
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();

if (myReader != null)
while (myReader.Read())
{
if (myReader.GetValue(0) != DBNull.Value)
st.Terms.Add(myReader.GetValue(0).ToString());
}

ret = true;
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 7);
}
finally
{
if (myReader != null)
myReader.Close();

if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}

public static string FindParsi(string farsi)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
string ret = string.Empty;
string strSQL = "select parsi from tblFarsiToParsi where farsi='" + farsi.Replace("'", "''") + "'";
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();

if (myReader != null)
{
myReader.Read(); //اولین مورد کافی است
if (myReader.GetValue(0) != DBNull.Value)
ret = myReader.GetValue(0).ToString();
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 8);
}
finally
{
if (myReader != null)
myReader.Close();

if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}
#endregion Methods
}
}

همانطور که پیشتر نیز عنوان شد اگر با ADO.net آشنایی داشته باشید، هیچ نکته‌ی خاص جدیدی را در اینجا مشاهده نخواهید کرد و تنها یک سری امور روزمره کاری با ADO.net مطرح شده است، باز کردن کانکشن، اجرای کوئری، دریافت اطلاعات و پاکسازی نهایی. (قسمت finally را با استفاده از عبارت using می‌شود حذف کرد)

هنگام نصب برنامه، مسیر پوشه نصب در رجیستری ویندوز توسط نصاب نوشته خواهد شد. از همین مورد برای ایجاد رشته اتصالی به دیتابیس استفاده گردید.

class ConStr
{
public static string ConnectionString
{
get
{
return Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\FarsiToParsi").GetValue("folder") + "\\ErrorsBank.sqlite";
}
}
}

سورس کامل این افزونه را به صورت یک پروژه VS.Net 2008 SP1 از اینجا می‌توانید دریافت کنید.
نصاب برنامه با استفاده از NSIS ایجاد شده که در روزی دیگر درباره‌ی آن توضیح خواهم داد.
اگر قصد داشته باشید از روش‌های متداول استفاده کنید، مشاهده ویدیوی زیر توصیه می‌شود:
http://msdn.microsoft.com/en-us/office/bb851702.aspx

برای توزیع این نوع افزونه‌ها علاوه بر دات نت فریم ورک، به چهار به روز رسانی دیگر نیز نیاز خواهد بود:
به روز رسانی نصاب ویندوز (که احتمالا نصب هست)
WindowsInstaller-KB893803-v2-x86.exe
Microsoft Office System Update: Redistributable Primary Interop Assemblies :
o2007pia.msi
نصب vsto و همچنین sp1 آن
vstor30.exe
vstor30sp1-KB949258-x86.exe

این موارد را من در بسته به روز رسانی سیستم قرار داده‌ام که به صورت خودکار و یکی پس از دیگری اجرا و نصب خواهند شد.
پس از آن با کلیک بر روی فایلی با پسوند vsto که در پوشه build برنامه موجود است، می‌توان افزونه را نصب کرد (click once installation).




سایر اطلاعات در مورد پروژه‌های VSTO را می‌توان از طریق وبلاگ رسمی آنها دنبال کرد:
http://blogs.msdn.com/vsto/

ایده‌های دیگری را هم در همین رابطه می‌توان پیاده سازی کرد. برای مثال درست کردن یک افزونه برای بررسی آئین نگارش فارسی در متون word. دقیقا با همین روش قابل پیاده سازی است و یا ایجاد غلط یاب بهتری نسبت به آن‌چه که هم اکنون برای آفیس 2003 توسط مایکروسافت ارائه شده است (این غلط یاب با صفحه کلید استاندارد تایپ ایران همخوانی ندارد، به همین جهت با استقبال نیز مواجه نشد).


اشتراک‌ها
انتشار EF6.1.3 RTM
EF6.1.3 just contain fixes to high priority issues that have been reported on the 6.1.2 release. The fixes include
Query: Regression in EF 6.1.2: OUTER APPLY introduced and more compex queries for 1:1 relationships and "let" clause
TPT problem with hiding base class property in inherited class
DbMigration.Sql fails when the word 'go' is contained in the text
Create compatibility flag for UnionAll and Intersect flattening support
Query with multiple Includes does not work in 6.1.2 (working in 6.1.1)
"You have an error in your SQL syntax" after upgrading from EF 6.1.1 to 6.1.2
انتشار EF6.1.3 RTM
مطالب
سرورهای متصل شده‌ی SQL Server و مبحث تراکنش‌ها

یکی از قابلیت‌های جالب SQL Server در یک شبکه محلی امکان link و اتصال آن‌ها به یکدیگر است. به این صورت امکان کوئری گرفتن (و یا اعمال متداول SQL ایی) از دو یا چند سرور مختلف با دستورات T-SQL میسر می‌شود؛ به نحوی که حس یکپارچگی دیتابیس‌های این سرورها را حین کوئری نوشتن خواهیم داشت.
برای مثال فرض کنید دو سرور SQL1 و SQL2 را در شبکه داریم. می‌خواهیم در سرور SQL1 اتصالی را به سرور SQL2 ایجاد کنیم.

USE master

EXEC sp_addlinkedserver
'SQL2',
N'SQL Server'

sp_addlinkedsrvlogin @useself='false ', @rmtsrvname = 'SQL2',
@rmtuser = 'sa',
@rmtpassword = 'pass#'

دستورات T-SQL فوق کار ثبت یک liked server جدید و اعمال مشخصات کاربری که توسط آن قرار است به سرور SQL2 دسترسی داشت، انجام می‌دهند.
اکنون جهت بررسی این اتصال در سرور SQL1 کوئری زیر را اجرا می‌کنیم:

select * from sql2.faxManager.dbo.tblErja

که نحوه‌ی فراخوانی جدول مورد نظر باید به صورت Server.DatabaseName.dbo.TableName در آن رعایت شود.
تا اینجا همه چیز خوب است. مشکل از زمانی شروع می‌شود که بخواهیم تراکنش‌ها را نیز دخالت دهیم و اصولی کار کنیم. برای مثال:

begin distributed tran
select * from sql2.faxManager.dbo.tblErja
commit tran

خطایی که در ویندوز سرور 2003 با آخرین به روز رسانی‌ها ظاهر می‌شود به صورت زیر است:

The operation could not be performed because OLE DB provider for linked server was unable to begin a distributed transaction.
OLE DB provider for linked server returned message "The partner transaction manager has disabled its support for remote/network transactions.".


به صورت پیش فرض این نوع تراکنش‌های توزیع شده غیرفعال هستند مگر اینکه فعال شوند و روش حل مشکل نیز به صورت زیر می‌باشد:
قبل از هر کاری به کنسول سرویس‌های ویندوز مراجعه کرده و از در حال اجرا بودن سرویس Distribute Transaction Coordinator اطمینان حاصل کنید.
سپس به قسمت زیر مراجعه نمائید:
Control Panel > Administrative Tools > Component Services


نود مربوط به Component Service را گشوده و سپس بر روی My Computer کلیک راست کرده و گزینه‌ی خواص را انتخاب کنید.
در صفحه‌ی بازه شده به برگه‌ی MSTDC مراجعه کرده و بر روی دکمه‌ی Security Configuration کلیک نمائید.
اکنون تنظیمات آن‌را مطابق شکل زیر تغییر دهید.


این تنظیم باید بر روی هر دو سرور SQL1 و SQL2 انجام شود.

پس از این تغییرات که شامل راه اندازی مجدد سرویس Distribute Transaction Coordinator نیز خواهد شد، مشکل خطای فوق برطرف شده و امکان استفاده از تراکنش‌ها در linked servers نیز میسر می‌شود.

مشکل دیگری که به آن برخوردم خطای زیر است:

Unable to start a nested transaction for OLE DB provider for linked server . A nested transaction was required because the XACT_ABORT option was set to OFF.
OLE DB provider for linked server returned message "Cannot start more transactions on this session.".


برای حل این مشکل یک سطر زیر را باید به ابتدای کوئری خود اضافه کرد که جزو الزامات تراکنش‌های توزیع شده است و به این صورت از rollback کامل تمامی دستورات موجود فراخوانی شده T-SQL در صورت بروز کوچکترین خطایی اطمینان حاصل می‌کند:
SET XACT_ABORT ON


برای مطالعه بیشتر:
MSDTC Troubleshooting

اشتراک‌ها
دوره آموزشی Blazor

Welcome to this short introduction to Blazor! This new Microsoft framework uses a unique approach to leverage your existing C# and .NET skills to create single-page applications running in web browsers. The technology that makes this possible is called WebAssembly, an open standard supported directly by current browsers on desktop and mobile platforms. You write C# and Razor code instead of JavaScript, and the compiled app runs natively on the client.

Sample Source Code: https://github.com/DevExpress/blazor-training-samples  

دوره آموزشی Blazor
نظرات مطالب
استفاده از چندین Context در EF 6 Code first
- در SQL Server قابلیتی به نام Linked servers وجود دارد که توسط آن در یک شبکه داخلی می‌شود چندین بانک اطلاعاتی SQL Server را در نودهای مختلف شبکه به هم متصل کرد و با آن‌ها یکپارچه و مانند یک دیتابیس واحد کار کرد. این مورد در برنامه‌های سازمانی خیلی مرسوم است. قرار نیست به ازای هر برنامه‌ای که برای یک سازمان نوشته می‌شود، هر کدام جداگانه بانک اطلاعاتی کاربران و لاگین خاص خودشان را داشته باشند. عموما یک دیتابیس مرکزی مثلا مدیریت منابع انسانی وجود دارد که مابقی برنامه‌ها را تغذیه می‌کند. حتی می‌شود به یک بانک اطلاعاتی MySQL هم متصل شد (^).
- ORMها صرفا کارهایی را قادر به انجام هستند که بانک اطلاعاتی مورد استفاده پشتیبانی می‌کند. برای نمونه در SQL Server امکان تهیه رابطه بین دو جدول از دو بانک اطلاعاتی مختلف وجود ندارد. منظور مثلا ایجاد کلید خارجی بین جداول دو بانک اطلاعاتی مختلف است و نه نوشتن کوئری بین آ‌ن‌ها که از این لحاظ مشکلی نیست.
A FOREIGN KEY constraint can reference columns in tables in the same database or within the same table
- هدف از پشتیبانی چند Context در EF 6، تلفیق این‌ها با هم در قالب یک بانک اطلاعاتی است (مطلب فوق).
- همچنین در EF 6 می‌توان چندین Context را به چندین بانک اطلاعاتی مختلف با رشته‌های اتصالی متفاوت، انتساب داد. مباحث آغاز بانک‌های اطلاعاتی هر کدام جداگانه عمل کرده و مستقل از هم عمل می‌کنند.
یک مثال جهت اجرا و آزمایش:
Sample25.cs
- اگر می‌خواهید به انعطاف پذیری Linked servers برسید (مثلا در طی یک کوئری و نه چند کوئری از جداول دو بانک اطلاعاتی مختلف در دو سرور متفاوت کوئری بگیرید)، نیاز خواهید داشت مثلا View یا SP تهیه کنید و سپس این‌ها را در برنامه مورد استفاده قرار دهید. Viewها با استفاده از T-SQL می‌توانند کوئری واحدی از چند بانک اطلاعاتی تهیه کنند. اینبار برنامه هم نهایتا به یک بانک اطلاعاتی متصل می‌شود و برای آن اهمیتی ندارد که View یا SP به چه نحوی تهیه شده و با چند بانک اطلاعاتی کار می‌کند.
- تراکنش‌های توزیع شده هم نیاز به تنظیمات خاصی در SQL Server دارند و  باید MSDTC راه اندازی و تنظیم شود: (^). در غیراینصورت پیام خطای The underlying provider failed on Open. MSDTC on server is unavailable را دریافت خواهید کرد. بعد از آن باید از TransactionScope برای کار همزمان با چند Context استفاده کنید.
اشتراک‌ها
TypeScript 1.8 منتشر شد

TypeScript 1.8 provides full support for module augmentation, delivers a stronger type system with string literal types, and catches even more common bugs with smarter control flow analysis. 

TypeScript 1.8 منتشر شد
اشتراک‌ها
نسخه RTM برای 1.0 ASP.NET Core ارایه شد

We are excited to announce the release of .NET Core 1.0, ASP.NET Core 1.0 and Entity Framework 1.0, available on Windows, OS X and Linux! .NET Core is a cross-platform, open source, and modular .NET platform for creating modern web apps, microservices, libraries and console applications.

This release includes the .NET Core runtime, libraries and tools and the ASP.NET Core libraries. We are also releasing Visual Studio and Visual Studio Code extensions that enable you to create .NET Core projects. You can get started at https://dot.net/core. Read the release notes for detailed release information. 

نسخه RTM برای 1.0 ASP.NET Core ارایه شد
مطالب
مرتب‌سازی، فیلتر کردن و صفحه‌بندی اطلاعات در ASP.NET Core

مقدمه

اگر با Apiها کار کرده باشید احتمالاً با این چالش که گاهی نیاز است منابعی (Resources) که به کاربر ارسال می‌شوند مرتب (Sort)، بر اساس درخواست کاربر فیلتر (Filter) و در صفحه‌بندی (Paging) مشخصی تحویل داده شوند، برخورد کرده‌اید. این نیاز خصوصاً در پاسخ (Response) با روش GET از استاندارد HTTP مشهود است. در این مطلب به معرفی کتابخانه‌ای می‌پردازیم که با استفاده از آن می‌توان عملیات فوق را پیاده‌سازی نمود. Sieve یک چارچوب (Framework) ساده، تمیز و قابل توسعه برای NET Core. است. در زمان نگارش این مقاله ویرایش ۲.۱.۳ از این کتابخانه در دسترس است و همانگونه که اشاره شد، این کتابخانه منبع باز (Open Source) بوده و می‌توانید آن را از مخزن گیت‌هاب در این پیوند دریافت نمایید.
  
سیستمی با یک موجودیت به نام "پست" (Post) مفروض است. با استفاده از کتابخانه Sieve عملیات مرتب‌سازی، فیلتر و صفحه‌بندی را هنگام درخواست (GET) تمامی پست‌ها اعمال خواهیم کرد.
// Post

public int Id { get; set; }

public string Title { get; set; }

public int LikeCount { get; set; }

public int CommentCount { get; set; }

public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;

۱. نصب کتابخانه

ابتدا لازم است از طریق Package Manager Console و اجرای دستور فوق اقدام به نصب این کتابخانه نمایید:  Install-Package Sieve -Version 2.1.3

۲. اضافه کردن سرویس‌

در فایل Startup.cs سرویس SieveProcessor را تزریق کنید:
services.AddScoped<SieveProcessor>();
 

۳. تعیین ویژگی‌هایی از کلاس برای اعمال مرتب‌سازی و فیلتر

باید ویژگی‌هایی (Properties) از کلاس را که می‌خواهید اعمال مرتب‌سازی و فیلتر بر روی آن‌ها انجام شوند، مشخص کنید. به دو روش این امر ممکن است:
 

۱.۳. از طریق اضافه کردن صفت (Attribute) به ویژگی‌ها

تنها ویژگی‌هایی از کلاس که دارای صفت [(Sieve(CanSort = true, CanFilter = true] باشند، می‌توانند مرتب و یا فیلتر شوند (می‌توان تنها از یکی از آن‌ها نیز استفاده نمود).
لذا کلاس پست به صورت زیر ویرایش می‌شود:
// Post

public int Id { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public string Title { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public int LikeCount { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public int CommentCount { get; set; }

[Sieve(CanFilter = true, CanSort = true, Name = "created")]
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;

 

۲.۳. از طریق Fluent API

برای استفاده از این روش، ابتدا کلاسی را ایجاد و از کلاس SieveProcessor مشتق کنید. سپس تابع MapProperties موجود در کلاس والد را override کنید.
// ApplicationSieveProcessor

public class ApplicationSieveProcessor : SieveProcessor
{
    public ApplicationSieveProcessor(
        IOptions<SieveOptions> options, 
        ISieveCustomSortMethods customSortMethods, 
        ISieveCustomFilterMethods customFilterMethods) 
        : base(options, customSortMethods, customFilterMethods)
    {
    }

    protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
    {
        mapper.Property<Post>(p => p.Title)
            .CanFilter()
            .HasName("a_different_query_name_here");

        mapper.Property<Post>(p => p.CommentCount)
            .CanSort();

        mapper.Property<Post>(p => p.DateCreated)
            .CanSort()
            .CanFilter()
            .HasName("created_on");

        return mapper;
    }
}
حال باید کلاس جدید را تزریق نمایید:
services.AddScoped<ISieveProcessor, ApplicationSieveProcessor>();
در هر دو روش پارامتری دیگر با نام "Name" نیز وجود دارد که می‌توانید با استفاده از آن برای هر ویژگی، نامی غیر از نام اصلی آن را اتخاذ نمایید.
 

۴. دریافت پرس‌و‌جوهای (Queries) مرتب/فیلتر/صفحه‌بندی با اضافه کردن SieveModel به کنترلر (Controller)

برای دریافت پرس‌و‌جوهای مرتب/فیلتر/صفحه‌بندی، SieveModel را به اکشنی (Action) که پست‌ها را برگشت می‌دهد به عنوان پارامتر اضافه کنید. سپس با فراخوانی تابع Apply با استفاده از تزریق SieveProcessor در کنترلر خود، پرس‌و‌جوها را به منابع خود اعمال کنید.
[HttpGet]
public JsonResult GetPosts(SieveModel sieveModel) 
{
    var result = _dbContext.Posts;
    result = _sieveProcessor.Apply(sieveModel, result);
    return Json(result.ToList());
}
توجه داشته باشید مقادیر پرس‌و‌جوها اختیاری است و هر کدام می‌توانند به تنهایی و یا با هم مورد استفاده قرار گیرند.
 

۵. ارسال درخواست

با تمام موارد گفته شده، اکنون می‌توانید درخواستی را برای دریافت (GET) شامل پرس‌و‌جوهای مرتب/فیلتر/صفحه‌بندی ارسال نمایید. برای مثال:
GET /GetPosts

?sorts=     LikeCount,CommentCount,-created         // sort by likes, then comments, then descendingly by date created 
&filters=   LikeCount>10,Title@=awesome title,      // filter to posts with more than 10 likes, and a title that contains the phrase "awesome title"
&page=      1                                       // get the first page...
&pageSize=  10                                      // ...which contains 10 posts
sorts= LikeCount,CommentCount,-created ?: مرتب‌سازی بر اساس تعداد محبوبیت، سپس تعداد نظرات و در آخر تاریخ ثبت پست به صورت نزولی.
filters= LikeCount>10,Title@=awesome title &: فیلتر بر اساس پست‌هایی که تعداد محبوبیت آن‌ها بیش از ۱۰ است و در عنوان خود شامل عبارت "awesome title" می‌باشند.
page=1 &: صفحه اول ...
pageSize=10 &: ... که شامل ۱۰ پست است.

به صورت رسمی‌تر:
sorts: فهرست دستورالعمل‌هایی شامل نام ویژگی‌هایی است که مرتب‌سازی بر روی آن‌ها اعمال می‌شود و از طریق کاما (,) از یکدیگر تمایز داده می‌شوند. با اضافه کردن - قبل از نام ویژگی، آن را به صورت نزولی مرتب نمایید.
  • filters: دستورالعمل‌های جدا شده توسط کاما (,) به صورت {Name}{Operator}{Value} که در آن:
    • {Name} نام ویژگی‌ای است که صفت Sieve بر روی آن تعریف شده و یا نام سفارشی‌ای است که کاربر تعیین کرده است.
      • همچنین می‌توانید بیش از یک نام (برای یای منطقی (OR)) در درون جفت پرانتز باز و بسته و جداکننده یای منطقی (|) داشته باشید. برای مثال: LikeCount|CommentCount)>10) مشخص می‌کند مقدار LikeCount و یا CommentCount بیش از ۱۰ باشد.
    • {Operator} یکی از عملگرهای ممکن است.
    • {Value} مقداری است که در عمل فیلتر مورد استفاده قرار می‌گیرد.
  • page: شماره صفحه‌ای است که برگشت داده می‌شود.
  • pageSize: تعداد مواردی است که در هر صفحه برگردانده خواهد شد.
 

۶. عملگرها (Operators)

عملگر
توضیحات
عملگر
توضیحات
== برابر =@  شامل
=! مخالف
=_  شروع شود با
< بزرگ‌تر
*=@  شامل (حساس به حروف)*
> کوچک‌تر
*=_  شروع شود با (حساس به حروف)
=< بزرگ‌تر مساوی
*==  برابر (حساس به حروف)
=> کوچک‌تر مساوی

 
* حساس به بزرگی و کوچکی حروف

۷. پیکربندی

برای پیکربندی شامل مواردی چون حساس به بزرگ و کوچک بودن نام ویژگی، تعداد صفحات پیشفرض، حداکثر تعداد صفحه مجاز و نحوه برخورد با نام ویژگی ناموجود در ویژگی‌های کلاس ابتدا قطعه زیر را به appsettings اضافه کنید.
{
    "Sieve": {
        "CaseSensitive": "boolean: should property names be case-sensitive? Defaults to false",
        "DefaultPageSize": "int number: optional number to fallback to when no page argument is given. Set <=0 to disable paging if no pageSize is specified (default).",
        "MaxPageSize": "int number: maximum allowed page size. Set <=0 to make infinite (default)",
        "ThrowExceptions": "boolean: should Sieve throw exceptions instead of silently failing? Defaults to false"
    }
}

 سپس سرویس فوق را در Startup.cs اضافه کنید:
services.Configure<SieveOptions>(Configuration.GetSection("Sieve"));