آی تی نرد

اشتراک اطلاعات و تجربیات در زمینه ی توسعه ی دات نت و البته شیرپوینت

تاریخ و زمان شمسی در MVC بدون نیاز به استفاده از تمپلیت

shamsi datetime

حل مشکل تاریخ و زمان شمسی در اکثر پروژه های نرم افزاری که کار میکنیم یک کار مازاد به شمار میاد که باید در گوشه ای از ذهنمون در نظر داشته باشیم و معمولا هم در انتهای پروژه نسبت به رفع اون اقدام میکنیم. البته هر کسی روشی داره و بالاخره این مشکل رو حل میکنه. خود من یادم هست که حدود 8 الی 9 سال پیش قسمت های سال و ماه و روز تاریخ شمسی رو به صورت عددی کنار هم میچسبوندم و توی جدول نگهداری میکردم که البته کار اشتباهی بود.

بهترین روش این هست که هر مقداری معادل کاربردش در سیستم و با نوع متناسب نگهداری بشه و مقادیر در زمان و لایه ی نمایش تغییر کنند. به هر حال مثلا وقتی میگیم تاریخ تولد، نوعش هم باید تاریخ باشه.

توی پروژه های MVC معمولا برای حل این مسئله یک تمپلیت برای نمایش و یکی هم برای ویرایش(که در نهایت مقدار به سرور ارسال میشود) استفاده می کنیم که در تمپلیت نمایش(DisplayTemplate) تاریخ رو تبدیل میکنیم و بعد نشون میدیم و در ویرایش(EditorTemplate) هم به همین صورت اما فقط مقدار میلادی رو توی یک فیلد مخفی نگهداری میکنیم و بعد در زمان Submit اون مقدار رو ارسال میکنیم. خود این کارها واقعا وقت گیر، حوصله بر، دست و پاگیر و اضافی هست، البته در نهایت برای انتخاب تاریخ مجبوریم از یک DatePicker در EditorTemplate استفاده کنیم ولی همانطور که در ادامه میخونید دیگر نگرانی تبدیل اون از شمسی به میلادی رو در سمت کلاینت رو نخواهیم داشت.

به نظر من بهترین کار این هست که تمامی این تبدیل ها رو به قسمتی از سیستم بدیم و بزاریم خودش تشخیص بده و مدیریت کنه و ما هم این مشغله رو از ذهنمون دور بندازیم.

توی یکی از مطالبم مقدمه ای در مورد کالچر در Asp.net Web form و سیستم Blogengine نوشتم که از همون استراتژی هم میشه توی MVC استفاده کرد به هر حال هر دو زیرساخت Asp.net رو دارند اما فقط نحوه ی پیاده سازی برخی ساختارهای زیرین در دو تکنولوژی متفاوت هست.

بیشتر...

بیش از 1000 متد کاربردی - C# Extension Methods Library

امروز توی صفحه ی اول کدپلکس مشغول بررسی برنامه ها و کتابخانه ها بودم که با یک کتابخانه ی کد #c بسیار عالی مواجه شدم. این کتابخانه ی کد شامل بیش از 1000 متد Extension کاربردی هست که سرعت کد نویسی رو وقعا زیاد میکنه.

بعضی وقتها نوشتن یک متد ساده که یک خط کد داره میتونه خیلی جاها به برنامه نویس کمک کنه و اگر برنامه نویس حرفه ای باشید واقعا دوست ندارید کدهای تکراری و ساده بنویسید. برای مثال متد اکستنژن زیر رو ببینید(البته این مربوط به این کتابخانه نیست ولی شاید همچین متدی داشته باشه متد زیر رو من به مسئول این کتابخانه پیشنهاد دادم و ایشان هم خوششان آمد و قرار شد به کتابخانه اضافه بشه البته تحت عنوان ToStringSafe):

      public static string ToStringForce(this object obj)
      {
         return obj == null ? "" : obj.ToString();
      }

خب همین متد ساده که وظیفه ی اون کاملا مشخص هست خیلی جاها از جمله زمان نوشتن کد Lambda خیلی کاربردی میتونه باشه. حالا تصور کنید بیش از 1000 تا از این متدها داشته باشید واقعا یک جعبه ابزار مفید برای یک برنامه نویس #c محسوب میشه.

برخی از متدها رو میتونید در تصاویر زیر ببینید:

Object extension:

Database extension:

 String extension:

میتونید برای مشاهده ی لیست کامل متدها و دانلود آن به آدرس های زیر در کدپلکس مراجعه کنید:

http://zextensionmethods.codeplex.com/
http://zextensionmethods.codeplex.com/releases/view/117295

نکات برنامه نویسی Timer Job ها در شیرپوینت

در شیرپوینت برخی از کارهای اساسی و سنگین که نیاز به اجرا شدن دوره ای و یا به دلیل طولانی بودن فرایند و پردازش می بایست باعث متوقف شدن محیط اصلی شیرپوینت نشوند از طریق سرویس ویندوزی به نام SharePoint Timer به صورت زمانبندی شده اجرا و پردازش می شوند.

شیرپوینت با فراهم کردن آبجکت مدلی شرایط ایجاد و کار با این سرویس را مهیا نموده است. به این صورت که میتوان از طریق این آبجکت مدل نمونه های جدید زمانبندی شده ای از این سرویس را ایجاد کرد که به اصطلاح فنی به ان Job گفته میشود.

جاب ها در سطح Web Application تعریف و ایجاد میشوند و مدیریت آنها تنها از طریق سنترال ادمین و با دسترسی مدیر فارم امکان پذیر می باشد. برای ایجاد و مدیریت نمونه ی جدید جاب از طریق آبجکت مدل مهیا شده می بایست شرایط زیر حتما فراهم شده باشد:

  • اجرای این کدها در سروری که شیرپوینت در ان نصب می باشد.
  • کدها یا آبجکت مدل مورد نظر می بایست ابتدا حتما در GAC قرار داشته باشند.
  • ایجاد نمونه ی جدید جاب با دسترسی کاربر مدیر فارمی که بتواند در حالت نرمال و از طریق سنترال ادمین جاب ها را مدیریت کند.
  • یکی بودن Application Pool محیطی که در ان قرار هست جاب اجرا یا ایجاد شود با سنترال ادمین. برای مثال App Pool سایت کالکشن ایکس با سنترال ادمین یکی باشد.(که البته این کار از نظر توپولوژی و استاندارد های شیرپوینت مشکل دارد.)

البته باید اعتراف کرد که فراهم کردن این شرایط مقداری مشکل و باعث کاهش میزان استفاده از این جاب ها می شود.

معمولا در راهکارهایی که در سطح فارم نوشته میشوند و برای رفع نیاز اجرای دوره ای فرایندی که می بایست در پیش زمینه ی شیرپوینت اچرا شود استفاده میشود.

تمام این راهکارها که می بایست از طریق مدیر فارم نصب و دیپلوی بشند می بایست Feature یا ویژگی انها نیز در سطوح مختلف سایت و یا مجموعه سایت فعال یا غیر فعال شوند که در این حالت در صورتی که از این جاب ها استفاده شده باشد به احتمال قریب به یقین با توجه به شرایطی که قبلا گفته شد با مشکل دسترسی مواجه خواهد شد.

بیشتر...

استفاده از ماژول Ninject.Extensions.Factory و الگوی Factory در زمان اعتبارسنجی Model در MVC

استفاده از الگوی Repository و پیاده سازی Dependency Injection با استفاده از کتابخانه ی Ninject برروی یک پروژه ی نسبتا بزرگ MVC بسیار کارامد خواهد بود.
به هرحال هر کدوم از این الگوها مزایای مربوط به خودش رو خواهد داشت. استفاده از الگوی اشاره شده به مراتب بیشتر از الگوهای دیگر در برنامه هایی که محوریت بیشتر آن برروی استفاده و تحلیل داده ها در بانک های اطلاعاتی هست می باشد، و استفاده از Ninject هم که مزایای خودش رو به این پروژه اضافه خواهد کرد.

بخش مهم اعتبارسنجی داده ها قبل از افزوده شدن به منبع ذخیره سازی نهایی مورد توجه است، در کلاس های Metadata که از طریق Attribute ها یا DataAnnotations اعتبار سنجی های اولیه صورت میگیرد زمانی نیاز به پیاده سازی یک اعتبارسنجی سفارشی و استفاده از Repository و استخراج داده های مورد نیاز به عنوان بخشی از این اعتبارسنجی می باشد. که متاسفانه عملیات ایجاد نمونه ی جدید کلاس Repository از طریق Field Injection یا هر نوع دیگری از Injection صورت نمی گیرد و با خطای null reference exception مواجه خواهید شد.

برای روشن کردن توضیحاتم یه مثال بزنم:
سناریویی رو در نظر بگیرید که در اون مشتری میخواد یک محصول رو خریداری کنه، اما باید بررسی بشه که اگر در لحظه ی خرید، تعداد محصول برابر با 0 هست پیغام خطای مناسب نمایش داده شود.
بنابراین ما یک کلاس Customer و یک کلاس Product که مربوط به اعتبارسنجی می باشد به شکل زیر خواهیم داشت،

بیشتر...

متد استخراج یا یافتن لیست و فیلد توسط مقادیر مختلف در شرپوینت

یکی از مشکلاتی که یک برنامه نویس شرپوینت باهاش زیاد مواجه میشه دسترسی و استخراج یا یافتن یک آبجکت شرپوینتی مانند لیست یا فیلد هست.
یه مفهومی که همیشه وجود داره این هست که اضافه کردن لایه های مختلف و دور کردن برنامه نویس از لایه های پایین هم باعث راحتی برنامه نویس و هم سختی بیش از حد اون خواهد شد.
برای مثال در Asp.Net Web Forms وجود لایه های بسیار برای راحتی کار برنامه نویس مثل داشتن کنترل های سروری به قیمت سختی یافتن مشکل و همچنین سنگین شدن برنامه ی نهایی تمام خواهد شد.

در این مورد برای دسترسی به یک لیست شرپوینت و عملیات برروی آن نیاز هست تا برنامه نویس مشخصاتی از قبیل نام نمایشی(DisplayName) یا نام ثابت(StaticName) و یا نام داخلی(InternalName) و یا شناسه ی لیست(ID or Guid) را داشته باشد.

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

بیشتر...