نظرات مطالب
ASP.NET MVC #19
اگر قرار هست layout به ازای هر کاربر مختلف، جداگانه کش شود و در آن layout، اطلاعات خاص هر کاربر درج شده که از هر کاربر به کاربر دیگری متفاوت است (تنها دلیل منطقی کش نکردن layout) باید varyByCustom را مقدار دهی و پیاده سازی کرد. برای مثال یک پروفایل مخصوص را در web.config تعریف می‌کنید:
<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="Dashboard" duration="86400" varyByParam="*" varyByCustom="User" location="Server" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>
جایی که قرار است view نمایش داده شود، این پروفایل را تنظیم خواهید کرد (در MVC کار نمایش View از View شروع نمی‌شود):
[OutputCache(CacheProfile="Dashboard")]
public class DashboardController : Controller { ...}
سپس باید در فایل global.asax.cs پیاده سازی و مقدار دهی varyByCustom، به ازای کاربران مختلف لاگین شده، انجام شود:
    //string arg filled with the value of "varyByCustom" in your web.config
    public override string GetVaryByCustomString(HttpContext context, string arg)
    {
        if (arg == "User")
             {
             // depends on your authentication mechanism
             return "User=" + context.User.Identity.Name;
             //?return "User=" + context.Session.SessionID;
             }

        return base.GetVaryByCustomString(context, arg);
    }
به این صورت view رندر شده، به ازای هر کاربر لاگین شده به صورت جداگانه کش می‌شود و این کش شدن به صورت عمومی، برای تمام کاربران و به یک شکل نیست.
نظرات مطالب
نحوه ایجاد یک تصویر امنیتی (Captcha) با حروف فارسی در ASP.Net MVC
ممنون. میشه قسمت بررسی نهایی در اکشن متد رو هم کپسوله کرد (چیزی شبیه به امکانات AOP سرخود در MVC). مثلا یک ویژگی جدید به نام ValidateCaptcha درست کرد که به اکشن متد اعمال شود و کار بررسی صحت اطلاعات ورودی مخصوص Captcha رو انجام و نهایتا اطلاعات ModelState رو بر اساس اطلاعات ورودی و Session ایی که در اینجا تعریف شده، به روز کنه:
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ValidateCaptchaAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var controllerBase = filterContext.Controller;

            var captchaInputTextProvider = controllerBase.ValueProvider.GetValue("CaptchaInputText");
            if (captchaInputTextProvider == null)
            {
                controllerBase.ViewData.ModelState.AddModelError("CaptchaInputText", "لطفا تصویر امنیتی را وارد کنید");
                base.OnActionExecuting(filterContext);
                return;
            }
            var inputText = captchaInputTextProvider.AttemptedValue;

            if (inputText != Session["captchastring"].ToString())
               controllerBase.ViewData.ModelState.AddModelError("CaptchaInputText", "تصویر امنیتی را اشتباه وارد کرده اید");
         } 
     }
به این صورت (با استفاده از ویژگی فوق) همان بررسی متداول ModelState.IsValid در یک اکشن متد کافی خواهد بود.
نظرات مطالب
آشنایی با Refactoring - قسمت 4
در مورد Active Record موافقم و هرگز هم از این الگو استفاده نکرده‌ام. در مورد Attached Property هم با مکانیزم آن آشنا هستم و استفاده‌های متفاوت تری از Layouting همچون اعمال Security توسط AP بر روی یک المان را تجربه کردم که انصافاً طراحی هوشمندانه AP را برایم آشکار کرد اما تصور می‌کنم برخی از موارد مانند hiding و حتی overriding در مورد AP و Dependency Property ها رعایت نمی‌شود (شاید انتظار overriding درست نباشد جون AP و DP ففط مخصوص ذخیره‌سازی هستند). مثلا شما می‌توانید با دستور GetValue مقدار یک خصیصه از جنس DP یک شی را در خارج از آن شی به دست آورید در حالی که اگر بخواهید از خاصیت Binding استفاده کنید استفاده از DP توصیه شده. البته امتحان نکرده‌ام اما فکر می‌کنم با protected کردن متغییرهای static مربوط به DP به این حالت دست یافت اما فکر می‌کنم بازهم از سطح private محروم می‌مانیم.

در نهایت در مورد Active Record و Entity ها صحبتهایتان را با این جمله کامل کردید که: «این نوع کلاس‌ها فقط اهداف display / reference دارند و نه بیشتر ... این‌ کلاس‌ها (کلاسهایی که در پست تعریف شده بود/م) هیچکدام در رده تعریف POCO یا Plain old .Net classes قرار نمی‌گیرند.»
نظرات مطالب
یکسان سازی ی و ک دریافتی حین استفاده از NHibernate
سلام
کاری که اکسس در اینجا کرده یا SQLite ایی که مثال زدم، مرتب سازی بر اساس کدهای یونیکد این حروف است و کار صحیحی (در بدو امر حداقل) انجام شده: (+)

کد یونیکد "ک" عربی = 1603
کد یونیکد "ی" عربی = 1610
کد یونیکد "ک" فارسی = 1705
کد یونیکد "ی" فارسی = 1740

یعنی این مرتب سازی بر اساس منطق ریاضی صحیح است؛ اما بر اساس فرهنگ ایران خیر. به همین جهت توسعه دهنده‌های بانک‌های اطلاعاتی مجبور شده‌اند تا مفهومی به نام Collation را ارائه بدهند که در بالا در مورد آن بحث شد. این Collation دیگر صرفا بر اساس منطق ریاضی کدهای یونیکد حروف، مرتب سازی را انجام نمی‌دهد، بلکه بر اساس ادبیات و فرهنگ زبان‌های مختلف کار مرتب سازی را انجام خواهد داد. SQL Server در این زمینه حداقل برای فارسی زبان‌ها یک Collation مخصوص را در نگارش 2008 خودش ارائه داده تا مرتب سازی صورت گرفته روی رشته‌ها دقیقا مطابق فرهنگ و ادبیات ایرانی باشد (برای سایر کشورها هم این نوع Collation ها پیش بینی شده).
در اکسس که مد نظر شما است این Collation به نام General Sort order مهیا است (در اکسس‌های جدید در قسمت فایل، options و سپس برگه‌ی general قسمتی هست به نام new database sort order که همین collation است) (+)
و اگر در این مورد خاص درست کار نمی‌کند باید با مایکروسافت مکاتبه کرد و این مسایل را توضیح داد.
مطالب
روش نامگذاری Smurf ایی!
اگر به یک سری از کتابخانه‌ها دقت کنید، تمام کلاس‌های آن‌ها دارای یک پیشوند تکراری هستند؛ مثلا SmurfXMLDataRow، SmurfXMLElement و الی آخر در مورد تمام کلاس‌های موجود در پروژه. به این رویه «Smurf Naming Convention» گفته می‌شود!
در این نوع کتابخانه‌ها زمانیکه کاربری بر روی دکمه‌ای کلیک می‌کند، SmurfAccountView اطلاعات SmurfAccountDTO را به SmurfAccountController منتقل می‌کند. در ادامه از خاصیت SmurfID دریافتی، مقدار SmurfOrderHistory دریافت شده و به SmurfHistoryReportingView جهت نمایش ارسال خواهد شد. اگر استثنای SmurfErrorEvent رخ دهد، توسط SmurfErrorLogger در فایلی به نام log/smurf/smurflog.log ثبت خواهد شد.

کلمه Smurf هم از شخصیتی کارتونی به همین نام اخذ شده است که در زبان مخصوص آن‌ها اکثر افعال و نام‌ها از کلمه Smurf مشتق می‌شود! برای مثال در مورد ماهیگیری کردن در یک رودخانه عنوان می‌کنند «We're going smurfing on the River Smurf today».


خوب، چکار باید کرد؟ روش صحیح معرفی نام یک شرکت در حین طراحی و نامگذاری کلاس‌های یک کتابخانه چیست؟
در مطلب بسیار جامع و عالی «اصول و قراردادهای نام‌گذاری در دات‌نت» عنوان شده است که اساس نام‌گذاری فضاهای نام باید از قاعده زیر پیروی کند:
<Company>.<Technology|Produt|Project>[.<Feature>][.<SubNamespace>]
مثلا مایکروسافت یکبار فضای نام Microsoft.Reporting.WebForms را تعریف کرده است و ... همین! دیگر به ابتدای هر کلاسی در این کتابخانه، پیشوند Microsoft یا MS و امثال آن اضافه نشده است تا بر روی اعصاب و روان استفاده کننده تاثیر منفی داشته باشد.

 
مطالب
خلاصه اشتراک‌های روز جمعه 8 مهر 1390
مطالب
به روز رسانی مهم تمام برنامه‌های ASP.NET WebForms و همچنین SharePoint

این روزها توسعه دهندگان مرورگرها، شماره‌های نگارش‌های برنامه‌های خود را مرتبا و با اعداد نجومی بالا می‌برند. امروز فایرفاکس 5، تا چند وقت دیگر فایرفاکس 8 هم در راه خواهد بود؛ سایر مرورگرها نیز به همین ترتیب. به همراه نگارش‌های متفاوت دات نت، یک سری browser definition files نیز وجود دارد که تنها بازه‌ی محدودی از این شماره نگارش‌ها در آن‌ها تعریف شده است. در نتیجه زمانیکه مثلا مرورگر کاربر IE 10 باشد، آن‌را به عنوان unknown browser تشخیص داده و یک سری از قابلیت‌ها را به صورت خودکار حذف می‌کند. برای مثال جاوا اسکریپت برای این نوع مرورگرها خاموش می‌شود. منظور از خاموش کردن جاوا اسکریپت این است که موتور ASP.NET Webforms دیگر یک سری اسکریپت‌های تولیدی مخصوص خود را به صفحه تزریق نخواهد کرد؛ برای مثال تمام PostBackهای سایت شما از کار خواهند افتاد و مسایلی از این دست.

روش حل آن هم ساده است. باید فایل‌های firefox.browser و ie.browser به روز شده را در پوشه‌ی استاندارد App_Browsers کپی کنید و همین!
به زودی یک آپدیت دات نت نیز جهت به روز رسانی در سطح ماشین، ارائه خواهد شد. فعلا مجبور هستید به ازای تک تک برنامه‌های خود این پوشه‌ی به روز شده را کپی کنید.

جهت توضیحات بیشتر و دریافت فایل‌‌های ذکر شده به این مطلب مراجعه نمائید.


مطالب
معرفی چهار افزودنی رایگان Visual Studio.NET

توسط این ابزار متدهای شما به ترتیب حروف الفباء مرتب شده و همچنین متدهای عمومی و خصوصی در region های مخصوص خود به صورت خودکار قرار خواهند گرفت.


نحوه عملکرد آنرا در اینجا مشاهده نمائید.

این افزودنی در حقیقت یک افزودنی جهت ReSharper به‌شمار می‌رود و کار آن بررسی اصول نامگذاری صحیح متغیرها، توابع و امثال آن است. همچنین کار غلط گیری املایی را نیز انجام می‌دهد.



تیم‌های داخلی مایکروسافت از این ابزار برای یک دست سازی سورس‌های تیم‌های مختلف استفاده می‌کنند.
هرچند عده‌ای این قوانین را بیش از اندازه سخت گیرانه می‌دانند!


همچنین اگر علاقمند باشید که StyleCop را به صورت خودکار و در زمان تایپ سورس استفاده کنید (حالت فعلی آن به صورت دستی است و باید برای مثال بر روی صفحه کلیک راست کرد و از منوی ظاهر شده گزینه مربوطه را انتخاب و اجرا نمود)، افزودنی دیگری برای ReSharper طراحی شده است که اینکار را برای شما انجام می‌دهد:
http://www.codeplex.com/StyleCopForReSharper/

اگر هم تمایل به غیر فعال کردن افزودنی‌های ReSharper را داشتید، می‌توان به منوی مربوطه در VS.Net مراجعه کرد و آنها را غیرفعال نمود (ReSharper->plugins).


نظرات مطالب
اعتبارسنجی مبتنی بر کوکی‌ها در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
یک نکته‌ی تکمیلی: RedirectUri در SignInAsync نیاز به encoding دارد.

روشی که در مطلب جاری مطرح شده، در برنامه‌های Blazor SSR هم قابل استفاده‌است و جهت سهولت بازگشت از صفحه‌ی لاگین به صفحه‌ی قبلی، می‌توان از خاصیت RedirectUri آن بدون نیاز به هیچ متد دیگری استفاده کرد:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, cookieClaims,
            new AuthenticationProperties
            {
                // ...
                RedirectUri = GetSafeRedirectUri(ReturnUrl)
            });
پیاده سازی متد GetSafeRedirectUri را در اینجا می‌توانید مشاهده کنید که هدف از آن، مقاومت در برابر حملات Open redirect است. فقط ... نکته‌ی مهمی که در اینجا لحاظ شده، encoding آن است که بدون آن، به خطای زیر خواهیم رسید:
Unhandled exception rendering component: Invalid non-ASCII or control character in header: 0x062A 
System.InvalidOperationException: Invalid non-ASCII or control character in header: 0x062A at 
void Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ThrowInvalidHeaderCharacter(char ch)
فرض کنید که RedirectUri نهایی، به همراه حروف فارسی است. چون متد HttpContext.SignInAsync از هدرهای HTTP برای انجام هدایت به صفحه‌ای دیگر استفاده می‌کند،‌ مقادیر این هدرها نمی‌توانند یونیکد باشند و حتما باید encode شوند و اگر اینکار انجام نشود، هر از چندگاهی با خطای فوق مواجه خواهیم شد. متد ویژه‌ی UriHelper.Encode، دقیقا جهت encoding آدرس‌های وب، مخصوص قرارگیری در هدرهای HTTP طراحی شده‌است.