نظرات مطالب
میان‌افزار جدید Authorization در ASP.NET Core 3.0
خطای 500، یعنی internal server error، یعنی بروز استثنایی در کدهای شما (و این مورد نیاز به بررسی دقیقی دارد). در مطلب «بررسی خطاهای ممکن در حین راه اندازی اولیه برنامه‌های ASP.NET Core در IIS» دو روش لاگ کردن آن‌ها ذکر شده‌اند. همچنین روش‌های دیگری هم برای لاگ کردن خطاها توسط «فریم ورک Logging» وجود دارد. به علاوه گاهی از اوقات بررسی محتوای response بازگشتی از سرور هم مفید است؛ یک نمونه. نکته‌ی «شبیه سازی customErrors در نگارش‌های دیگر ASP.NET» هم مفید است.
- در کل زمانیکه خطای 500 internal server error را دریافت می‌کنید، اگر برنامه را در حالت dotnet run اجرا کرده باشید، تمام خطاهای مرتبط، در پنجره‌ی کنسولی که باز است، لاگ می‌شوند. اگر از ویژوال استودیو استفاده می‌کنید، همین خروجی، در پنجره‌ی دیباگ آن هم درج می‌شود. مرور این خطاهای سمت سرور، برای رفع مشکل الزامی است. همچنین احتمال دارد خروجی خطاهای سمت سرور، در قسمت مشاهده‌ی محتوای response، در برگه‌ی ابزارهای توسعه دهندگان مرورگر هم ظاهر شود. آن‌را هم بررسی کنید. 
نظرات مطالب
پَرباد - راهنمای اتصال و پیاده‌سازی درگاه‌های پرداخت اینترنتی (شبکه شتاب)
شما با هر درگاهی که کار کنید هیچ فرقی در مشکل فعلی شما به وجود نمیاره چون redirecturl برای تمامی درگاه‌های پرداخت مورد نیاز هست.
برای این نوع پرداخت، روش‌های مختلفی وجود داره.
آدرس بازگشتی باید حتما یک آدرس در سمت سرور باشه نه کلاینت. هنگامیکه کاربر پرداخت رو انجام میده، توسط درگاه بانکی، به آدرس بازگشتی شما در سرور هدایت میشه و شما در اون مرحله عملیات تایید تراکنش رو انجام میدید. برای اینکه سمت کلاینت از تمام شدن پرداخت با خبر بشید، میتونید اون فرمی رو که در مرحله اول به سمت درگاه سامان پست کرده بودید رو به صورت یک popup window توسط جاوا اسکریپت باز کنید. زمانیکه یک شی window درست میکنید، میتونید event هم برای اون اختصاص بدید. رخدادی که شما احتیاج دارید onbeforeunload هست. توسط این رخداد میتونید متوجه بشید که پنجره پرداخت بسته شده و شما برای مثال یک سرویس در سمت سرور رو جهت دریافت اطلاعات تراکنش صدا بزنید.
توجه داشته باشید که پنجره پرداخت هنگامی که کاربر به سرور شما اومد میتونه توسط جاوا اسکریپت بسته بشه.
نظرات مطالب
معرفی JSON Web Token
خیلی ممنون از مطلب مفیدتون.
روش token base authentication روش بسیار خوبی برای جایگزین شدن با روش‌های پیشین است، به خصوص در برنامه‌های تک صفحه ای. سوالی که برای بنده مطرح شد. بنده در پروژه ای token و اطلاعات تکمیلی کاربر را در Local Storage ذخیره میکنم. حال اینکه وقتی token به کاربر داده شد، اگر اطلاعات را کپی کنم و در مرورگر دیگری این اطلاعات را وارد کنم من را تایید صلاحیت میکنه. در صورتی که این نکته میتونه خیلی خطر ساز باشه، چون token که به کاربر اعطا میشه کلید refresh token را هم به همراه خودش داره و در نهایت کاربر تا هر زمانی که بخواد میتونه لاگین شده باقی بمونه. ممنون میشم اگر راه حلی پیشنهاد بدید به بنده.
یک سوالی در مورد عملکرد برنامه تلگرام هم دیده بودم، در تلگرام هم فکر میکنم از token استفاده میشه. اما خیلی جالبه که شما میتونید sessionهای فعالتون را ببینید که از چند دستگاه لاگین شده اید. آیا اگر اطلاعات token را در دیتابیس نگه دارم میتونم مثل تلگرام این وضعیت را هم کنترل کنم؟ مثلا آیا میتونم از سمت سرور یک token که تایید صلاحیت هست را expire کنم؟
نظرات مطالب
فعال‌سازی استفاده از Session در ASP.NET MVC 4 API Controller ها
برای طراحی سبد کالا یا هر نوع آیتم مشابه آن بهتر هست که از روش هایی غیر از سشن بهره برد. چون سشن خودش سنگینی زیادی داره و با افزایش کاربران همزمان این افزایش مصرف حافظه بیشتر هم خواهد شد.

 مشکلات دیگری هم که داره این هست که در سشن یک شی زمان دار هست و اگر کاربر 15مثلا  دقیقه کار نکند بعد از آن سبد خالی می‌شود که بهتر هست انتخاب‌ها همواره حفظ گردد . پس بهترین راه‌ها استفاده از کوکی (+  +) است که در این مقاله نحوه ذخیره هر نوع داده( به همراه فشرده سازی) ذکر شده است و مورد دوم استفاده از local storage و indexedDB است که به زودی قسمت دوم هم منتشر می‌شود.

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

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

نکته تکمیلی اینکه فقط باید در رسم مجدد سبد کالا تحت کلاینت باید موجودی‌ها و قیمت‌ها و تخفیف‌ها و ... هم مجددا بررسی شوند که اطلاعات قبلی نمایش داده نشود که البته این بر میگرده به طراحی ساختاری که ترتیب داده اید.
استفاده از جدول جداگانه برای نگهداری اطلاعات هم روش مناسبی حساب می‌شود که انتخاب بین اینها به نظر برنامه نویس مربوط می‌شود.
نظرات مطالب
مخفی کردن کوئری استرینگ‌ها در ASP.NET MVC توسط امکانات Routing
- بحث مطلب جاری در مورد ASP.NET MVC است و ساز و کار استاندارد آن؛ نه در مورد وب فرم‌ها یا روش‌های سفارشی دیگر. هنگام تعریف مسیر اسکریپت‌ها در MVC اگر از Url.Content و ~ برای ذکر ریشه سایت، استفاده شده باشد، موتور توکار MVC مسیرها را به صورت خودکار اصلاح می‌کند. مثلا:
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
- پیشتر در مورد دیباگ اسکریپت‌های یک سایت مطلبی تهیه شده بود: (^)

الان مرورگر، مسیر اسکریپت‌های شما را از انتهای مسیر یک مطلب دریافت می‌کند نه از ریشه سایت. برای وب فرم‌ها هم روش ذیل وجود دارد:
<script language="javascript" src='<%=ResolveUrl("~/App_Themes/MainTheme/jquery.js")%>' type='text/javascript'></script>
البته در این حالت هدر صفحه باید runat server داشته باشد:
<head runat="server">
و یا از اسکریپت منیجر استفاده کنید:
<asp:ScriptManager ID="ScriptManager1" runat="server">
        <Scripts>
            <asp:ScriptReference Path="~/js/somefile.js" />
        </Scripts>
</asp:ScriptManager>
نظرات مطالب
ASP.NET MVC #10
- Steven Sanderson (عضو تیم ASP.NET MVC) از روش ActionName استفاده می‌کنه (نویسنده کتاب Pro ASP.NET MVC هم هست). بنابراین روش برگزیده رو میشه این حالت درنظر گرفت. در مورد FormCollection هم در انتهای بحث توضیح دادم. Scaffold هم جهت تولید View مورد استفاده قرار می‌گیره نه کنترلر و اکشن متدهای آن. البته در این حالت strongly typed ، نیاز به مدل خواهد داشت که خارج از بحث FormCollection است؛ چون loosely typed است و نمیشه Viewایی رو از یک FormCollection استخراج کرد.
- هدف من تکمیل بحث بود. آشنایی با انواع روش‌های ممکن.
ضمن اینکه من چند سال قبل به کمک روش Request.Form که توضیح دادم، یک form generator برای ASP.NET Web forms نوشتم. زمانیکه کنترل‌های وب فرم‌ها به صورت پویا به صفحه اضافه بشن، دیگه eventها جهت دریافت مقادیر اون‌ها معنا نخواهند داشت (با توجه به اینکه کل صفحه رو بخواهیم پویا تولید کنیم و برنامه چند صد فرم پویا داشته باشد). در اینجا از همین روش Request.Form برای دریافت مقادیر کنترل‌های پویای اضافه شده به صفحه استفاده کردم.
مطالب
بررسی Bad code smell ها: فیلدهای موقتی
فیلد موقتی یا Temporary field در دسته بندی الگوهای «بد استفاده کنندگان از شیء گرایی» قرار می‌گیرد. در این الگوی بد، فیلدها یا خصوصیات یک کلاس، در شرایط خاصی مقدار گرفته و مورد استفاده قرار می‌گیرند و در بقیه شرایط خالی هستند. 
زمانیکه در یک کلاس، متدی برای انجام فعالیت خود، تعدادی پارامتر ورودی زیادی نیاز داشته باشد، ممکن است برنامه نویس برای مواجه نشدن با تعداد پارامترهای زیاد ورودی، فیلدها یا خصوصیاتی را در کلاس مربوط به آن متد ایجاد کند. این فیلدها عملا فقط زمان صدا زدن آن متد مقدار گرفته و در بقیه شرایط خالی هستند.
خواندن و استفاده از این نوع کدها معمولا مشکل و چالش برانگیز است. زیرا خواننده شاهد فیلدهایی است که در اکثر مواقع خالی هستند. همچنین زمان استفاده از این کلاس نمی‌توان از وجود مقادیر فیلدها یا خصوصیات آن‌ها اطمینان لازم را داشت.

روش‌های اصلاح این کد بد بو 

برای اصلاح چنین بوی بدی به طور معمول دو راه وجود دارد. 
اول: با در نظر گرفتن اینکه تمامی کد موجود در متد و فیلدهای مرتبط به آن قابلیت انتقال به کلاس خاص خودشان را دارند، می‌تواند کلاس مجزایی را برای آن متد و فیلدهای مربوطه ایجاد کرد. 
دوم: برای فیلدها و خصوصیاتی که در خیلی مواقع خالی هستند، می‌توان با روش Null object برای وضعیت خالی بودن آن، یک شیء خالی بی اثر را ایجاد کرد.  
به مثال زیر توجه کنید: 
فرض کنید در حال تولید سیستمی هستید که در روال خاصی، نیاز به محاسبه پورسانت فروشنده‌ها دارید. برای محاسبه پورسانت به موارد زیر نیاز است:
  • لیست محصولات فروخته شده
  • درصد کمیسیون خام
  • تاریخ فروش
  • شعبه فروش
  • نوع پرداخت 
به طور نمونه اگر فروشنده فروش نقدی ای انجام دهد، کمیسیون بیشتری نسبت به کمیسیون پیشفرض، به او تعلق خواهد گرفت و … 
ممکن است طراحی اولیه برای چنین متدی به صورت زیر باشد: 
public class Salesman 
{ 
    public void Method1() 
    { 
       return; 
    } 
    public void Method2() 
    { 
        return; 
    } 
    public void Method3() 
    { 
       return; 
    }
    public decimal CalculateCommission(dynamic products, dynamic commissionRate, dynamic saleDate, dynamic branch, dynamic paymentType) 
    { 
       return decimal.MaxValue; 
    } 
}
با مشاهده پارامتر‌های زیاد متد، برنامه نویس می‌تواند از روش‌های اصلاح بوی بد «تعداد زیاد پارامترهای ورودی» استفاده کند. یا اینکه برنامه نویس برای خلاصی از این کد بد بو، بجای ارسال پارامتر، فیلدهایی را در کلاس Salesman ایجاد کند؛ مانند کد زیر:  
public class SalesmanV2 
{ 
    public IEnumerable<dynamic> Products { get; set; } 
    public dynamic CommisionRate { get; set; } 
    public dynamic SaleDate { get; set; } 
    public dynamic Branch { get; set; } 
    public dynamic PaymentType { get; set; } 
    public void Method1() 
    { 
        return; 
    } 
    public void Method2() 
    { 
        return; 
    } 
    public void Method3() 
    { 
        return; 
    } 
    public decimal CalculateCommission() 
    { 
       return decimal.MaxValue; 
    } 
}
با این تغییر، پارامترهای متد CalculateCommision به خصوصیاتی در کلاس Salesman تبدیل خواهند شد. دقت کنید این کلاس متدهای دیگری برای فعالیت‌های مختلف دارد.  
در روش‌های اصلاح این کد بد بو، اشاره به انتقال منطق متد مذکور به کلاس مجزا و مخصوص به خود شده بود. در واقع کد بد بوی «فیلد موقتی» ناشی از عدم رعایت اصل single responsibility است و محاسبه پورسانت را از نظر ذاتی می‌توان وظیفه‌ی اضافه‌ای در این کلاس دانست. با توجه به اینکه می‌توان محاسبه پورسانت را به صورت جداگانه پیاده سازی کرد. به چنین پیاده سازی ای خواهیم رسید.  
public class SalesmanV3 
{ 
    public void Method1() 
    { 
        return; 
    } 
    public void Method2() 
    { 
        return; 
    } 
    public void Method3() 
    { 
        return; 
    } 
} 

public class CommissionCalculator 
{ 
    private IEnumerable<dynamic> _products; 
    private dynamic _commisionRate; 
    private dynamic _saleDate; 
    private dynamic _branch; 
    private dynamic _paymentType; 
    public CommissionCalculator(IEnumerable<dynamic> products, dynamic commisionRate, 
            dynamic saleDate, dynamic branch, dynamic paymentType) 
    { 
        _products = products; 
        _commisionRate = commisionRate; 
        _saleDate = saleDate; 
        _branch = branch; 
        _paymentType = paymentType; 
    } 
}
در شرایط نادری، کد بد بوی «فیلد موقتی» ناشی از عدم رعایت اصل single responsibility نیست. در چنین شرایطی می‌توان از null object برای رفع این بوی بد استفاده کرد.

جمع بندی 

همان‌طور که در متن نیز اشاره شد، عدم رعایت اصل single responsibility می‌تواند منجر به چنین کد بد بویی شود. این کد بد بو با روش‌های ساده‌ای قابل اصلاح است. اصلاح چنین بویی خوانایی و قابلیت نگهداری کد را افزایش خواهد داد. 
مطالب
ارتقاء به NHibernate 3.2

شروع به کار با NH به دو قسمت تقسیم می‌شود. یک قسمت نگاشت کلا‌س‌ها است و قسمت دوم سشن گردانی آن. قسمت دوم آن به همان مباحث کلاس‌های singleton ایی که بحث آن‌ها در سایت هست بر می‌گردد. یا حتی استفاده از کتابخانه‌های IOC برای مدیریت آن (که این پیاده سازی را به صورت توکار هم دارند).
قسمت نگاشت کلاس‌ها در NH انواع و اقسامی دارد:
  • ابتدا همان فایل‌های XML مدل Hibernate جاوا بود.
  • بعد شد مدل annotation ایی به نام Castle ActiveRecord. (این پروژه آنچنان فعال نیست و علتش به این بر می‌گردد که نویسنده اصلی جذب مایکروسافت شده)
  • سپس Fluent NHibernate پدید آمد. (این پروژه هم پس از NH 3.2 ، سرد شده و به نظر آنچنان فعال نیست)
  • الان هم مدل جدیدی به صورت توکار و بدون نیاز به کتابخانه‌های جانبی از NH 3.2 به بعد به آن اضافه شده به نام mapping-by-code .
بنابراین روش مرجح از NH 3,2 به بعد، همین روش mapping-by-code توکار آن است. خصوصا اینکه نیاز به وابستگی خارجی ندارد. برای مثال به دلیل عدم فعال بودن پروژه‌هایی که نام برده شد، مثلا NH 3,3 امروز ارائه می‌شود، شاید دو ماه بعد، این کتابخانه‌های جانبی ساده سازی نگاشت‌ها، به روز شوند یا نشوند.

و ... خبر خوب اینکه شخصی در 18 قسمت به توضیح این قابلیت جدید mapping by code پرداخته و روش‌های نگاشت مرتبط رو با مثال توضیح داده که در آدرس زیر می‌تونید اون‌ها رو پیدا کنید:



مطالب
راه‌های تامین Product backlog در تیم‌های مایکروسافت

شاید مهم‌ترین رخداد وبلاگ‌های مرتبط با برنامه نویسی ایرانی در نیمه دوم سال 89، انتشار کتابچه اسکرام و XP ساده شده به زبان فارسی باشد. یکی از فصول این کتابچه، به روش‌های تهیه Product backlog اختصاص دارد که جزو قسمت‌های اولیه پروسه اسکرام است و می‌شود به آن یک to-do list الویت بندی شده هم گفت. تیم‌های مایکروسافت هم به نظر کمابیش بر همین اساس مدیریت می‌شوند. در ادامه لیستی از سایت‌هایی را مشاهده خواهید کرد که این تیم‌های گوناگون درون مایکروسافت از آن‌ها جهت تامین product backlog خود استفاده می‌کنند؛ کاربران (که در اینجا همان برنامه نویس‌ها هستند) با مراجعه به این سایت‌ها نیازهای خود را عنوان کرده و همچنین با وجود امکانات رای دهی، امکان تهیه لیست‌هایی اولویت بندی شده هم وجود دارد:




و ...


تیم‌های خارج از مایکروسافت هم از این ایده استفاده می‌کنند؛ مانند:

مطالب
عدم کاهش حجم لاگ فایل SQL Server

در مورد روش‌های کاهش حجم لاگ فایل‌های SQL Server در این مطلب بحث شد.
اما یکی از دیتابیس‌های قدیمی shrink نمی‌شد و پیغام خطای زیر را صادر می‌کرد:

Cannot shrink log file 2 because of minimum log space required.

یکی از علت‌هایی که اگر مطابق روش ذکر شده در مقاله یاده شده رفتار شود، سبب کاهش حجم لاگ فایل یک دیتابیس نمی‌شود، وجود تراکنش‌های کامل نشده است. جهت مشاهده‌ی وضعیت تراکنش‌های یک دیتابیس می‌توان دستور زیر را صادر کرد:

DBCC OPENTRAN
که نتیجه به صورت زیر بود:

Replicated Transaction Information:
Oldest distributed LSN : (0:0:0)
Oldest non-distributed LSN : (5291:25:1)

وجود سطر مربوط به Oldest non-distributed LSN به این معنا است که هنوز یک replication نا تمام بر روی این دیتابیس موجود است. البته چون این دیتابیس از یک سرور دیگر به اینجا منتقل شده بود و هیچ نوع replication ایی هم در این سرور بر روی آن تنظیم نشده بود؛ بنابراین ابتدا این replication حذف شد:
exec sp_removedbreplication 'dbName', 'both';

سپس مجددا دستور زیر جهت مشاهده‌ی وضعیت تراکنش‌های ناتمام صادر شد:
DBCC OPENTRAN

که این‌بار دیگر هیچ خروجی نداشت.
اکنون با استفاده از روش ذکر شده، لاگ فایل 70 گیگابایتی این دیتابیس به سادگی به چند مگابایت shrink شد.