پایان پروژه ASP.NET Ajax Control Toolkit !
هدف مایکروسافت از اینکار مدیریت هر دو پروژه MVC و Web forms است آن هم با هزینه کم، کیفیت بالا و سازگار با تمام مرورگرها.
ضمنا این رو در نظر باشید که یکی از توانمندیهای jQuery، Ajax است (از کار با DOM گرفته تا دستکاری CSS نمایش داده شده، تا Animation ، مدیریت سادهتر رخدادها، اعمال قالب به سایت و غیره) و این مورد مزیت مهمی است نسبت به تمام کتابخانههایی که فقط برای یک کار و آن هم سهولت تولید برنامههای مبتنی بر Ajax ایجاد شدهاند و از چند مشکل مهم رنج میبرند:
- تک کارهاند. فقط Ajax .
- مشکل سازگاری با مرورگرهای مختلف را دارند.
- به صورت فعال توسعه داده نمیشوند؛ رفع باگ نمیشوند و غیره. برای مثال فواصل به روز رسانی همان Anthem.Net را بررسی کنید.
- توسعه پذیر نیستند. برای مثال آیا میتوان برای Anthem.Net افزونه نوشت؟
- حجم بالایی دارند.
- سرعت پایینی دارند.
jQuery در مورد تمام موارد عنوان شده حرف برای گفتن دارد از حجم کم تا سرعت بالاتر نسبت به اکثر کتابخانههای جاوا اسکریپتی دیگر تا توسعهی منظم، سازگاری عالی با مرورگرها، توسعه پذیری و صدها و هزاران افزونهی مهیا برای آن و غیره.
و RAD هزینه بر است. یعنی چی؟ یعنی حجم بالای کدهای اسکریپتی که باید به برنامهی شما مثلا توسط ASP.NET Ajax تزریق شود که مبادا شما بخواهید دست خودتان را به نوشتن چند سطر کد جاوا اسکریپتی آلوده کنید. همچنین حجم تبادل اطلاعات ASP.NET Ajax را هم که مبتنی است بر RAD را هم با حجم اطلاعات مبادله شده توسط jQuery مقایسه کنید (با پلاگین فایرباگ مربوط به فایرفاکس). این حجم واقعا زیاد است و قابل مقایسه نیست. (تمام اینها هزینههای RAD است)
ضمنا وجود 100 ها افزونه و پلاگین نوشته شده برای jQuery کار شما را بسیار بسیار ساده میکنند، مانند پاسخ قبلی من در این مطلب.
فقط باید کمی وقت بگذارید و چیزی را بیاموزید که واقعا ارزش دارد. گیرم فردا نخواستید با ASP.NET کار کنید. تمام این اطلاعات در PHP هم به درد شما میخورد، چون قسمت سمت کلاینت آنچنان تفاوتی نمیکند و jQuery یک کتابخانهی سمت کلاینت است.
<Button Content="RemoveItem" Command="{Binding RemoveItemCommand}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>Command تعریف شده در Button مورد نظر به خاصیتی به نام RemoveItemCommand در BookViewModel که نوع آن ICommand است اشاره میکند. پس باید تغییرات زیر را در ViewModel اعمال کنیم:
public ICommand RemoveItemCommand { get; set; }
public Book CurrentItem { get { return currentItem; } set { if(currentItem != value) { currentItem = value; RaisePropertyChanged("CurrentItem"); } } } private Book currentItem;
همان طور که در پست قبلی توضیح داده شد پیاده سازیها تعاریف ViewModel در Controller انجام میگیرد برای همین منظور باید تعریف DelegateCommand که یک پیاده سازی خاص از ICommand است در کنترلر انجام شود. :
[Export] public class BookController { [ImportingConstructor] public BookController(BookViewModel viewModel) { ViewModelCore = viewModel; } public BookViewModel ViewModelCore { get; private set; } public DelegateCommand RemoveItemCommand { get; private set; } private void ExecuteRemoveItemCommand() { ViewModelCore.Books.Remove(ViewModelCore.CurrentItem); } private void Initialize() { RemoveItemCommand = new DelegateCommand(ExecuteRemoveItemCommand); ViewModelCore.RemoveItemCommand = RemoveItemCommand; } public void Run() { var result = new List<Book>(); result.Add(new Book { Code = 1, Title = "Book1" }); result.Add(new Book { Code = 2, Title = "Book2" }); result.Add(new Book { Code = 3, Title = "Book3" }); Initialize(); ViewModelCore.Books = new ObservableCollection<Models.Book>(result); (ViewModelCore.View as IBookView).Show(); } }
تغییرات:
»خاصیتی به نام RemoveItemCommand که از نوع DelegateCommand است تعریف شده است؛
»متدی به نام Initialize اضافه شد که متدهای Execute و CanExecute برای Commandها را در این قسمت رجیستر میکنیم.
»در نهایت Command تعریف شده در کنترلر به Command مربوطه در ViewModel انتساب داده شد.
حال کافیست خاصیت SelectedItem دیتاگرید BookShell به خاصیت CurrentItem موجود در ViewModel مقید شود:
<DataGrid ItemsSource="{Binding Books}" SelectedItem="{Binding CurrentItem ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="400" Height="200"> <DataGrid.Columns> <DataGridTextColumn Header="Code" Binding="{Binding Code}" Width="100"></DataGridTextColumn> <DataGridTextColumn Header="Title" Binding="{Binding Title}" Width="300"></DataGridTextColumn> </DataGrid.Columns> </DataGrid>
قبل از آن بد نیست که بدانید چرا این ابزار T4 نام گرفته !
T4 مخفف Text Template Transformation Toolkit میباشد (TTTT). شکل زیر مراحل اجرای یک کد Text Template را توسط T4 نشان میدهد:
برای آزمایش، یک فایل متنی کنار فایل TextTransform.exe با نام Text2.tt ایجاد نمایید و کد زیر را در داخل آن بنویسید:
<#@ template debug="true" hostspecific="false" language="C#" #> <#@ output extension=".txt" #> <#@ import namespace="System.Diagnostics" #> Report In : <#= DateTime.Now #> <# Process[] Procs = Process.GetProcesses(); for (int i = 0; i < Procs.Length; i++) { string Pstr = Procs[i].ProcessName + " -|- " + Procs[i].Id + Environment.NewLine ; #><#= Pstr #><# } #>
برای تولید فایل خروجی، دستور زیر را در cmd.exe اجرا کنید :
نکته: اگر User شما به این پوشه دسترسی ندارد و کاربر Admin نیستید احتمالا به مشکل بر میخورد. میتوانید فایل TextTransform.exe را در مکان دیگری قرار دهید و دستور را از آن محل اجرا کنید و یا برای پوشهی مذکور دسترسی ایجاد نمایید.
اگر میخواهید بیشتر در مورد معماری T4 بدانید بهتر است مقاله زیر را مطالعه کنید:
http://www.olegsych.com/2008/05/t4-architecture/
نکته دیگر این که برای Visual Studio، ابزارهایی جهت بهبود کار با Text Templateها وجود دارند که با جستجوی T4 Editor، نمونههایی از آنها را خواهید یافت. tangible T4 Editor نمونه ای از این Pluginها میباشد که به Visual Studio افزوده میگردد و یا یک پروژه Open Source هم برای آشنایی بسیار بیشتر با T4 در t4toolbox.codeplex.com وجود دارد که میتوانید مشاهده کنید.- CUME_DIST:
CUME_DIST( ) OVER ( [ partition_by_clause ] order_by_clause )
Create Table TestCUME_DIST (SalesOrderID int not null, OrderQty smallint not null, ProductID int not null ); GO Insert Into TestCUME_DIST Values (43663,1,760),(43667,3,710),(43667,1,773), (43667,1,775),(43667,1,778),(43669,1,747), (43670,1,709),(43670,2,710),(43670,2,773),(43670,1,776)
SELECT SalesOrderID, OrderQty, CUME_DIST() OVER(ORDER BY SalesOrderID) AS [CUME_DIST] FROM TestCUME_DIST ORDER BY [CUME_DIST] DESC
*** برای بدست آوردن CUME_DIST سطر پنجم نیز خواهیم داشت:
Rows=(c1+c2)/c3 بنابراین خواهیم داشت: 0/6=10/(5+1)=Rows
مثال دوم : ابتدا Script زیر را اجرا نمایید:
SELECT SalesOrderID, OrderQty, ProductID, CUME_DIST() OVER(PARTITION BY SalesOrderID ORDER BY ProductID ) AS [CUME_DIST] FROM TestCUME_DIST WHERE SalesOrderID IN (43670, 43669, 43667, 43663) ORDER BY SalesOrderID DESC, [CUME_DIST] DESC
همانگونه که ملاحظه میکنید، در این مثال، خروجی، براساس SalesOrderID به چهار گروه تقسیم میشود و عملیات مرتب سازی روی فیلد ProductID انجام می گیرد، بنابراین CUME_DIST، روی هر گروه بر روی فیلد ProductID محاسبه میشود.
گروه اول : نحوه محاسبه Cume_DIST سطر اول:
سوال:چه تعداد از مقادیر ProductID آن برابر 776 میباشد؟
جواب: فقط مقدار سطر اول، بنابراین خواهیم داشت C1=1
سوال: چه تعداد از مقادیر کوچکتر از ProductID=776 میباشد؟
جواب: مقدار سه سطر، در واقع مقادیر سطر دوم،سوم و چهارم کوچکتر از مقدار سطر اول میباشند، c2=3
سوال: تعداد کل سطرهای گروه اول چه مقدار میباشد؟
جواب: 4سطر
بنابراین برای بدست آوردن CUME_DIST سطر اول خواهیم داشت:
1=4/(1+3)=Rows
محاسبه سطر دوم از گروه اول بدون شرح:
0/75=4/(1+2)=Rows
امیدوارم مفید واقع شده باشد.
- MICROSOFT FOCUS - دریافت برنامه Process Explorer 15.1 | microsoft-focus.blogfa.com
- چگونه در یک فرم MVC مانع حملات از نوع CSRF شویم؟ - بازار آی تی | itbazaar.persianblog.ir
- مجموعه مقالات مفید برنامه نویسی برای دانلود - برنامه نویسی به زبان سی شارپ | csharpdotnet.blogsky.com
- Google Trends: v.p.n | www.google.com
- MonoGame - Write Once, Play Everywhere | monogame.codeplex.com
- FxCop for stylesheets | madskristensen.net
- Go To Definition for JavaScript Functions in Visual Studio 2011 | dailydotnettips.com
- WCF RIA Services V1.0 SP2 | www.microsoft.com
- تهیه فید از گوگل پلاس | pipes.yahoo.com
- در مورد jQuery Plugins Site | blog.jquery.com
- لیست کتابخانههایی که توسط آنها در دات نت میتوان PDF تولید کرد | stackoverflow.com
- لیستی از ORMهای قابل استفاده در دات نت | en.wikipedia.org
خواندنیهای 23 تیر
اس کیوال سرور
امنیت
دات نت فریم ورک
دبلیو پی اف و سیلور لایت
سی و مشتقات
شیرپوینت
متفرقه
محیطهای مجتمع توسعه
مرورگرها
پی اچ پی
اندازه گیری دما، مختصات جغرافیایی، لرزه یا تکانه و تنظیم نمودن هشدار دهنده توسط NET Micro Framework
جلوگیری از ارسال Spam در ASP.NET MVC
- این برنامهها، user agentهای متفاوتی را به ازای هر درخواست ارسال میکنند (عموما). بنابراین مورد دوم هم علاوه بر مورد سوم نباید بکار گرفته شود.
- دو نوع هش در حالت کلی وجود دارند. هشهای سریع و هشهای امن. هشهای امن سعی میکنند این تضمین را ارائه دهند که به ازای یک ورودی مشخص، خروجی منحصربفردی را تولید کنند؛ اما ... با قیمت کندتر بودن عملیات هش. هشهای سریع، مانند xxHash، برای یک چنین مواردی که نیاز هست کلید کش تولید شود بکار گرفته میشوند. الزاما مانند هشهای امن سعی در تولید خروجیهای منحصربفردی نمیکنند، اما تا این اندازه دقیق هستند که در بانکهای اطلاعاتی key-value store فوق سریعی مانند Redis از آنها استفاده میشود. بنابراین در یک چنین مواردی مانند سناریوی جاری بهتر است از هشهای سریع استفاده شود. البته اگر آدرس صفحه و همچنین UA را حذف کنیم، نیازی به هش کردن نخواهد بود؛ چون IP را میتوان بعنوان کلید درنظر گرفت.
- بررسی UA از دیدگاه دیگری به صورت جداگانه میتواند مفید باشد. تشخیص باتهای شناخته شده و بستن دسترسی آنها.
class Visitor { visit(item){} } class BookVisitor extends Visitor { visit(book) { var cost=0; if(book.getPrice() > 50) { cost = book.getPrice()*0.50 } else{ cost = book.getPrice() } console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); return cost; } } class Book{ constructor(id,name,price){ this.id = id this.name = name this.price = price } getPrice(){ return this.price } getName(){ return this.name } getID(){ return this.id } accept(visitor){ return visitor.visit(this) } } var visitor = new BookVisitor() var book1 = new Book("#1234","lordOftheRings",80) book1.accept(visitor)
class Book{ constructor(id,name,price){ this.id = id this.name = name this.price = price } //code... }
- id
- name
- price
getPrice(){ return this.price } getName(){ return this.name } getID(){ return this.id }
accept(visitor){ return visitor.visit(this) }
class Visitor { visit(item){} }
class BookVisitor extends Visitor { visit(book) { var cost=0; if(book.getPrice() > 50) { cost = book.getPrice()*0.50 } else{ cost = book.getPrice() } console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); return cost; } }
- زمانیکه نیاز است عملیاتی مشابه، بر روی شیءهای متفاوتی از یک data structure انجام شود.
- زمانیکه نیاز است عملیاتی خاص، بر روی شیءهای متفاوتی از data structure انجام شود.
- زمانیکه میخواهید توسعه پذیری را برای کتابخانهها (libraries) یا فریم ورکها (frameworks) اضافه کنید.