بررسی ویجت Kendo UI File Upload
<script> $(function() { kendo.destroy("#files"); }); </script>
بررسی ویجت Kendo UI File Upload
[TestMethod] public void SearchForWatiNOnGoogle() { using (var browser = new IE("http://www.google.com")) { browser.TextField(Find.ByName("q")).TypeText("WatiN"); browser.Button(Find.ByName("btnG")).Click(); Assert.IsTrue(browser.ContainsText("WatiN")); } }
[TestMethod] public void SearchForWatiNOnGoogle() { using (var browser = new IE("http://www.google.com")) { browser.TextField(Find.ByName("q")).Value="WatiN"; browser.Button(Find.ByName("btnG")).ClickNoWait(); Thread.Sleep(3000); Assert.IsTrue(browser.ContainsText("WatiN")); } }
namespace jqGrid10.Models { public class Post { public int Id { set; get; } public string Title { set; get; } public string CategoryName { set; get; } public int NumberOfViews { set; get; } } }
- گروه بندی بر روی ستون CategoryName انجام شود.
- ستونی که بر روی آن گروه بندی انجام میشود، نمایش داده نشود.
- در ابتدای نمایش گروهها، تمام آنها به صورت جمع شده و Collapsed نمایش داده شوند.
- پس از نمایش گروهها، اولین گروه به صورت خودکار باز شود.
- تعداد ردیف هر گروه به عنوان گروه اضافه شود.
- جمع کل ستون تعداد بار مشاهدات هر گروه قابل محاسبه شود.
- جمع کل هر گروه در زمانیکه هر گروه نیز بستهاست نمایش داده شود.
- رنگ ردیف جمع کل قابل تنظیم باشد.
فعال سازی گروه بندی در jqGrid
فعال سازی گروه بندی در jqGrid به سادگی افزودن تعاریف ذیل است:
$('#list').jqGrid({ caption: "آزمایش دهم", //... grouping: true, groupingView: { groupField: ['CategoryName'], groupOrder: ['asc'], groupText : ['<b>{0} - {1} ردیف</b>'], groupDataSorted: true, groupColumnShow: false, groupCollapse: true, groupSummary: [true], showSummaryOnHide: true } });
groupField بیانگر آرایهای از ستونهایی است که قرار است بر روی آنها گروه بندی صورت گیرد.
groupOrder آرایهای اختیاری از مقادیر asc یا desc است که متناظر هستند با نحوهی مرتب سازی پیش فرض ستونهای معرفی شده در آرایه groupField.
groupText آرایهای اختیاری از عناوین گروه بندیهای انجام شدهاست. اگر ذکر شود، {0} آن با نام گروه و {1} آن با تعداد عناصر گروه جایگزین میشود.
تنظیم groupDataSorted سبب خواهد شد تا نام ستونی که بر روی آن گروه بندی صورت میگیرد، به سرور ارسال شود (توسط پارامتر sidx). به این ترتیب در سمت سرور میتوان اطلاعات را به صورت پویا مرتب سازی کرده و بازگشت داد.
با تنظیم groupColumnShow به false سبب خواهیم شد تا ستونهای معرفی شده در قسمت groupField نمایش داده نشوند.
با تنظیم groupCollapse به true، در ابتدای نمایش گروهها، ردیفهای آنها نمایش داده نخواهند شد و در حالت جمع شده قرار میگیرند.
groupSummary به معنای فعال سازی نمایش ردیف محاسبهی summary مانند sum، min، max و امثال آن بر روی یک گروه است.
اگر مقدار showSummaryOnHide مساوی true باشد، ردیف محاسبهی summary حتی در حالت groupCollapse: true نمایش داده خواهد شد.
فعال سازی محاسبهی جمع ستون تعداد بار مشاهدات مطالب
برای فعال سازی نهایی محاسبهی جمع ستون تعداد بار مشاهدات، علاوه بر تنظیم groupSummary به true، نیاز است در همان ستون مشخص کنیم که این محاسبات چگونه باید انجام شوند:
colModel: [ // ........ { name: '@(StronglyTyped.PropertyName<Post>(x => x.Title))', index: '@(StronglyTyped.PropertyName<Post>(x => x.Title))', align: 'right', width: 150, summaryTpl: '<div style="text-align: left;">خلاصه </div>', summaryType: function (val, name, record) { return ""; } }, // ........ { name: '@(StronglyTyped.PropertyName<Post>(x => x.NumberOfViews))', index: '@(StronglyTyped.PropertyName<Post>(x => x.NumberOfViews))', align: 'center', width: 70, summaryType: 'sum', summaryTpl: '<b>جمع مشاهدات: {0}</b>' } ],
summaryType مانند ستون عنوان، سفارشی شده نیز میتوان باشد. در ردیف summary و ستون عنوان تنها میخواهیم یک مقدار ثابت را نمایش دهیم، به همین جهت summaryType آن به یک مقدار خالی تنظیم شدهاست.
تغییر رنگ ردیف خلاصه عملیات هر گروه به همراه گشودن خودکار اولین گروه
گروه بندی به همراه یک سری متد توکار نیز هست. برای مثال اگر متد groupingToggle را بر روی Id هر گروه فراخوانی کنیم، میتوان سبب باز یا بسته شده آن گروه شد. متدهای دیگری مانند groupingGroupBy برای گروه بندی پویا و groupingRemove برای حذف گروه بندی نیز وجود دارند:
$('#list').jqGrid({ caption: "آزمایش دهم", //......... loadComplete: function() { //......... $('#list').jqGrid('groupingToggle', 'list' + 'ghead_0_0'); $("tr.jqfoot td").css({ "background": "#2f4f4f", "color": "#FFF" }); }, });
مثال کامل این قسمت را از اینجا میتوانید دریافت کنید:
jqGrid10.zip
معرفی برنامهی Subtitle Tools
نکتهی مطلب «تخمین مدت زمان خوانده شدن یک مطلب» به این برنامه اضافه شد (یکبار کلیک بر روی recalculate در نوار ابزار آن). کار آن تصحیح مدت زمان نمایش یک ردیف زیرنویس بر اساس مدت زمان خوانده شدن آن هست تا سریع، پیش از خوانده شدن آن، ردیف بعدی نمایش داده نشود و اگر نمایش داده شد، در بالا و یا ذیل آن توسط برنامهی پخش کننده، برای مدتی باقی بماند (روش کار KMPlayer).
سلام
سال نو مبارک! به امید سالی بهتر از پارسال!
این روزها با هزینهای معادل هزینهی تهیهی یک هاست اشتراکی سالیانه برای بالاگذاری یک سایت معمولی در 5 سال قبل، میتوان یک VPS تهیه کرد و به این صورت قفل و کلید یک نیمچه سرور را (با 200 و خردهای مگ رم، 30 گیگ فضا، سرعت CPU نزدیک به 700 MHz و ویندوز سرور 2003 یا 2008) در اختیار شما قرار میدهند (البته به قول معروف هر چقدر پول بدهید همانقدر هم سخت افزار در اختیار شما قرار میدهند) بجای صرفا یک دایرکتوری مجازی محدود با 100 مگ فضای هاست که هر احدی در آن هاست اشتراکی میتواند سر مبارک را اندکی چرخانده و تمام زندگی شما را مرور کند و غیره!
استفادهی مفیدی هم که این VPS برای من داشته، ترنس لود کردن یک سری فایل است (با توجه به سرعتهای نجومی دریافت فایل این سرورها). برای مثال دریافت فایل از یوتیوب و انتقال به یک هاست دیگر برای دریافت سادهتر خودم و یا دیگران.
برای نمونه سایت dotnet-tv.com را در نظر بگیرید. تعدادی از ویدیوهای این سایت در یوتیوب هاست شده و از این دست زیاد هستند. خیلیها برای فرار از مشکلات کمبود پهنای باند از یوتیوب استفاده میکنند. یوتیوب هم که از این طرف بسته است. خوب، من الان میخواهم ویدیوی مربوط به ASP.Net MVC آن را مشاهده کنم، چکار باید کرد؟!
یک برنامهی سادهی کنسول را تهیه کردهام که این کار را برای VPS داران تسهیل میکند.
- دریافت فایل از یوتیوب
- آپلود خودکار آن به رپیدشیر
یک نمونه خروجی آن: (فایلهای یوتیوب سایت ذکر شده که به رپیدشیر منتقل شده)
دریافت
در سورس این برنامه موارد زیر پیاده سازی شده است:
- یافتن لینکهای یوتیوب سایت dotnet-tv.com با استفاده از regular expressions
- یافتن لینک دانلود مستقیم این فایلها از سایت یوتیوب که شامل استفاده از regular expressions برای استخراج قسمتهای مفید از صفحات و همچنین استفاده از امکانات Json دات نت فریم ورک سه و نیم برای parse قسمتهای استخراج شده است.
- ایجاد یک thread pool سفارشی که هر بار 7 لینک مستقیم را به صورت همزمان از یوتیوب دریافت میکند. (thread pool پیش فرض دات نت تمام تردها را به یکباره شروع میکند که برای اینکار مفید نیست. به همین جهت از این thread pool سفارشی شده استفاده شد)
پیش فرض فایلی که از سایت یوتیوب دریافت میشود MP4 با کیفیت بالا است که با fmt=18 در فایل Youtube.cs مشخص شده. فرمتهای دیگر را میتوانید از این فایل ایده بگیرید.
- آپلود فایل دریافتی از یوتیوب به یک اکانت رایگان کالکتور در رپیدشیر. (ماخذ این مورد در سایت code projects)
مشخصات این اکانت رایگان کالکتور در فایل app.config باید ذکر شود.
این سورس میتونه ایدهی ابتدایی بسیاری از کارهای مشابه باشد. برای مثال ایجاد یک وب سرویس، یک وب سایت، یک سرویس ایمیلی و غیره.
پ.ن.
کار انجام شده فعالیت وارز محسوب نمیشود زیرا مجوز ویدیوهای سایت یوتیوب این امکان توزیع (و بسیاری موارد دیگر) را به شما میدهد.
using System; using System.Globalization; namespace ArabicDate { class Program { static void Main(string[] args) { var now = DateTime.Now; var date = now.ToString("d MMMM yyyy", new CultureInfo("ar-SA")); Console.WriteLine(date); } } }
9 صفر 1438
اگر به سایت http://time.ir مراجعه کنیم، امروز را «8 صفر» معرفی کردهاست.
سؤال: مشکل کجاست؟ آیا پیاده سازی تاریخ قمری در دات نت مشکل دارد؟
پاسخ: این مساله مرتبط به دات نت فریم ورک نیست و به تنظیمات ویندوز بر میگردد:
همانطور که در اینجا مشاهده میکنید، اگر به کنترل پنل، قسمت Region آن مراجعه کرده و در برگهی باز شده، بر روی دکمهی additional settings کلیک کنیم، امکان انتخاب تاریخ قمری هم وجود دارد و در اینجا به ازای روز جاری، 5 روز و تاریخ مختلف را میتوان انتخاب کرد (بسته به موقعیت جغرافیایی).
پس از این تنظیم است که قطعه کد فوق، تاریخ روز جاری را به قمری به نحو صحیحی نمایش میدهد.
خلاصه مهاجرت داده پروفایل ها
- کلاس جدیدی بسازید که دارای خواصی برای ذخیره اطلاعات پروفایل است.
- کلاس جدیدی بسازید که از 'ProfileBase' ارث بری میکند و متدهای لازم برای دریافت پروفایل کاربران را پیاده سازی میکند.
- استفاده از تامین کنندههای پیش فرض را، در فایل web.config فعال کنید. و کلاسی که در مرحله 2 ساختید را بعنوان کلاس پیش فرض برای خواندن اطلاعات پروفایل معرفی کنید.
شروع به کار
پوشه جدیدی با نام 'Models' بسازید تا اطلاعات پروفایل را در آن قرار دهیم.
بعنوان یک مثال، بگذارید تا تاریخ تولد کاربر، شهر سکونت، قد و وزن او را در پروفایلش ذخیره کنیم. قد و وزن بصورت یک کلاس سفارشی (custom class) بنام 'PersonalStats' ذخیره میشوند. برای ذخیره و بازیابی پروفایل ها، به کلاسی احتیاج داریم که 'ProfileBase' را ارث بری میکند. پس کلاس جدیدی با نام 'AppProfile' بسازید.
public class ProfileInfo { public ProfileInfo() { UserStats = new PersonalStats(); } public DateTime? DateOfBirth { get; set; } public PersonalStats UserStats { get; set; } public string City { get; set; } } public class PersonalStats { public int? Weight { get; set; } public int? Height { get; set; } } public class AppProfile : ProfileBase { public ProfileInfo ProfileInfo { get { return (ProfileInfo)GetPropertyValue("ProfileInfo"); } } public static AppProfile GetProfile() { return (AppProfile)HttpContext.Current.Profile; } public static AppProfile GetProfile(string userName) { return (AppProfile)Create(userName); } }
پروفایل را در فایل web.config خود فعال کنید. نام کلاسی را که در مرحله قبل ساختید، بعنوان کلاس پیش فرض برای ذخیره و بازیابی پروفایلها معرفی کنید.
<profile defaultProvider="DefaultProfileProvider" enabled="true" inherits="UniversalProviders_ProfileMigrations.Models.AppProfile"> <providers> ..... </providers> </profile>
برای دریافت اطلاعات پروفایل از کاربر، فرم وب جدیدی در پوشه Account بسازید و آنرا 'AddProfileData.aspx' نامگذاری کنید.
<h2> Add Profile Data for <%# User.Identity.Name %></h2> <asp:Label Text="" ID="Result" runat="server" /> <div> Date of Birth: <asp:TextBox runat="server" ID="DateOfBirth"/> </div> <div> Weight: <asp:TextBox runat="server" ID="Weight"/> </div> <div> Height: <asp:TextBox runat="server" ID="Height"/> </div> <div> City: <asp:TextBox runat="server" ID="City"/> </div> <div> <asp:Button Text="Add Profile" ID="Add" OnClick="Add_Click" runat="server" /> </div>
کد زیر را هم به فایل code-behind اضافه کنید.
protected void Add_Click(object sender, EventArgs e) { AppProfile profile = AppProfile.GetProfile(User.Identity.Name); profile.ProfileInfo.DateOfBirth = DateTime.Parse(DateOfBirth.Text); profile.ProfileInfo.UserStats.Weight = Int32.Parse(Weight.Text); profile.ProfileInfo.UserStats.Height = Int32.Parse(Height.Text); profile.ProfileInfo.City = City.Text; profile.Save(); }
دقت کنید که فضای نامی که کلاس AppProfile در آن قرار دارد را وارد کرده باشید.
اپلیکیشن را اجرا کنید و کاربر جدیدی با نام 'olduser' بسازید. به صفحه جدید 'AddProfileData' بروید و اطلاعات پروفایل کاربر را وارد کنید.
با استفاده از پنجره Server Explorer میتوانید تایید کنید که اطلاعات پروفایل با فرمت xml در جدول 'Profiles' ذخیره میشوند.
مهاجرت الگوی دیتابیس
اسکریپت مورد نیاز را از آدرس https://raw.github.com/suhasj/UniversalProviders-Identity-Migrations/master/Migration.txt دریافت کرده و آن را اجرا کنید. اگر اتصال خود به دیتابیس را تازه کنید خواهید دید که جداول جدیدی اضافه شده اند. میتوانید دادههای این جداول را بررسی کنید تا ببینید چگونه اطلاعات منتقل شده اند.
مهاجرت اپلیکیشن برای استفاده از ASP.NET Identity
- Microsoft.AspNet.Identity.EntityFramework
- Microsoft.AspNet.Identity.Owin
- Microsoft.Owin.Host.SystemWeb
- Microsoft.Owin.Security.Facebook
- Microsoft.Owin.Security.Google
- Microsoft.Owin.Security.MicrosoftAccount
- Microsoft.Owin.Security.Twitter
using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Web; using UniversalProviders_ProfileMigrations.Models; namespace UniversalProviders_Identity_Migrations { public class User : IdentityUser { public User() { CreateDate = DateTime.UtcNow; IsApproved = false; LastLoginDate = DateTime.UtcNow; LastActivityDate = DateTime.UtcNow; LastPasswordChangedDate = DateTime.UtcNow; Profile = new ProfileInfo(); } public System.Guid ApplicationId { get; set; } public bool IsAnonymous { get; set; } public System.DateTime? LastActivityDate { get; set; } public string Email { get; set; } public string PasswordQuestion { get; set; } public string PasswordAnswer { get; set; } public bool IsApproved { get; set; } public bool IsLockedOut { get; set; } public System.DateTime? CreateDate { get; set; } public System.DateTime? LastLoginDate { get; set; } public System.DateTime? LastPasswordChangedDate { get; set; } public System.DateTime? LastLockoutDate { get; set; } public int FailedPasswordAttemptCount { get; set; } public System.DateTime? FailedPasswordAttemptWindowStart { get; set; } public int FailedPasswordAnswerAttemptCount { get; set; } public System.DateTime? FailedPasswordAnswerAttemptWindowStart { get; set; } public string Comment { get; set; } public ProfileInfo Profile { get; set; } } }
انتقال داده پروفایلها به جداول جدید
آخرین نسخه پکیج Entity Framework را نصب کنید. همچنین یک رفرنس به اپلیکیشن وب پروژه بدهید (کلیک راست روی پروژه و گزینه 'Add Reference').
کد زیر را در کلاس Program.cs وارد کنید. این قطعه کد پروفایل تک تک کاربران را میخواند و در قالب 'ProfileInfo' آنها را serialize میکند و در دیتابیس ذخیره میکند.
public class Program { var dbContext = new ApplicationDbContext(); foreach (var profile in dbContext.Profiles) { var stringId = profile.UserId.ToString(); var user = dbContext.Users.Where(x => x.Id == stringId).FirstOrDefault(); Console.WriteLine("Adding Profile for user:" + user.UserName); var serializer = new XmlSerializer(typeof(ProfileInfo)); var stringReader = new StringReader(profile.PropertyValueStrings); var profileData = serializer.Deserialize(stringReader) as ProfileInfo; if (profileData == null) { Console.WriteLine("Profile data deserialization error for user:" + user.UserName); } else { user.Profile = profileData; } } dbContext.SaveChanges(); }
برخی از مدلهای استفاده شده در پوشه 'IdentityModels' تعریف شده اند که در پروژه اپلیکیشن وبمان قرار دارند، بنابراین افزودن فضاهای نام مورد نیاز فراموش نشود.
کد بالا روی دیتابیسی که در پوشه App_Data وجود دارد کار میکند، این دیتابیس در مراحل قبلی در اپلیکیشن وب پروژه ایجاد شد. برای اینکه این دیتابیس را رفرنس کنیم باید رشته اتصال فایل app.config اپلیکیشن کنسول را بروز رسانی کنید. از همان رشته اتصال web.config در اپلیکیشن وب پروژه استفاده کنید. همچنین آدرس فیزیکی کامل را در خاصیت 'AttachDbFilename' وارد کنید.
یک Command Prompt باز کنید و به پوشه bin اپلیکیشن کنسول بالا بروید. فایل اجرایی را اجرا کنید و نتیجه را مانند تصویر زیر بررسی کنید.
در پنجره Server Explorer جدول 'AspNetUsers' را باز کنید. حال ستونهای این جدول باید خواص کلاس مدل را منعکس کنند.
کارایی سیستم را تایید کنید