1- نیاز به تواناییهای موجود در برنامههای Desktop را دارید اما همچنین نیاز است تا آنها را تحت وب نیز ارائه دهید.
یکی از دلایل اقبال به برنامههای تحت وب در سازمانها عدم نیاز به نصب آنها و توزیع هر چه سادهتر اینگونه برنامهها در شبکه است. تنها کافی است چند فایل را بر روی سرور به روز رسانی کنید و پس از آن تمام کلاینتها از آخرین نگارش برنامه شما بهرهمند خواهند شد (+). توزیع برنامههای سیلورلایت نیز به همین منوال است. علاوه بر آن استفاده از فناورهایی مانند MEF امکان ماژولار ساختن برنامه و دریافت آخرین ماژولهای تهیه شده (فایلهای XAP مجزای از برنامه به صورت افزونه) را بر اساس انتخاب و سطح دسترسی کاربر نیز میسر میسازد.
2- نیاز است تا یک برنامهی گرافیکی تمام عیار را تحت وب ارائه دهید.
تواناییهای XAML به همراه یکی از زبانهای دات نت جهت خلق جلوههای بصری، پویانمایی و گرافیکی بسیار بسیار فراتر از کتابخانههای جاوا اسکریپتی موجود هستند و نکتهی مهم آنها هم این است که لازم نیست حتما یک متخصص مثلا جاوا اسکریپت باشید تا بتوانید برای مثال پویانمایی را ارائه دهید. امکان استفاده از انواع و اقسام قلمها و قرار دادن آنها در برنامه، امکان استفاده از گرافیک برداری و غیره را نیز لحاظ کنید.
3- برنامهی شما نیاز است تا از طریق وب توزیع شود اما نیاز به سطح دسترسی بیشتری نسبت به یک برنامهی وب معمولی دارد.
تمام برنامههای توزیع شده از طریق مرورگرها محدود به سطوح دسترسی آنها نیز هستند. اما امکان نصب خارج از مرورگر برنامههای سیلورلایت نیز وجود دارد. در این حالت میتوان در صورت نیاز و همچنین تائید صریح کاربر، به سطوح دسترسی بیشتری دست یافت. برای مثال دسترسی به اسکنر در یک برنامهی وب متداول بیمعنا است. اما سیلورلایت 4 در حالت اجرای در خارج از مرورگر امکان تعامل با اشیاء COM را نیز دارد.
4- برنامهی وب شما نیاز است تا مدت زمان زیادی فعال باقی بماند.
یک برنامه دریافت ایمیل یا یک برنامه مونیتورینگ را در نظر بگیرید. اینگونه برنامهها باید مرتبا بدون نیاز به دخالت کاربر، فعال باقی بمانند و با سرور ارتباط داشته باشند. نوشتن اینگونه برنامهها با HTML و جاوا اسکریپت و فناوریهای مشابه واقعا مشکل بوده و نیاز به دانش فنی بالایی دارند. اما این مساله و حیات یک برنامه سیلورلایت تا زمانیکه مرورگر بسته نشده است جزو خواص اولیه اینگونه برنامهها است.
5- از مشکلات مدیریت حالت در برنامههای متداول وب به تنگ آمدهاید.
اگر برای مثال برنامه نویس ASP.NET باشید حتما با مباحث State management آشنایی دارید (از سشن و کوکی گرفته تا ViewState (ایی که همه به نحوی قصد کوچک کردن آنرا دارند!) و غیره). تمام اینها هم برای این است که بتوان تجربهی کاری برنامههای دسکتاپ را در محیط مرورگرها شبیه سازی کرد. این مشکلات در سیلورلایت حل شده است. یک برنامهی سیلورلایت State full است نه Stateless . همچنین اگر از حافظهای هم استفاده میکند این مورد در سمت کاربر است و نه سمت سرور و نه منقضی شدن زود هنگام سشنها و صدها ترفند برای مقیاس پذیری همین مسالهی بسیار کوچک با تعداد کاربران بالا در برنامههای متداول وب.
به عبارتی تصور کنید که برنامهی دسکتاپ سالهای قبل شما هم اکنون داخل مرورگر دارد اجرا میشود و چیزی به نام وب سرور وجود ندارد که پس از نمایش صفحهی وب شما، کلیهی اشیاء مرتبط با آنرا در سمت سرور تخریب کند چون باید پاسخگوی کاربران همزمان بیشماری باشد و منابع سرور هم محدود است. (سیلورلایت یک فناوری سمت کاربر است. بنابراین وب سرور صرفا نقش توزیع آنرا به عهده دارد یا حداکثر ارائهی یک وب سرویس جهت تعاملات بعدی مانند کار با بانک اطلاعاتی)
6- نیاز دارید تا برنامهی وب شما تحت تمام مرورگرها به یک شکل به نظر برسد و همچنین رفتار یکسانی هم داشته باشد.
هیچ وقت روزی را فراموش نمیکنم که حین پرداخت الکترونیکی بانک XYZ به کمک مرورگر فایرفاکس، دکمهی پرداخت در مرحلهی آخر، کار نمیکرد! هر چقدر روی آن کلیک میکردم اتفاقی نمیافتاد! تراکنش برگشت خورد و همین خرید ساده با مرورگر IE به سادگی انجام شد.
با سیلورلایت این مشکلات را نخواهید داشت زیرا کار نمایش برنامه شما توسط افزونهی مربوطه صورت میگیرد و این افزونه مستقل است از نوع مرورگر شما.
7- نیاز است برنامهی وب شما در حالت آفلاین هم کار کند.
برنامههای سیلورلایت تنها زمانیکه نیاز به دریافت یا ثبت اطلاعاتی از سرور داشته باشند، باید آنلاین باشند. همچنین این برنامهها دسترسی به مفهوم جدیدی به نام Isolated Storage دارند که در آن میتوان اطلاعات را به ازای هر کاربر آن هم با ضریب امنیتی بالا بر روی هارد شخص ذخیره کرد و زمان آنلاین شدن برنامه آنها را به سرور انتقال داد.
8- برنامه وب شما نیاز است تا با فایلهای مالتی مدیا تعامل داشته و آنها را پخش کند.
حتی تگ Video در HTML5 نیز به پای تواناییهای مالتی مدیا در Silverlight مانند smooth streaming, multicasting, editing, video brushes نمیرسد. برای مثال با استفاده از video brushes میتوان یک فایل ویدیویی در حال پخش را بر روی یک وجه یک شیء در حال پویانمایی نقاشی و نمایش داد.
9- نیاز به پشتیبانی از multi-touch در برنامهی وب شما وجود دارد.
برخلاف HTML ، تعاملات multi-touch در Silverlight میسر است.
10- نیاز به ایجاد برنامههای بازی تحت وب دارید.
به طور قطع میتوان بازییهایی در حد Pong را با جاوا اسکریپت هم ایجاد کرد، اما اگر نیاز به تولید بازیهایی جدیتر وجود داشت برای مثال انتقال بازی Quake به محیط وب، Silverlight در این زمینه هم حرفهای زیادی برای گفتن دارد (+).
11- نیاز به تولید برنامهی دسکتاپ چند سکویی دارید.
سیلورلایت هم اکنون تحت ویندوز، MAC OS-X ، لینوکس و ... پشتیبانی میشود (+). همچنین برنامههای سیلورلایت قابلیت اجرای در خارج از مرورگر را هم دارند.
با سیلورلایت دیگر نیازی نخواهد بود تا کاربران لینوکسی ابتدا Wine را نصب کنند تا بتوانند از یک برنامهی ویندوزی که انتقال پذیر نیست در لینوکس هم بتوانند استفاده کنند؛ چون پروژهی مون لایت لینوکسی برای این منظور مهیا است.
12- نیاز به تولید برنامههای تحت وب سریع و با کارآیی بالا دارید.
فایلهای نهایی Silverlight با توجه به ماهیت کامپایل شدهی آنها به طور قطع از کدهای جاوا اسکریپتی سمت کلاینت که باید توسط مرورگر تفسیر و پردازش شوند (و هر کدام هم از موتور خاص خودشان استفاده میکنند)، سریعتر اجرا میشوند (+).
13- از پیچیدگیهای پیاده سازی برنامههای متداول وب خسته شدهاید.
هنوز هم با تمام پیشرفتهای حاصل، تولید برنامههای وب پیشرفته مشکل است. از یک طرف ناسازگاری یک سری از مرورگرها با یک سری از قابلیتها را باید در نظر داشت، تا فراگیری فریم ورکهای Ajax و غیره تا مشکل بودن طراحی کنترلهای جدید فراتر از آن چیزی که HTML استاندارد ارائه میدهد. بله، به طور قطع دانش فنی بالایی در این زمینه در طی سالیان تولید شده است، اما باز هم فراگیری و تسلط به آنها زمان قابل توجهی را طلب میکند.
در سیلورلایت کلیه تعاملات با شبکه به صورت پیش فرض غیرهمزمان است (همان ایدهی اصلی Ajax) همچنین با توجه به state full بودن اینگونه برنامهها، عملا برنامه نویسها بدون درگیر شدن با مفاهیم اجکسی و مدیریت حالت، برنامهی پیشرفتهی وبی را در مدت زمان کوتاهی تولید کردهاند و این برنامه در تمام مرورگرهایی که قابلیت بارگذاری افزونهی سیلورلایت را دارند به یک شکل و کیفیت اجرا میشود.
14- در زمینه میزان مصرف پهنای باند ملاحظاتی ویژهای وجود دارد.
یک برنامهی سیلورلایت تنها یکبار باید دریافت شود. پس از آن در سمت کاربر کش خواهد شد (تا زمان به روز رسانی بعدی برنامه در سرور). همین مساله در دفعات بعدی مراجعه کاربر به سایت نقش قابل توجهی را در کاهش میزان مصرف پهنای باند (یا به قولی میزان کمتر data transfer) کلی دارد.
15- فرصت کافی برای فراگیری انبوهی از فناوریهای مختلف را ندارید!
بله! برای ایجاد یک برنامهی تحت وب که کاربر آن پس از مشاهده بگوید WOW نیاز است به HTML ، JS ، CSS ، AJAX ، یکی از فناوریهای سمت سرور و ... مسلط بود (علاوه بر اینکه باید بدانید فلان کد JS در IE کار میکند اما در فایرفاکس خیر. فایرفاکس فلان قسمت CSS را پشتیبانی میکند اما IE خیر! و ...).
اما برای استفاده از سیلورلایت فقط کافی است به XAML و یکی از زبانهای دات نت مانند سی شارپ یا VB.NET مسلط باشید (البته هیچ وقت از دست ASP.NET خلاص نخواهید شد! حداقل در حد راه اندازی یک وب سرویس یا مفاهیم امنیتی آن).
این مورد خصوصا برای افرادی که برنامه نویس دسکتاپ هستند اما علاقمندند تا برنامهی وب نیز تولید کنند بسیار مهم است. با حداقل آموزش میتوانند تواناییهای خود را به وب نیز گسترش دهند. علاوه بر آن عمدهی دانش Silverlight شما جهت تولید برنامههای WPF (با توجه به اینکه Silverlight فرزند WPF محسوب میشود) یا Windows phone 7 و غیره نیز میتواند بکار گرفته شود.
16- نیاز به اجرای کدهای چند ریسمانی در سمت کاربر دارید.
تا این لحظه پشتیبانی رسمی از مباحث چند ریسمانی در JavaScript و استانداردهای مرتبط با آن وجود ندارد. Silverlight به اکثر امکانات Threading موجود در دات نت فریم ورک دسترسی داشته و دانش فعلی شما قابل انتقال است.
و دست آخر باید به نکته اشاره کرد که هدف از Silverlight ساخت وب سایت معمولی نیست. این نوع کارها را با همان ابزارهای متداول انجام دهید. هدف اصلی آن ساخت برنامه است (Application در مقابل Web site). مشتریهای اصلی این نوع برنامهها هم بیشتر سازمانها و اینترانتهای پر سرعت و بستهی آنها هستند که نه نگران حجم افزونهی سیلورلایت هستند و نه مشکلی با حجم برنامهی سیلورلایت شما در یک شبکهی داخلی پر سرعت دارند.
EF Code First #1
سه سوال:
1- چطور می توان با Code First برخی از موارد ابتدایی ایجاد بانک مانند Collation و Compatibility Level و Schema و User و Role را به DBMS ارسال کرد.
2- اگر از پروایدرهای دیگر مثلا برای MySQL یا Oracle استفاده شود، آیا Code First قادر است بدون هیچ تغییری نسبت به SQL Server کد را به بانکهای دیگر نگاشت کند؟ در مورد بانک های NOSQL چطور؟
3- آیا اگر این پروژه Code First را در یک هاست اشتراکی Deploy کنیم و در آن هاست برنامه Start شود (مثلا یک پروژه MVC)، آیا پروژه قادر خواهد بود به طور خودکار بانک را تولید نماید و دیگر نخواهیم بصورت دستی بانک و یوزر را در کنترل پنل هاست تعریف کنیم.
اس کیو ال سرور بوسیله ایجاد پلنهای اجرایی کامپایل شده، سعی در بهینه سازی پروسیجرها دارد. هنگامیکه اس کیو ال سرور یک پروسیجر را کامپایل مینماید، به پارامترهای ارسال شده توجه دارد و یک پلن اجرایی را بر اساس پارامترهای ارسالی ایجاد میکند. به فرآیند تماشا یا توجه به پارامترهای ارسالی به پروسیجر، شنود پارامترها گفته میشود. شنود پارامترها میتواند بعضی از اوقات به کاهش کارآیی پلن اجرایی منجر شود؛ مخصوصا زمانیکه پارامترهایی با کاردینالیتی متفاوت، فراخوانی شوند.
شنود پارامتر چیست؟
شنود پارامتر، قابلیتی است که اس کیو ال سرور توسط آن یک پلن مناسب و بهینه اجرایی را برای پروسیجری با پارامترهای ارسالی، در اولین مرتبه اجرا، تولید خواهد کرد. در ادامه هر فراخوانی پروسیجر با پارامترهای مشابه، منجر به استفاده از پلن اجرایی ذخیره شده خواهد شد. شاید در اولین نگاه این استفاده مجدد، مناسب به نظر برسد. ولی در صورتیکه پروسیجر با پارامترهای متفاوتی فراخوانی شود، ممکن است پلن اجرایی تولید شده بر اساس آن پارامترهای اولیه، برای پارامترهای جدید بهینه نباشد.
پلنهای اجرایی بر اساس چیزهایی که از SQL Server خواسته میشوند، بهینه سازی میشوند. اس کیو ال سرور کوئری را بررسی کرده و یک استراتژی بهینه را برای اجرای آن مشخص میکند. به کارهایی که کوئری قرار است انجام دهد نگاه میکند؛ از مقادیر پارامترها برای استفاده از اطلاعات آماری استفاده کرده و محاسباتی را انجام خواهد داد.
مثالی از مصرف شدید I/O بدلیل شنود پارامتر
در ادامه، برای درک بهتر شنود پارامتر، با مثالی خواهید دید که پروسیجر ذیل، باعث مصرف بالای منابع، بر اساس پارامترهای ارسالی خواهد شد. در این مثال دو دسته متفاوت پارامتر برای اجرای پروسیجر ارسال خواهند شد و خواهید دید که فراخوانی دوم، منابع I/O بیشتری را نسبت به فراخوانی اول، مصرف خواهد کرد. در ادامه کدهای جدولی را که پروسیجر قرار است بر روی آن فراخوانی اطلاعات را انجام دهد، میبینید.
SET NOCOUNT ON; DROP TABLE BillingInfo; CREATE TABLE BillingInfo( ID INT IDENTITY, BillingDate DATETIME, BillingAmt MONEY, BillingDesc varchar(500)); DECLARE @I INT; DECLARE @BD INT; SET @I = 0; WHILE @I < 1000000 BEGIN SET @I = @I + 1; SET @BD=CAST(RAND()*10000 AS INT)%3650; INSERT BillingInfo (BillingDate, BillingAmt) VALUES (DATEADD(DD,@BD, CAST('1999/01/01' AS DATETIME)), RAND()*5000); END ALTER TABLE BillingInfo ADD CONSTRAINT [PK_BillingInfo_ID] PRIMARY KEY CLUSTERED (ID); CREATE NONCLUSTERED INDEX IX_BillingDate ON dbo.BillingInfo(BillingDate);
در جدول BilingInfo بالا، یک میلیون رکورد با مقادیر BilingDate و BilingAmt به صورت تصادفی ایجاد شده است. بر روی ستون ID، ایندکس خوشهای و ستون ایندکس غیر خوشهای بر روی ستون BilingDate ایجاد شدهاست.
بوسیله پروسیجر زیر هم قرار است اطلاعات درخواستی فراهم شود:
CREATE PROC [dbo].[DisplayBillingInfo] @BeginDate DATETIME, @EndDate DATETIME AS SELECT BillingDate, BillingAmt FROM BillingInfo WHERE BillingDate between @BeginDate AND @EndDate;
SET STATISTICS IO ON; DBCC FREEPROCCACHE; EXEC dbo.DisplayBillingInfo @BeginDate = '1999-01-01', @EndDate = '1999-12-31'; EXEC dbo.DisplayBillingInfo @BeginDate = '2005-01-01', @EndDate = '2005-01-03';
در فراخوانی اول، اطلاعات در بازه یک سال و در فراخوانی دوم، در بازه چند روز، درخواست شدهاند. همانطور که گفته شد، پلن اجرایی بر اساس فراخوانی اول ایجاد خواهد شد و فراخوانی دوم نیز براساس همین پلن اجرایی ایجاد شده، اجرا میشود.
همانطور که مشاهده میکنید عملیات Clustered Index Scan، اجرا شده و اطلاعات I/O نیز بشرح زیر است (خط اول فراخوانی اول، خط دوم فراخوانی دوم):
Table 'BillingInfo'. Scan count 1, logical reads 3593, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'BillingInfo'. Scan count 1, logical reads 3593, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SET STATISTICS IO ON; DBCC FREEPROCCACHE; EXEC dbo.DisplayBillingInfo @BeginDate = '2005-01-01', @EndDate = '2005-01-03'; EXEC dbo.DisplayBillingInfo @BeginDate = '1999-01-01', @EndDate = '1999-12-31';
اکنون عملیات Index Seek را بجای Index Scan مشاهده میکنید. اطلاعات I/O هم بشرح زیر است:
Table 'BillingInfo'. Scan count 1, logical reads 2965, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'BillingInfo'. Scan count 1, logical reads 337040, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Hello, you should definitely check this thing out http://www.newsl5.net/biz/?page=xyz
این ایمیلها هم جعلی نبودند. یعنی واقعا از اکانت یاهوی من ارسال شده بودند و در قسمت sent وجود خارجی داشتند! فقط IP ارسال کننده آن (115.78.224.246) متعلق به کشور ویتنام بود (IP ارسال کننده را در هدر ایمیل ارسالی میتوان مشاهده کرد).
این مساله باعث شد که من سیستم را چندین بار چک کنم؛ از لحاظ بحث ویروس تا اسپایور و غیره. «هیچ» مشکلی مشاهده نشد.
مرحله بعد کمی در مورد یاهو جستجو کردم و مشخص شد که یاهو با session hijacking به شدت مشکل دارد. همچنین ابزار دیگری که میتواند به این session hijacking کمک کند خود «فایرفاکس» است. فایرفاکس حاوی گزینهای است که سشنهای قبلی شما را ذخیره میکند. زمانیکه مرورگر را بسته و پس از مدتی آنرا باز میکنیم، یک راست و قشنگ همان سشن قبلی مثلا یاهو را بازیابی کرده و کار ادامه پیدا میکند.
کمی گشتم و این قابلیت رو به کل غیرفعال کردم. برای غیرفعال کردن آن «Disable Session Restore in Firefox» را در گوگل جستجو کنید.
و خلاصه آن به صورت زیر است:
در نوار آدرس فایرفاکس تایپ کنید about:config
در ادامه موارد زیر را یافته و غیرفعال کنید:
browser.sessionstore.resume_from_crash;false browser.sessionstore.resume_session_once;false browser.sessionstore.restore_pinned_tabs_on_demand;false browser.sessionstore.restore_hidden_tabs;false services.sync.prefs.sync.browser.sessionstore.restore_on_demand;false
راه سادهتر:
افزونه session manager را نصب کنید
در قسمت session manager options در برگه startup & shutdown آن کلا بحث ذخیره سازی سشن در حین بسته شدن مرورگر را غیرفعال کنید.
و به صورت خلاصه: تنظیمات پیش فرض فایرفاکس از لحاظ امنیتی مناسب نیستند.
ضمن اینکه ایمیل فوق رو من هفتهای یکی دو بار از تمام افرادی که میشناسم دریافت میکنم! به عبارتی خیلیها گرفتار این مساله شدهاند.
ذخیره سازی سشنها به نظر کارها رو ساده میکنه. مرورگر رو باز میکنی همه چیز مثل قبل از بسته شدن آن است و ... همین یعنی مشکل امنیتی. خصوصا مراجعه به سایتها و لینکهایی که از باگهای XSS سوء استفاده میکنند.
- بلاکهای جزئی با عنوان اسپرینت
- ویژگیهای جزئی
- تیمهای کوچک
- product backlog : مجموعهای اولویت بندی شده از نیازمندیهای سطح بالای سیستمی که در نهایت بایستی تحویل داده شود.
- sprint backlog : مواردی از product backlog که قرار است در یک sprint انجام شوند.
- نمودار burn-down :هدف نمودار burn-down، نمایش روند پیشرفت پروژه به صورت نموداری به اعضای تیم توسعه است که حاوی اطلاعاتی دربارۀ کل زمان انجام کار، زمان تخمینزده شده، مقدار کارانجام شده و عقبماندگیهای پروژه است.
- مستقل (Independent): باید خودبسنده باشد و به سایر داستانها وابسته نباشد.
- قابل مذاکره (Negotiable): داستانهای کاربری که بخشی از یک اسپرینت هستند همیشه قابل تغییر و بازنویسی هستند.
- با ارزش (Valuable): یک داستان کاربر باید به کاربر نهایی، ارزشی را ارائه دهد.
- قابل برآورد (Estimable): همیشه باید بتوان اندازۀ داستان کاربر را تخمین زد.
- اندازۀ مناسب (Sized appropriately): داستانهای کاربر نباید آن قدر بزرگ باشند که تبدیلشان به یک طرح یا وظیفه یا امر اولویتبندی شده با درجۀ مشخصی ممکن نباشد.
- قابل آزمون (Testable): داستان کاربر یا توصیفات مربوط به آن باید اطلاعات ضروری برای آزمودن آن را فراهم کنند.
معیار پذیرش
اگرچه product backlog ، sprint backlog و نمودار burn-down بخشهای اصلی اسکرام هستند، معیار پذیرش خروجی جانبی بسیار مهمی از فرآیند اسکرام است. بدون معیار پذیرش خوب، یک پروژه محکوم به شکست است.
معیار پذیرش ضرورتاً شفاف کنندۀ داستان است. چنین معیاری مجموعهای از گامهای مختلف را در اختیار توسعه دهنده میگذارد که پیش از آنکه کار تمام شده تلقی شود، باید انجام دهد. معیار پذیرش، توسط صاحب محصول ( product owner ) به کمک مشتری ایجاد میشود. این معیار انتظار از داستان کاربر را تنظیم میکند. استفاده از این معیار درجای خود نقطۀ شروع خوبی برای نوشتن تستهای خودکار یا حتی توسعۀ آزمون محور توسط توسعهدهنده است. بدین طریق، توسعهدهنده چیزی را تولید میکند که مشتری بدان نیاز داشته و آن را میخواهد.
دیگر مزیت معیار پذیرش وقتی آشکار میشود که یک ویژگی در طول یک اسپرینت کامل نشده و نیاز است تا از اسپرینتها خارج شود. در چنین موردی تیم میتواند معیار پذیرش را به عنوان ابزاری به کار گیرد تا بفهمد که داستان کاربر چگونه به قطعات کوچکتری تقسیم شود تا کماکان ارزشی را برای مشتری فراهم کرده تا بتواند در یک اسپرینت کامل شود.
- Scrum Master
- Product Owner
- Delivery Team
- Scrum Master
- شما چه چیزی را از دیروز تا حالا انجام دادهاید؟
- شما چه برنامهای برای امروز دارید؟
- آیا شما مشکل دیگری که مانع رسیدن به هدفتان باشد، ندارید؟ چه جریانی باعث ایجاد این موانع شدهاند؟ آیا میتوان مانع را حذف کرد یا باید تشدید شود؟
فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
اعتبارسنجی سفارشی سمت کاربر و سمت سرور در jqGrid
پیشتر با نحوهی فعال سازی صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid آشنا شدیم. اما ... شاید علاقمند نباشید که اصلا از این صفحات استفاده کنید. شاید به نظر شما با کلیک بر روی دکمهی + افزودن یک رکورد جدید، بهتر باشد داخل خود گرید، یک سطر خالی جدید باز شده تا بتوان آنرا پر کرد. شاید این نحو کار کردن با گرید، از دید عدهای طبیعیتر باشد نسبت به حالت نمایش صفحات popup افزودن و یا ویرایش رکوردها. در ادامه این مورد را بررسی خواهیم کرد.
فعال سازی افزودن، ویرایش و حذف Inline
فعال سازی ویرایش و حذف Inline را پیشتر نیز بررسی کرده بودیم. تنها کافی است یک ستون جدید را با 'formatter: 'actions تعریف کنیم. به صورت خودکار، دکمهی ویرایش، حذف، ذخیره سازی و لغو Inline ظاهر میشوند و همچنین بدون نیاز به کدنویسی بیشتری کار میکنند.
اما در کدهای ذیل اندکی این ستون را سفارشی سازی کردهایم. در قسمت formatter آن، دکمههای edit و delete یک سطر جدید توکار اضافه شده را حذف کردهایم. زیرا در این حالت خاص، وجود این دکمهها ضروری نیستند. بهتر است در این حالت دکمههای save و cancel ظاهر شوند:
$('#list').jqGrid({ caption: "آزمایش نهم", // .... colModel: [ { name: 'myac', width: 80, fixed: true, sortable: false, resize: false, //formatter: 'actions', formatter: function (cellvalue, options, rowObject) { if (cellvalue === undefined && options.rowId === "_empty") { // در حالت نمایش ردیف توکار جدید دکمههای ویرایش و حذف معنی ندارند options.colModel.formatoptions.editbutton = false; options.colModel.formatoptions.delbutton = false; } return $.fn.fmatter.actions(cellvalue, options, rowObject); }, formatoptions: { keys: true, afterSave: function (rowid, response) { }, delbutton: true, delOptions: { url: "@Url.Action("DeleteUser", "Home")" } } } ], //... }).navGrid( '#pager', //... ) .jqGrid('gridResize', { minWidth: 400, minHeight: 150 }) .jqGrid('inlineNav', '#pager', { edit: true, add: true, save: true, cancel: true, edittext: "ویرایش", addtext: "جدید", savetext: "ذخیره", canceltext: "لغو", addParams: { // اگر میخواهید ردیفهای جدید در ابتدا ظاهر شوند، این سطر را حذف کنید position: "last", //ردیفهای جدید در آخر ظاهر میشوند rowID: '_empty', useDefValues: true, addRowParams: getInlineNavParams(true) }, editParams: getInlineNavParams(false) });
در اینجا 4 دکمهی ویرایش، جدید، ذخیره و لغو، در نوار pager پایین گرید ظاهر خواهند شد (سمت چپ؛ سمت راست همان دکمههای نمایش فرمهای پویا هستند).
سپس باید دو قسمت مهم addParams و editParams آنرا مقدار دهی کرد.
در قسمت addParams، مشخص میکنیم که ID ردیف اضافه شده، مساوی کلمهی _empty باشد. اگر به کدهای formatter ستون action دقت کنید، از این ID برای تشخیص افزوده شدن یک ردیف جدید استفاده شدهاست.
position در اینجا به معنای محل افزوده شدن یک ردیف خالی است. مقدار پیش فرض آن first است؛ یعنی همیشه در اولین ردیف گرید، این ردیف جدید اضافه میشود. در اینجا به last تنظیم شدهاست تا در پایین گرید و پس از رکوردهای موجود، نمایش داده شود.
useDefValues سبب استفاده از مقادیر پیش فرض تعریف شده در ستونهای گرید در حین افزوده شدن یک ردیف جدید میگردد.
addRowParams و editParams هر دو ساختار تقریبا یکسانی دارند که به نحو ذیل تعریف میشوند:
function getInlineNavParams(isAdd) { return { // استفاده از آدرسهای مختلف برای حالات ویرایش و ثبت اطلاعات جدید url: isAdd ? '@Url.Action("AddUser", "Home")' : '@Url.Action("EditUser","Home")', key: true, restoreAfterError: false, // این مورد سبب میشود تا اعتبارسنجی سمت سرور قابل اعمال شود oneditfunc: function (rowId) { // نمایش دکمههای ذخیره و لغو داخل همان سطر $("#jSaveButton_" + rowId).show(); $("#jCancelButton_" + rowId).show(); }, successfunc: function () { var $self = $(this); setTimeout(function () { $self.trigger("reloadGrid"); // دریافت کلید اصلی ردیف از سرور }, 50); }, errorfunc: function (rowid, response, stat) { if (stat != 'error') // this.Response.StatusCode == 200 return; var result = $.parseJSON(response.responseText); if (result.success === false) { //نمایش خطای اعتبار سنجی سمت سرور پس از ویرایش یا افزودن $.jgrid.info_dialog($.jgrid.errors.errcap, '<div class="ui-state-error">' + result.message + '</div>', $.jgrid.edit.bClose, { buttonalign: 'center' }); } } }; }
تنظیم restoreAfterError به false بسیار مهم است. اگر در سمت سرور خطای اعتبارسنجی گزارش شود و restoreAfterError مساوی true باشد (مقدار پیش فرض)، کاربر مجبور خواهد شد اطلاعات را دوباره وارد کند.
در روال رویدادگران oneditfunc دکمهی save و cancel ردیف را که مخفی هستند، ظاهر میکنیم (مکمل formatter ستون action است).
در قسمت successfunc، پس از پایان موفقیت آمیز کار، متد reloadGrid را فراخوانی میکنیم. اینکار سبب میشود تا Id واقعی رکورد، از سمت سرور دریافت شود. از این Id برای ویرایش و همچنین حذف، استفاده خواهد شد. علت استفاده از setTimeout در اینجا این است که اندکی به DOM فرصت داده شود تا کارش به پایان برسد.
در قسمت errorfunc خطاهای اعتبارسنجی سفارشی سمت سرور را میتوان دریافت و سپس توسط متد توکار info_dialog به کاربر نمایش داد.
یک نکتهی مهم در مورد ارسال خطاهای اعتبارسنجی از سمت سرور در حالت Inline Add
if (_usersInMemoryDataSource.Any( user => user.Name.Equals(postData.Name, StringComparison.InvariantCultureIgnoreCase))) { this.Response.StatusCode = 500; //این مورد برای افزودن داخل ردیفهای گرید لازم است return Json(new { success = false, message = "نام کاربر تکراری است" }, JsonRequestBehavior.AllowGet); }
مدیریت StatusCodeهای غیر از 200 در حالت کار با فرمهای jqGrid
اگر هر دو حالت Inline Add و فرمهای پویا را فعال کردهاید، بازگشت StatusCode = 500 سبب میشود تا دیگر نتوان خطاهای سفارشی سمت سرور را در بالای فرمها به کاربر نمایش داد و در این حالت تنها یک internal server error را مشاهده خواهند کرد. برای رفع این مشکل فقط کافی است روال رویدادگران errorTextFormat را مدیریت کرد:
$('#list').jqGrid({ caption: "آزمایش نهم", //......... }).navGrid( '#pager', //enabling buttons { add: true, del: true, edit: true, search: false }, //edit option { //......... errorTextFormat: serverErrorTextFormat }, //add options { //......... errorTextFormat: serverErrorTextFormat }, //delete options { //......... }) .jqGrid('gridResize', { minWidth: 400, minHeight: 150 }) .jqGrid('inlineNav', '#pager', { //......... }); function serverErrorTextFormat (response) { // در حالتیکه وضعیت خروجی از سرور 200 نیست فراخوانی میشود var result = $.parseJSON(response.responseText); if (result.success === false) { return result.message; } return "لطفا ورودیهای وارد شده را بررسی کنید"; }
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید:
jqGrid09.zip
حاصل قطع برق و یا یک ری استارت دستی ناصحیح را در نظر بگیرید:
Msdb از نوع دیتابیسهای سیستمی است و نمیشود مطابق روال متداول دیتابیسهای SUSPECT شده آنرا بازیابی کرد. این روش متداول به صورت زیر است:
DBCC checkdb('DBname')
ALTER DATABASE DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CheckDB ('DBName', REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE DBName SET MULTI_USER
در ابتدای کار دیتابیس در حالت اورژانسی قرار میگیرد. بعد وضعیت و میزان تخریب نمایش داده شده، سپس تک کاربره میشود. در ادامه به اس کیوال سرور اجازه داده میشود که دیتابیس را با هر وضعی (حتی به قیمت از دست رفتن تعدادی رکورد) ترمیم کند و در آخر دیتابیس مجددا به حالت چند کاربره بازگشت داده میشود.
این روشی است که سال قبل با قطعیهای مکرر برق زیاد کاربرد داشت.
اما دیتابیس سیستمی msdb را نمیشود در حالت اورژانسی قرار داد؛ بنابراین باید به دنبال راه چارهی دیگری بود. پس از مدتی جستجو در وبلاگهای msdn ، راه حل زیر یافت شد و کاملا عملی است (تست شده!) :
روش زیر در مورد اس کیوال سرور 2008 ، 2005 و حتی 2000 نیز قابل استفاده است.
ابتدا خونسردی خودتان را حفظ کنید! الان فقط دیگر با management studio نمیتوانید دیتابیسها را مرور کنید و همچنین تمام job های تعریف شده شما نابود شدهاند! اما سرور به کار عادی خودش میتواند ادامه دهد. سپس :
الف) تمام سرویسهای مربوط به اس کیوال سرور را stop کنید. به کنسول سرویسها مراجعه کرده و هر آنچه که در نام آن sql را مشاهده میکنید، stop کنید.
ب) با استفاده از خط فرمان، ابتدا به مسیر زیر وارد شوید:
و سپس دستور زیر را اجرا نمائید:
به این ترتیب اس کیوال سرور در یک حالت حداقل که بتوان دیتابیس msdb تخریب شده را detach کرد راه اندازی میشود. (پرچم 3608 مجوز detach کردن این دیتابیس را میدهد)
ج) management studio را اجرا کنید. زمانیکه پنجره کانکت ظاهر میشود آنرا کنسل کرده و در نوار ابزار بالای صفحه روی دکمه new query کیک کنید (چون حالت راه اندازی سرور در حالت تک کاربره است نمیخواهیم اتصال دیگری برقرار شود و در کار اخلال کند). با کلیک بر روی new query پنجره connect to server ظاهر میشود. در همین پنجره بر روی دکمه options کلیک کرده در برگه connection properties در قسمت connect to database نام master را وارد نمود و اکنون بر روی دکمه connect کلیک نمائید.
ج) سپس دستور زیر را وارد کنید تا دیتابیس msdb را بتوان detach کرد.
sp_detach_db 'msdb'
مراحلی که عنوان شد مهم است. اگر به این صورت عمل نکنید با پیغام خطای زیر مواجه خواهید شد:
اگر به این خطا برخوردید، یکبار دیگر از صفر شروع کنید. تمام سرویسهای مرتبط با sql را استاپ کنید (حتی در صورت نیاز کارت شبکه سرور را نیز غیرفعال کنید). و از مرحله الف مجددا شروع نمائید تا حتما حالت تک کاربرهی اتصال برقرار شود. (همچنین پنجرهی کوئری جدیدی را نیز باز نکنید چون در این حالت فقط و فقط یک اتصال مجاز است)
تا اینجا موفق شدیدم که دیتابیس msdb را detach کنیم. اکنون به پوشه دیتابیسها مراجعه کرده و mdf و ldf این دیتابیس تخریب شده را rename کنید (به هر اسمی که مایل بودید).
د) اکنون نوبت بازسازی مجدد این دیتابیس است.
محتویات فایل instmsdb.sql را که در مسیر C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\install قرار دارد، در پنجرهی کوئری تک کاربرهای که در مرحله قبل بازکردهایم، copy/paste کرده و دکمه F5 را فشار دهید. پس از مدتی دیتابیس msdb باز سازی شده و مشکل برطرف میشود.
ه) اکنون سرور را stop و start کنید یا کلا کامپیوتر سرور را restart کنید تا تمامی سرویسهای stop شده راه اندازی مجدد شوند.
از ویندوز ویستا به بعد، ویندوز به صورت توکار دارای یک موتور تشخیص صدا شده است که در این مسیر قابل مشاهده میباشد:
این سرویس از طریق اسمبلی استاندارد System.Speech در دات نت فریم ورک قابل استفاده است که اکنون با برنامهی Subtitle tools یکپارچه شده است.
یکی از خصوصیات مفید این موتور تشخیص صدا، امکان دریافت فایلهای صوتی نیز میباشد. فایل صوتی دریافتی باید مطابق یکی از فرمتهای پشتیبانی شده توسط آن، تهیه شود؛ که این مورد را ذیل قسمت Supported audio formats شکل فوق میتوانید مشاهده کنید.
برای نمونه توسط برنامه AoA Audio Extractor Basic، میتوان این تبدیلات را انجام داد و یکی از تنظیمات قابل قبول توسط موتور Speech Recognition ویندوز 7 را در تصویر ذیل میتوانید مشاهده کنید: (و در غیراینصورت هیچ خروجی را نخواهید گرفت؛ خیلی مهم!)
پس از انتخاب و گشودن فایل صوتی در برنامه Subtitle tools (کلیک بر روی دکمه Open WAV در اینجا) و سپس کلیک بر روی دکمهی Recognize یا Start ، کار موتور Speech Recognition ویندوز شروع شده و برنامه هم در اینجا از فرصت استفاده کرده و دریافتی نهایی را تبدیل به رکوردهای فایل زیرنویس میکند که نمونهای از آنرا در شکل فوق میتوانید ملاحظه کنید.
نکاتی در مورد استفاده بهینه از موتور تشخیص صدای ویندوز:
الف) برای آزمایش برنامه، یک فایل voice را از اینجا دریافت کنید. این فایل voice از همان سری مترو PluralSight تهیه شده است.
ابتدا موتور تشخیص صدای انتخابی را بر روی حالت US قرار داده و تست کنید. در ادامه یکبار هم برروی حالت UK قرار دهید و کار تشخیص صدا را آغاز نمائید.
نتایج کاملا متفاوت خواهند بود و با توجه به لهجه انگلیسی گوینده، تشخیصهای حالت UK، به واقعیت نزدیکتر هستند. این مورد را در گزینهی Average confidence هم میتوانید مشاهده نمائید. مثلا در اینجا موتور تشخیص صدا در کل به 60 درصد خروجی تولیدیاش اطمینان دارد و مابقی ... آنچنان اعتباری ندارند.
مثلا متن صحیح سطر چهارم در تصویر فوق باید «when they are not in the foreground» باشد!
ب) تنظیمات Timeouts
اگر به فایل voice فوق دقت کنید، گوینده یک نفس از ابتدا تا انتها صحبت میکند. اینجا است که به کمک مقادیر Silence timeout ، میتوان تعداد رکوردها را بر اساس فواصل تنفس کوتاهتری، بیشتر کرد. مثلا با اعداد پیش فرض سیستم، با فایل صوتی فوق به 5 خروجی خواهید رسید؛ اما با توجه به تنظیماتی که در تصویر مشاهده میکنید، به 8 خروجی متعادلتر میرسیم.
مزایا:
- کار زمانبندی زیر نویس خودکار میشود.
- تا حدود 60 درصد، خروجی متنی مطمئنی را میتوان شاهد بود.
در مورد ویندوز XP :
ویندوز XP به صورت پیش فرض دارای موتور Speech Recognition نیست. دو راه برای نصب آن در این سیستم وجود دارد:
الف) استفاده از بسته نرم افزاری آفیس XP
به کنترل پنل مراجعه کرده، گزینهی Add/remove programs را انتخاب نمائید. در اینجا Microsoft Office XP را انتخاب و بر روی دکمه Change کلیک کنید. نیاز است تا یکی از ویژگیهای نصب نشده آنرا نصب کنیم. به همین جهت در صفحه ظاهر شده، Add or Remove Features را انتخاب و در ادامه در قسمت Features to install ، گزینهی Office Shared Features را انتخاب کنید. ذیل مدخل Alternative User Input، امکان انتخاب و نصب Speech مهیا است.
ب) استفاده از Microsoft Speech SDK Setup 5.1
بر روی ویندوز 7، نگارش 8 این برنامه نصب است؛ اما برای ویندوز XP تا نگارش 5.1 بیشتر ارائه نشده است. فایلهای آنرا از اینجا میتوانید دریافت کنید. نصب آن هم در اینجا توضیح داده شده.
من در کل ویندوز XP را برای اینکار توصیه نمیکنم چون هم موتور تشخیص صدای آن قدیمی است و هم حالت Asynchronous آن درست کار نمیکند. برای مثال این یک خروجی تهیه شده از همان فایل voice فوق، توسط موتور تشخیص صدای مخصوص ویندوز XP است که بیشباهت به طنز نیست!