نظرات مطالب
آشنایی با Refactoring - قسمت 7
بحث Refactoring در مورد طراحی کارهای شما معنا پیدا می‌کند؛ وگرنه اگر کتابخانه‌ی بسته دیگری، نیازهای خاص خودش را دیکته می‌کند، بدیهی است دست شما آنچنان باز نخواهد بود.
در مورد مطلبی که گفتید، بله می‌شود. در این حالت باید DataObject TypeName مربوط به ObjectDataSource را مشخص کنید: [^]
اگر می‌خواهید واقعا این اصول شیءگرایی را رعایت کنید، بهتر است به ASP.NET MVC کوچ کنید. Model binder آن، خودش به صورت خودکار این موارد را پوشش می‌دهد. نگارش بعدی ASP.NET Webforms هم کمی تا قسمتی از این Model binder رو به ارث برده ولی نه آنچنان که یک strongly typed view رو بتونید باهاش 100 درصد مثل MVC تعریف کنید.
در کل معماری ASP.NET Webforms مربوط به روزهای اول دات نت است و به نظر هم قرار نیست آنچنان تغییری بکند. به همین جهت MVC رو این وسط معرفی کرده‌اند.
نظرات مطالب
تنظیمات مورد نیاز جهت شروع به کار با C# 9.0
یک نکته‌ی تکمیلی: تداخل ReSharper قدیمی، با C# 9.0
اگر از ویژوال استودیو استفاده می‌کنید و پس از ارتقاء آن به آخرین نگارش، ویژگی‌های جدید C# 9.0 در ادیتور آن تشخیص داده نمی‌شوند .... مشکل از داشتن ReSharper قدیمی است:

نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 18 - کار با ASP.NET Web API
ارتقاء به ASP.NET Core 2.1: بهبود اعتبارسنجی پارامترها

تا پیش از نگارش 2.1، برای اعمال اعتبارسنجی به اطلاعات دریافتی از کاربر باید به صورت زیر عمل کرد:
public class UserModel   
{
   [Required, EmailAddress]
   public string Email { get; set; }
 
   [Required, StringLength(1000)]
   public string Name { get; set; }
}
اطلاعات مدنظر به صورت یک کلاس مدل تعریف شده و سپس ویژگی‌های اعتبارسنجی به خواص این کلاس اضافه می‌شوند.
در این حالت در اکشن متد تعریفی با بررسی ModelState.IsValid می‌توان وضعیت اعتبارسنجی اطلاعات دریافتی از سمت کاربر را مشاهده کرد:
public IActionResult SaveUser(UserModel model)
{
     if(!ModelState.IsValid)
     {

 در نگارش 2.1 الزامی به تعریف این کلاس مدل نیست و ویژگی‌های اعتبارسنجی را به پارامترهای تعریف اکشن متد هم می‌توان اعمال کرد:
public IActionResult SaveUser(
     [Required, EmailAddress] string Email  
     [Required, StringLength(1000)] string Name)
{
    if(!ModelState.IsValid)

یک نکته‌ی تکمیلی: اعمال ویژگی Required به non-nullable value types تاثیری ندارد. به همین جهت ویژگی دیگری به نام BindRequired نیز در اینجا اضافه شده‌است تا برای نمونه در مثال زیر اطمینان حاصل شود که testId از مقادیر route و qty از مقادیر کوئری استرینگ مقدار دهی شده‌اند:
public IActionResult Get([BindRequired, FromRoute] Guid testId, [BindRequired, FromQuery] int qty)   
{
   if(!ModelState.IsValid)

- به این ترتیب می‌توان تعداد ViewModelهای مورد نیاز یک برنامه را به شدت کاهش داد. البته نکته‌ی «بررسی Bad code smell ها: تعداد زیاد پارامترهای ورودی» و «آشنایی با Refactoring - قسمت 7» را هم مدنظر داشته باشید و زیاده‌روی نکنید!
- همچنین اگر ویژگی [ApiController] را نیز به کنترلر جاری اعمال کنید، بررسی ModelState.IsValid نیز به صورت خودکار انجام خواهد شد و نیازی به کدنویسی اضافه‌تری نخواهد داشت.
اشتراک‌ها
ادغام تیم #M با #C

یکی از تیم‌های تحقیقاتی مایکروسافت که بر روی زبان #M کار می‌کرد با #C ادغام شده‌است. یکی از مقالات آن‌ها که احتمالا در نگارش بعدی دات نت حضور خواهد داشت.

ادغام تیم #M با #C
نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 2 - به روز رسانی ساختار بانک اطلاعاتی
- متد Seed به نگارش بعدی EF Core اضافه خواهد شد (نگارش 2.1). یک نمونه پیاده سازی آن در نگارش فعلی.
- روش کار چندسکویی با NET Core. مبتنی بر CLI آن هست. بهتر است سری کار با VSCode را پیگیری کنید تا بیشتر با CLI آن آشنا شوید. اما اگر می‌خواهید از PowerShell استفاده کنید (هنوز حال و هوای EF 6.x را دارید)، پیشنیازهای فعالسازی این مورد در نظرات قسمت بعدی مطرح شده‌است.
نظرات مطالب
پیاده سازی عملیات CRUD با استفاده از پروتکل OData
در یک نگاه کلی، ASP.NET Web API OData بر روی ASP.NET Web API سوار شده است و مزیت‌های پایه آن را به صورت کامل دارد، شامل Routing، داشتن Action Filterها، احراز هویت و ... همچنین استاندارد OData بر روی استاندارد Rest سوار شده است و مزیت‌های پایه ای آن را دارا می‌باشد. اما در کنار اینها OData ویژگی هایی دارد، مانند batch request که در پست‌های بعدی توضیح خواهم داد. و همچنین با داشتن Metadata و استفاده از یک OData Client که در JavaScript | C# | Objective-C و ... کتاب خانه‌های مختلفی برای آن‌ها وجود دارد، شما می‌توانید به سادگی Proxy سمت کلاینت رو Generate کرده و متدها را فراخوانی کنید. همچنین سازگاری استاندارد دیتا گرید ها، کمبو باکس‌ها و کنترل‌های گوناگون از فریم ورک‌های مختلف از دیگر ویژگی‌های OData است. بخاطر مبتنی بر Rest بودن Web API OData امکان فراخوانی آن با jQuery نیز وجود دارد؛ اما استفاده از OData Client‌ها می‌تواند سادگی کار را به شدت بالا ببرد. سازگاری با Owin و امکان اجرای آن بر روی ASP.NET Core نیز از دیگر موارد مهمی است که باید به آن اشاره کنم. در ضمن این استاندارد محدود به مایکروسافت نبوده و در سایر زبان‌ها و پلتفرم‌ها نیز شناخته شده می‌باشد. برای مثال امکان نوشتن یک OData Server در جاوا یا جاوا اسکریپت نیز وجود دارد.
مطالب
استفاده از Dialect سفارشی در NHibernate

Dialects در NHibernate کلاس‌هایی هستند جهت معرفی تعاریف ویژگی‌های خاص بانک‌های اطلاعاتی مختلف؛ مثلا SQL Server 2008 چه ویژگی‌های جدیدی دارد یا SQL Server CE 4.0 که جدیدا ارائه شده، امکان تعریف offset را در کوئری‌های خود میسر کرده (چیزی که قرار است در نگارش بعدی SQL Server اصلی(!) در دسترس باشد) ، اکنون چگونه می‌توان این ویژگی را فعال کرد (باید Dialect آن به روز شود و ... همین). یک سری Dialect از پیش تعریف شده هم برای اکثر بانک‌های اطلاعاتی در NHibernate وجود دارد. ممکن است این Dialects پیش فرض الزاما خواسته شما را برآورده نکنند یا مو به مو مستندات بانک‌ اطلاعاتی مرتبط را پیاده سازی نکرده باشند و سؤال این است که اکنون چه باید کرد؟ آیا باید حتما سورس‌ها را دستکاری و بعد کامپایل کرد؟ به این صورت هر بار با ارائه یک نگارش جدید NHibernate به مشکل برخواهیم خورد چون باید کل عملیات تکرار شود.
خبر خوب اینکه می‌توان از همین Dialects موجود ارث بری کرد، سپس مواردی را که نیاز داریم override کرده یا به کلاس مشتق شده افزود. اکنون می‌توان از این Dialect سفارشی به جای Dialect اصلی استفاده کرد. در ادامه با یک نمونه آشنا خواهیم شد.
فرض کنید Dialect انتخابی مرتبط است با SQL Server CE استاندارد. کوئری ساده زیر را می‌نویسیم، به ظاهر باید کار کند:
var list = session.Query<SomeClass>().Where(x=>x.Date.Year==2011).ToList();
اما کار نمی‌کند! علت این است که تمام Dialects در NHibernate از یک Dialect پایه مشتق شده‌اند. در این Dialect پایه، تعریف تابع استخراج year از یک تاریخ به نحو زیر است:
extract(year, ?1)
اما در SQL CE این تابع باید به صورت زیر تغییر کند تا کار کند:
datepart(year, ?1)
و ... این Override انجام نشده (تا نگارش فعلی آن). مهم نیست! خودمان انجام خواهیم داد! به صورت زیر:
using NHibernate;
using NHibernate.Dialect;
using NHibernate.Dialect.Function;

namespace Test1
{
public class CustomSqlCeDialect : MsSqlCeDialect
{
public CustomSqlCeDialect()
{
RegisterFunction("year", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(year, ?1)"));
}
}
}
خوب تا اینجا ما یک Dialect جدید را با ارث بری از MsSqlCeDialect اصلی تولید کرده‌ایم. مرحله بعد نوبت به معرفی آن به NHibernate است. اینکار توسط Fluent NHibernate به سادگی زیر است:
var dbType = MsSqlCeConfiguration.Standard
...
.Dialect<CustomSqlCeDialect>();

پس از آن کوئری LINQ ابتدای بحث بدون مشکل اجرا خواهد شد چون اکنون می‌داند که بجای extract year ، باید از تابع datepart‌ استفاده کند.
مرحله بعد هم می‌تواند تهیه یک patch و ارسال به گروه اصلی برای به روز رسانی پروژه NH باشد.