مطالب
نمایش تاریخ بر حسب تعداد روزهای گذشته
در بیشتر وب سایت‌های شاهد نمایش تاریخ بر حسب تعداد روز/ ماه و یا سال گذشته شده از آن تاریخ هستیم. برای نمونه در سایت جاری تاریخ را بر همین اساس نمایش می‌دهند. نمونه‌ای از آن مانند «در ‫۲ سال قبل، چهار شنبه ۲۷ دی ۱۳۹۱، ساعت ۰۳:۳۵» می‌باشد. در این مقاله قصد دارم کدهایی را جهت انجام این کار ارائه کنم. در این مثال که در ادامه شاهد آن خواهیم بود، از یک پروژه‌ی Win form ساده، جهت نمایش بهتر استفاده کرده‌ام.
جهت اینکه درک کد و یا توضیح آن نیز ساده‌تر صورت بگیرد، به نظرم ابتدا متد‌های مورد استفاده و کلاس‌هایی را که از آنها استفاده کرده‌ام، معرفی کنم بهتر باشد:
از کلاس Persiancalender جهت گرفتن روز/ماه و سال استفاده شده و سه متد به شرح زیر دارد:
GetHour : از این متد برای گرفتن ساعت تاریخ مورد نظر استفاده می‌شود. کد این متد به صورت زیر است:
 public string GetHour(DateTime lastdate)
        {
            PersianCalendar pc = new PersianCalendar();
            string result = " ساعت " + (((pc.GetHour(lastdate)) < 10) ? ("0" + pc.GetHour(lastdate).ToString()) : (pc.GetHour(lastdate)).ToString()) + ":" + (((pc.GetMinute(lastdate)) < 10) ? ("0" + pc.GetMinute(lastdate).ToString()) : (pc.GetMinute(lastdate)).ToString());
            return result;
        }
توضیح: اگر ساعت یا دقیقه تک رقمی باشد، یعنی کمتر از 10، برای نمایش بهتر آن یک صفر را به ابتدای آن اضافه می‌کنیم. یعنی ساعت 1:5 تبدیل می‌شود به 01:05
متد getDay : از این متد برای گرفتن نام روز مورد نظر استفاده می‌شود. ورودی این متد یک enum  از نوع DayOfWeek است:
public string getDay(DayOfWeek day)
        {
            string Result = "";
            switch (day)
            {
                case DayOfWeek.Friday:
                    Result = "جمعه";
                    break;
                case DayOfWeek.Monday:
                    Result = "دوشنبه";
                    break;
                case DayOfWeek.Saturday:
                    Result = "شنبه";
                    break;
                case DayOfWeek.Sunday:
                    Result = "یکشنبه";
                    break;
                case DayOfWeek.Thursday:
                    Result = "پنج شنبه";
                    break;
                case DayOfWeek.Tuesday:
                    Result = "سه شنبه";

                    break;
                case DayOfWeek.Wednesday:
                    Result = "چهارشنبه";
                    break;
                default:
                    break;
            }
            return Result;
        }
و در هر جایی نیاز به گرفتن تاریخ باشد، به صورت زیر عمل خواهیم کرد:
getDay(pc.GetDayOfWeek(LastDate))
pc یک متغییر از نوع persianclander می‌باشد.
متد GetMounth : همانطور که از نام این متد معلوم است، کار آن بازگشت نام ماه مورد استفاد است. کد آن نیز به صورت زیر می‌باشد:
public string GetMounth(int month)
        {
            string[] monthInYear = {"فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند" };
            return monthInYear[month-1];
        }
وجود -1 در هنگام return به این دلیل است که زمانیکه قصد دریافت شماره ماه را از شیء PersianClander داشته باشیم، از یک شروع می‌شود. یعنی برای ماه اسفند مقدار 12 و برای ماه فروردین مقدار 1 و در یک آرایه، ایندکس‌ها از صفر شروع می‌شوند.
و اما کد کامل آن برای تبدیل تاریخ، به صورت رشته مورد نظر، به صورت زیر است:
private void btnGetDate_Click(object sender, EventArgs e)
        {
            DateTime LastDate = DateTime.Parse(txtLastDate.Text);
            TimeSpan ts = DateTime.Now - LastDate;
            PersianCalendar pc = new PersianCalendar();
            int DifferenceYear = DateTime.Now.Year - LastDate.Year;
            int DiffernceMounth = DateTime.Now.Month - LastDate.Month;
            if(DateTime.Now.Month>LastDate.Month)
                DiffernceMounth = DateTime.Now.Month - LastDate.Month; 
            else
            DiffernceMounth=LastDate.Month-DateTime.Now.Month;
            int DifferenceDays = ts.Days;

            StringBuilder Result = new System.Text.StringBuilder("");
           
            if(DifferenceYear>0)
            {
                Result.Append(DifferenceYear.ToString() + " سال پیش"+" ، "+getDay(pc.GetDayOfWeek(LastDate))+" "+pc.GetDayOfMonth(LastDate).ToString()+" " + GetMounth(pc.GetMonth(LastDate))+" " +pc.GetYear(LastDate)+GetHour(LastDate));
            }
            else if(DiffernceMounth>0)
            {
                Result.Append(DiffernceMounth.ToString() + " ماه پیش" + " ، " + getDay(pc.GetDayOfWeek(LastDate)) + " " + pc.GetDayOfMonth(LastDate).ToString() + " " + GetMounth(pc.GetMonth(LastDate)) + " " + pc.GetYear(LastDate) + GetHour(LastDate));
            }
            else if(DifferenceDays>0)
                Result.Append(DifferenceDays.ToString() + " روز پیش" + " ، " + getDay(pc.GetDayOfWeek(LastDate)) + " " + pc.GetDayOfMonth(LastDate).ToString() + " " + GetMounth(pc.GetMonth(LastDate)) + " " + pc.GetYear(LastDate) + GetHour(LastDate));
            else if(DifferenceDays==0)
                Result.Append(" امروز" + " ، " + getDay(pc.GetDayOfWeek(LastDate)) + " " + pc.GetDayOfMonth(LastDate).ToString() + " " + GetMounth(pc.GetMonth(LastDate)) + " " + pc.GetYear(LastDate) + GetHour(LastDate));

            lblResult.Text = Result.ToString();
        }
کد زیر برای دریافت تعداد اختلاف بین ماه‌ها، از تاریخی گذشته تا تاریخ جاری است:
if(DateTime.Now.Month>LastDate.Month)
                DiffernceMounth = DateTime.Now.Month - LastDate.Month; 
            else
            DiffernceMounth=LastDate.Month-DateTime.Now.Month;
چرا از if استفاده شده است؟ فرض کنید تاریخ امروز 2/12/2015 باشد و تاریخی که قصد تبدیل آن را داریم :10/12/2014 است. تعداد اختلافی که بین تعداد ماه‌ها است 8 ماه است و اگر این بررسی چک کردن بزرگ بودن آن دو انجام نشود، مقدار 8- را بر میگرداند که برای کار ما نادرست است.
نمونه‌ای از این تبدیل :
نظرات مطالب
Blazor 5x - قسمت 34 - توزیع برنامه‌های Blazor بر روی IIS
با سلام؛ پروژه بصورت WASM+Web API رو تغییر دادم و دات نت اون هم به  ورژن 7  ارتقا دادم. در موقع توسعه و محیط VS، برنامه بدون هیچ مشکلی کار میکند ولی بعد از publish و مستقر شدن در IIS خطای زیر صادر میکند.
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Arg_NoDefCTor, Wasm.Shared.MainLayout
System.MissingMethodException: Arg_NoDefCTor, Wasm.Shared.MainLayout
   at System.RuntimeType.CreateInstanceMono(Boolean , Boolean )
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean , Boolean )
   at System.Activator.CreateInstance(Type , Boolean , Boolean )
   at System.Activator.CreateInstance(Type , Boolean )
   at System.Activator.CreateInstance(Type )
   at Microsoft.AspNetCore.Components.DefaultComponentActivator.CreateInstance(Type )
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider , Type )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateComponent(Type )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& , Int32 , Int32 , Int32 , Int32 )
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer , RenderBatchBuilder , Int32 , ArrayRange`1 , ArrayRange`1 )
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder , RenderFragment , Exception& )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry )
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() blazor.webassembly.js:1:38555
پس از بررسی متوجه شدم مشکل از CascadingAuthenticationState هست. وقتی فایل App.razor بصورت زیر هست خطا بر طرف میشود.
<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>
ولی بصورت زیر بعد از پابلیش خطا صادر میکند.
 <CascadingAuthenticationState>
      <Router AppAssembly="typeof(App).Assembly"  PreferExactMatches="true">
          <Found Context="routeData">
          <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                    <Authorizing>
                        <FocusOnNavigate RouteData="@routeData" Selector="h1"/>
                    </Authorizing>
                    <NotAuthorized>

                      @*  <RedirectToLogin/>*@


                    </NotAuthorized>
                </AuthorizeRouteView>
            </Found>
            <NotFound>
                <LayoutView Layout="@typeof(MainLayout)">
                      <span>Error</span>
                 </LayoutView>
            </NotFound>
        </Router>
    </CascadingAuthenticationState>
مطالب
آشنایی و بررسی ابزار Version Manager
در مطلبی با نسخه بندی و چرخه انتشار نرم افزار آشنا شدید. اما کمبود ابزاری کارآمد و حرفه ای در ویژوال استادیو من را بر آن داشت تا افزونه‌ای را تهیه و در دسترس تمامی توسعه دهندگان قرار دهم. پس از مطالعه و بررسی روش‌های نگارش بندی نرم افزار و ابزار‌های موجود، دو روش عمده نسخه بندی نرم افزار وجود دارد که در زیر آورده شده است.
  • نسخه بندی معنایی
  • نسخه بندی استاندارد مایکروسافت
در روش معنایی چهار قسمت نسخه بندی Major.Minor.Build.Revision به صورت زیر افزایش و تغییر می‌یابد:
  1. Revision تا 1000 افزایش می‌یابد
  2. در اجرای بعدی به 0 تنظیم شده و قسمت Build بعلاوه 1 می‌شود.
  3. Build تا 100 افزایش می‌یابد
  4. در اجرای بعدی Build به 0 تنظیم شده و قسمت Minor بعلاوه 1 می‌شود و Revision هم 0 می‌شود.
  5. Minor تا 10 افزایش می‌یابد.
  6. در اجرای بعدی Minor به 0 تنطیم شده، قسمت Major بعلاوه 1 می‌شود و قسمت‌های قبل همه 0 می‌شوند. 
در روش استاندارد ماکروسافت مقادیر قسمت‌های Build و Revision از الگوریتم زیر محاسبه می‌شود.
  1. مقدار Build از مجموع روزهای که از تاریخ پروژه گذشته است بدست می‌آید.
  2. مقدار Revision از مجموع ثانیه‌های که از نیمه شب محلی روز جاری تا زمان اجرای پروژه تقسم بر دو بدست می‌آید.
  3. مقادیر Major و Minor هم با توجه تولید نسخه جدید و تغییرات عمده در نرم افزار بصورت دستی تغییر می‌یابد.
راهنمای نصب و اجرا:
ابتدا افزونه Version Manager را از سایت ویژوال استادیو گالری دریافت و نصب کنید.
سپس از منوی View > Other Windows > Version Manager را انتخاب کنید.

پس از باز شدن پنجره Version Manager پروژه‌های Solution جاری بارگذاری و  Assembly Version و File Version هر پروژه را می‌توانید به راحتی مشاهده و یا تغییر دهید.

اگر بخواهید بصورت خودکار بر اساس شمای انتخاب شده، نسخه نرم افزار را افزایش دهید، شمای نسخه بندی را انتخاب کنید. در دو زمان Build و یا Rebuild پروژه می توان نسخه را افزایش داد.

Semantic Versioning:

  1. گزینه Semantic Versioning را از قسمت Version Style انتخاب کنید.
  2. گزینه Increment Action قسمتی از نگارش که می‌خواهید شمای  نسخه بندی بر روی آن اعمال شود را مشخص می‌کند. که دو گزینه Build یا Revision وجود دارد
  3. گزینه Increment Event زمان رویداد اعمال شمای انتخاب شده را مشخص می‌سازد.
  4. تنظیمات را ذخیره و پروژه خود را Rebuild نمایید.
  5. در پنجره Output نسخه جدید نشان داده می‌شود.

Microsoft DateTime:

  1. گزینه Microsoft DateTime را از قسمت Version Style انتخاب کنید.

  2. تاریخ شروع پروژه بصورت خودکار خوانده و نمایش داده می‌شود یا تاریخ شروع پروژه را انتخاب کنید
  3. با توجه به انتخاب Increment Action نسخه جدید محاسبه می‌شود.
  4. پروژه را Rebuild و نسخه جدید را مشاهده نمایید.

    همچنین از پروژه‌های #C و VB.NET و C++ Managed  پشتیبانی می‌کند

    این ابزار هنوز در نگارش بتا است و ممکن است باگ‌هایی داشته باشد.

    نظرات و پیشنهادات شما توسعه دهندگان عزیز می‌تواند موجب هر چه بهتر و کامل‌تر شدن این ابزار باشد.

نظرات اشتراک‌ها
دوراهی انتخاب NHibernate و Entityframework
استفاده از EF برای ارتباط با Oracle واقعا عذاب آور است.
در یکی از پروژه‌ها که بانک اطلاعاتی oracle و نرم افزار asp.net بود مجبور شدیم از همان sqlHelper‌ها استفاده کنیم. حتی در یک برنامه تستی برای یک select ساده از یک جدول با یک میلیون رکورد تفاوت فاحشی بین ado.net و EF5 وجود داشت (100 میلی ثانیه در مقابل 2 ثانیه با رعایت Initialize‌های EF در حالی که خروجی EF در پروفایلر هم همان کوئری بود).

اشتراک‌ها
کتابخانه‌ای برای تغییر تصاویر وب‌سایت به صورت هوشمند؛ جهت بهبود کارآیی و سرعت
در حال حاضر قابلیت‌هایی که لایبری دارد:
  • تغییر عرض عکس
  • تغییر ارتفاع عکس
  • تغییر فرمت عکس
    • png
    • jpg
    • jpeg
  • چرخش اتوماتیک
  • تغییر کیفیت عکس (0-100)
  • کش در مموری
  • بعد از تغییر عرض و ارتفاع با هم انتخاب مود مورد نظر
    • pad
    • max 
    • crop 
    • stretch 
قابلیت‌هایی  که در آینده اضافه خواهند شد:
  • کش در دیسک (که بسیار مهم خواهد بود)
  • اضافه کردن واتر مارک
  • و بهبود کارآیی پکیج
کتابخانه‌ای برای تغییر تصاویر وب‌سایت به صورت هوشمند؛ جهت بهبود کارآیی و سرعت
اشتراک‌ها
کتابخانه juliusjs
A speech recognition library for the web  Demo
  • Real-time transcription
    • Use the provided grammar, or write your own
  • 100% JavaScript implementation
    • All recognition is done in-browser through a Worker
    • Familiar event-inspired API
    • No external server calls
کتابخانه juliusjs
اشتراک‌ها
کتاب رایگان jQuery Trickshots
In this book, you will find 100 advanced jQuery techniques that we have developed over the years as JavaScript programmers and authors for Tutorialzine, presented as easy to understand tips.
کتاب رایگان jQuery Trickshots
نظرات مطالب
ایندکس منحصر به فرد با استفاده از Data Annotation در EF Code First
در EF 6.2 امکان تعریف ایندکس‌ها توسط Fluent API هم (علاوه بر Attributes) میسر شده‌است:
public class MyContext: DbContext
{
        public DbSet<Person> People { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>().Property(p => p.Name).HasMaxLength(100);
            modelBuilder.Entity<Person>().HasIndex(p => p.Name).IsUnique();
        }
}
نظرات مطالب
ایجاد ایندکس منحصربفرد در EF Code first
در EF 6.2 امکان تعریف ایندکس‌ها توسط Fluent API هم (علاوه بر Attributes) میسر شده‌است:
public class MyContext: DbContext
{
        public DbSet<Person> People { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>().Property(p => p.Name).HasMaxLength(100);
            modelBuilder.Entity<Person>().HasIndex(p => p.Name).IsUnique();
        }
}