مطالب
ASP.NET MVC #5

بررسی نحوه انتقال اطلاعات از یک کنترلر به View‌های مرتبط با آن

در ASP.NET Web forms در فایل code behind یک فرم مثلا می‌توان نوشت Label1.Text و سپس مقداری را به آن انتساب داد. اما اینجا به چه ترتیبی می‌توان شبیه به این نوع عملیات را انجام داد؟ با توجه به اینکه در کنترلر‌ها هیچ نوع ارجاع مستقیمی به اشیاء رابط کاربری وجود ندارد و این دو از هم مجزا شده‌اند.
در پاسخ به این سؤال، همان مثال ساده قسمت قبل را ادامه می‌دهیم. یک پروژه جدید خالی ایجاد شده است به همراه HomeController ایی که به آن اضافه کرده‌ایم. همچنین مطابق روشی که ذکر شد، View ایی به نام Index را نیز به آن اضافه کرده‌ایم. سپس برای ارسال اطلاعات از یک کنترلر به View از یکی از روش‌های زیر می‌توان استفاده کرد:

الف) استفاده از اشیاء پویا

ViewBag یک شیء dynamic است که در دات نت 4 امکان تعریف آن میسر شده است. به این معنا که هر نوع خاصیت دلخواهی را می‌توان به این شیء انتساب داد و سپس این اطلاعات در View نیز قابل دسترسی و استخراج خواهد بود. مثلا اگر در اینجا به شیء ViewBag، خاصیت دلخواه Country را اضافه کنیم و سپس مقداری را نیز به آن انتساب دهیم:

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Country = "Iran";
return View();
}
}
}

این اطلاعات در View مرتبط با اکشنی به نام Index به نحو زیر قابل بازیابی خواهد بود (نحوه اضافه کردن View متناظر با یک اکشن یا متد را هم در قسمت قبل با تصویر مرور کردیم):

@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
Country : @ViewBag.Country
</p>

در این مثال، @ در View engine جاری که Razor نام دارد، به این معنا می‌باشد که این مقداری است که می‌خواهم دریافت کنی (ViewBag.Country) و سپس آن‌را در حین پردازش صفحه نمایش دهی.


ب) انتقال اطلاعات یک شیء کامل و غیر پویا به View

هر پروژه جدید MVC به همراه پوشه‌ای به نام Models است که در آن می‌توان تعاریف اشیاء تجاری برنامه را قرار داد. در پروژه جاری، یک کلاس ساده را به نام Employee به این پوشه اضافه می‌کنیم:

namespace MvcApplication1.Models
{
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}

اکنون برای نمونه یک وهله از این شیء را در متد Index ایجاد کرده و سپس به view متناظر با آن ارسال می‌کنیم (در قسمت return View کد زیر مشخص است). بدیهی است این وهله سازی در عمل می‌تواند از طریق دسترسی به یک بانک اطلاعاتی یا یک وب سرویس و غیره باشد.

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Country = "Iran";

var employee = new Employee
{
Email = "name@site.com",
FirstName = "Vahid",
LastName = "N."
};

return View(employee);
}
}
}

امضاهای متفاوت (overloads) متد کمکی View هم به شرح زیر هستند:

ViewResult View(Object model)
ViewResult View(string viewName, Object model)
ViewResult View(string viewName, string masterName, Object model)


اکنون برای دسترسی به اطلاعات این شیء employee در View متناظر با این متد، چندین روش وجود دارد:

@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<div>
Country: @ViewBag.Country <‪br />
FirstName: @Model.FirstName
</div>

می‌توان از طریق شیء استاندارد دیگری به نام Model (که این هم یک شیء dynamic است مانند ViewBag قسمت قبل)، به خواص شیء یا مدل ارسالی به View جاری دسترسی پیدا کرد که یک نمونه از آن‌را در اینجا ملاحظه می‌کنید.
روش دوم، بر اساس تعریف صریح نوع مدل است به نحو زیر:

@model MvcApplication1.Models.Employee
@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<div>
Country: @ViewBag.Country
<‪br />
FirstName: @Model.FirstName
</div>

در اینجا در مقایسه با قبل، تنها یک سطر به اول فایل View اضافه شده است که در آن نوع شیء Model تعیین می‌گردد (کلمه model هم در اینجا با حروف کوچک شروع شده است). به این ترتیب اینبار اگر سعی کنیم به خواص این شیء دسترسی پیدا کنیم، Intellisense ویژوال استودیو ظاهر می‌شود. به این معنا که شیء Model بکارگرفته شده اینبار دیگر dynamic نیست و دقیقا می‌داند که چه خواصی را باید پیش از اجرای برنامه در اختیار استفاده کننده قرار دهد.
به این روش، روش Strongly typed view هم گفته می‌شود؛ چون View دقیقا می‌داند که چون نوعی را باید انتظار داشته باشد؛ تحت نظر کامپایلر قرار گرفته و همچنین Intellisense نیز برای آن مهیا خواهد بود.
به همین جهت این روش Strongly typed view، در بین تمام روش‌های مهیا، به عنوان روش توصیه شده و مرجح مطرح است.
به علاوه استفاده از Strongly typed views یک مزیت دیگر را هم به همراه دارد: فعال شدن یک code generator توکار در VS.NET به نام scaffolding. یک مثال ساده:
تا اینجا ما اطلاعات یک کارمند را نمایش دادیم. اگر بخواهیم یک لیست از کارمندها را نمایش دهیم چه باید کرد؟
روش کار با قبل تفاوتی نمی‌کند. اینبار در return View ما، یک شیء لیستی ارائه خواهد شد. در سمت View هم با یک حلقه foreach کار نمایش این اطلاعات صورت خواهد گرفت. راه ساده‌تری هم هست. اجازه دهیم تا خود VS.NET، کدهای مرتبط را برای ما تولید کند.
یک کلاس دیگر به پوشه مدل‌های برنامه اضافه کنید به نام Employees با محتوای زیر:

using System.Collections.Generic;

namespace MvcApplication1.Models
{
public class Employees
{
public IList<Employee> CreateEmployees()
{
return new[]
{
new Employee { Email = "name1@site.com", FirstName = "name1", LastName = "LastName1" },
new Employee { Email = "name2@site.com", FirstName = "name2", LastName = "LastName2" },
new Employee { Email = "name3@site.com", FirstName = "name3", LastName = "LastName3" }
};
}
}
}

سپس متد جدید زیر را به کنترلر Home اضافه کنید.

public ActionResult List()
{
var employeesList = new Employees().CreateEmployees();
return View(employeesList);
}

برای اضافه کردن View متناظر با آن، روی نام متد کلیک راست کرده و گزینه Add view را انتخاب کنید. در صفحه ظاهر شده:


تیک مربوط به Create a strongly typed view را قرار دهید. سپس در قسمت Model class، کلاس Employee را انتخاب کنید (نه Employees جدید را، چون از آن می‌خواهیم به عنوان منبع داده لیست تولیدی استفاده کنیم). اگر این کلاس را مشاهده نمی‌کنید، به این معنا است که هنوز برنامه را یکبار کامپایل نکرده‌اید تا VS.NET بتواند با اعمال Reflection بر روی اسمبلی برنامه آن‌را پیدا کند. سپس در قسمت Scaffold template گزینه List را انتخاب کنید تا Code generator توکار VS.NET فعال شود. اکنون بر روی دکمه Add کلیک نمائید تا View نهایی تولید شود. برای مشاهده نتیجه نهایی مسیر http://localhost/Home/List باید بررسی گردد.


ج) استفاده از ViewDataDictionary

ViewDataDictionary از نوع IDictionary با کلیدی رشته‌ای و مقداری از نوع object است. توسط آن شیء‌ایی به نام ViewData در ASP.NET MVC به نحو زیر تعریف شده است:

public ViewDataDictionary ViewData { get; set; }

این روش در نگارش‌های اولیه ASP.NET MVC بیشتر مرسوم بود. برای مثال:

using System;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["DateTime"] = "<‪br/>" + DateTime.Now;
return View();
}
}
}

و سپس جهت استفاده از این ViewData تعریف شده با کلید دلخواهی به نام DateTime در View متناظر با اکشن Index خواهیم داشت:

@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<div>
DateTime: @ViewData["DateTime"]
</div>

یک نکته امنیتی:
اگر به مقدار انتساب داده شده به شیء ViewDataDictionary دقت کنید، یک تگ br هم به آن اضافه شده است. برنامه را یکبار اجرا کنید. مشاهده خواهید کرد که این تگ به همین نحو نمایش داده می‌شود و نه به صورت یک سطر جدید HTML . چرا؟ چون Razor به صورت پیش فرض اطلاعات را encode شده (فراخوانی متد Html.Encode در پشت صحنه به صورت خودکار) در صفحه نمایش می‌دهد و این مساله از لحاظ امنیتی بسیار عالی است؛ زیرا جلوی بسیاری از حملات cross site scripting یا XSS را خواهد گرفت.
احتمالا الان این سؤال پیش خواهد آمد که اگر «عالمانه» بخواهیم این رفتار نیکوی پیش فرض را غیرفعال کنیم چه باید کرد؟
برای این منظور می‌توان نوشت:
@Html.Raw(myString)

و یا:
<div>@MvcHtmlString.Create("<h1>HTML</h1>")</div>

به این ترتیب خروجی Razor دیگر encode شده نخواهد بود.


د) استفاده از TempData

TempData نیز یک dictionary دیگر برای ذخیره سازی اطلاعات است و به نحو زیر در فریم ورک تعریف شده است:

public TempDataDictionary TempData { get; set; }

TempData در پشت صحنه از سشن‌های ASP.NET جهت ذخیره سازی اطلاعات استفاده می‌کند. بنابراین اطلاعات آن در سایر کنترلرها و View ها نیز در دسترس خواهد بود. البته TempData یک سری تفاوت هم با سشن معمولی ASP.NET دارد:
- بلافاصله پس از خوانده شدن، حذف خواهد شد.
- پس از پایان درخواست از بین خواهد رفت.
هر دو مورد هم به جهت بالابردن کارآیی برنامه‌های ASP.NET MVC و مصرف کمتر حافظه سرور درنظر گرفته‌ شده‌اند.
البته کسانی که برای بار اول هست با ASP.NET مواجه می‌شوند، شاید سؤال بپرسند این مسایل چه اهمیتی دارد؟ پروتکل HTTP، ذاتا یک پروتکل «بدون حالت» است یا Stateless هم به آن گفته می‌شود. به این معنا که پس از ارائه یک صفحه وب توسط سرور، تمام اشیاء مرتبط با آن در سمت سرور تخریب خواهند شد. این مورد متفاوت‌ است با برنامه‌های معمولی دسکتاپ که طول عمر یک شیء معمولی تعریف شده در سطح فرم به صورت یک فیلد، تا زمان باز بودن آن فرم، تعیین می‌گردد و به صورت خودکار از حافظه حذف نمی‌شود. این مساله دقیقا مشکل تمام تازه واردها به دنیای وب است که چرا اشیاء ما نیست و نابود شدند. در اینجا وب سرور قرار است به هزاران درخواست رسیده پاسخ دهد. اگر قرار باشد تمام این اشیاء را در سمت سرور نگهداری کند، خیلی زود با اتمام منابع مواجه می‌گردد. اما واقعیت این است که نیاز است یک سری از اطلاعات را در حافظه نگه داشت. به همین منظور یکی از چندین روش مدیریت حالت در ASP.NET استفاده از سشن‌ها است که در اینجا به نحو بسیار مطلوبی، با سربار حداقل توسط TempData مدیریت شده است.
یک مثال کاربردی در این زمینه:
فرض کنید در متد جاری کنترلر، ابتدا بررسی می‌کنیم که آیا ورودی دریافتی معتبر است یا خیر. در غیراینصورت، کاربر را به یک View دیگر از طریق کنترلری دیگر جهت نمایش خطاها هدایت خواهیم کرد.
همین «هدایت مرورگر به یک View دیگر» یعنی پاک شدن و تخریب اطلاعات کنترلر قبلی به صورت خودکار. بنابراین نیاز است این اطلاعات را در TempData قرار دهیم تا در کنترلری دیگر قابل استفاده باشد:

using System;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult InsertData(string name)
{
// Check for input errors.
if (string.IsNullOrWhiteSpace(name))
{
TempData["error"] = "name is required.";
return RedirectToAction("ShowError");
}
// No errors
// ...
return View();
}

public ActionResult ShowError()
{
var error = TempData["error"] as string;
if (!string.IsNullOrWhiteSpace(error))
{
ViewBag.Error = error;
}
return View();
}
}
}

در همان HomeController دو متد جدید به نام‌های InsertData و ShowError اضافه شده‌اند. در متد InsertData ابتدا بررسی می‌شود که آیا نامی وارد شده است یا خیر. اگر خیر توسط متد RedirectToAction، کاربر به اکشن یا متد ShowError هدایت خواهد شد.
برای انتقال اطلاعات خطایی که می‌خواهیم در حین این Redirect نمایش دهیم نیز از TempData استفاده شده است.
بدیهی است برای اجرا این مثال نیاز است دو View جدید برای متدهای InsertData و ShowError ایجاد شوند (کلیک راست روی نام متد و انتخاب گزینه Add view برای اضافه کردن View مرتبط با آن اکشن).
محتوای View مرتبط با متد افزودن اطلاعات فعلا مهم نیست، ولی View نمایش خطاها در ساده‌ترین حالت مثلا می‌تواند به صورت زیر باشد:

@{
ViewBag.Title = "ShowError";
}

<h2>Error</h2>

@ViewBag.Error

برای آزمایش برنامه هم مطابق مسیریابی پیش فرض و با توجه به قرار داشتن در کنترلری به نام Home، مسیر http://localhost/Home/InsertData ابتدا باید بررسی شود. چون آرگومانی وارد نشده، بلافاصله صفحه به آدرس http://localhost/Home/ShowError به صورت خودکار هدایت خواهد شد.


نکته‌ای تکمیلی در مورد Strongly typed viewها:
عنوان شد که Strongly typed view روش مرجح بوده و بهتر است از آن استفاده شود، زیرا اطلاعات اشیاء و خواص تعریف شده در یک View تحت نظر کامپایلر قرار می‌گیرند که بسیار عالی است. یعنی اگر در View بنویسم FirstName: @Model.FirstName1 چون FirstName1 وجود خارجی ندارد، برنامه نباید کامپایل شود. یکبار این را بررسی کنید. برنامه بدون مشکل کامپایل می‌شود! اما تنها در زمان اجرا است که صفحه زرد رنگ معروف خطاهای ASP.NET ظاهر می‌شود که چنین خاصیتی وجود ندارد (این حالت پیش فرض است؛ یعنی کامپایل یک View‌ در زمان اجرا). البته این باز هم خیلی بهتر است از ViewBag، چون اگر مثلا ViewBag.Country1 را وارد کنیم، در زمان اجرا تنها چیزی نمایش داده نخواهد شد؛‌ اما با روش Strongly typed view، حتما خطای Compilation Error به همراه نمایش محل مشکل نهایی، در صفحه ظاهر خواهد شد.
سؤال: آیا می‌شود پیش از اجرای برنامه هم این بررسی را انجام داد؟
پاسخ: بله. باید فایل پروژه را اندکی ویرایش کرده و مقدار MvcBuildViews را که به صورت پیش فرض false هست، true نمود. یا خارج از ویژوال استودیو با یک ادیتور متنی ساده مثلا فایل csproj را گشوده و این تغییر را انجام دهید. یا داخل ویژوال استودیو، بر روی نام پروژه کلیک راست کرده و سپس گزینه Unload Project را انتخاب کنید. مجددا بر روی این پروژه Unload شده کلیک راست نموده و گزینه edit را انتخاب نمائید. در صفحه باز شده، MvcBuildViews را یافته و آن‌را true کنید. سپس پروژه را Reload کنید.
اکنون اگر پروژه را کامپایل کنید، پیغام خطای زیر پیش از اجرای برنامه قابل مشاهده خواهد بود:

'MvcApplication1.Models.Employee' does not contain a definition for 'FirstName1' 
and no extension method 'FirstName1' accepting a first argument of type 'MvcApplication1.Models.Employee'
could be found (are you missing a using directive or an assembly reference?)
d:\Prog\MvcApplication1\MvcApplication1\Views\Home\Index.cshtml 10 MvcApplication1

البته بدیهی است این تغییر، زمان Build پروژه را مقداری افزایش خواهد داد؛ اما امن‌ترین حالت ممکن برای جلوگیری از این نوع خطاهای تایپی است.
یا حداقل بهتر است یکبار پیش از ارائه نهایی برنامه این مورد فعال و بررسی شود.

و یک خبر خوب!
مجوز سورس کد ASP.NET MVC از MS-PL به Apache تغییر کرده و همچنین Razor و یک سری موارد دیگر هم سورس باز شده‌اند. این تغییرات به این معنا خواهند بود که پروژه از حالت فقط خواندنی MS-PL به حالت متداول یک پروژه سورس باز که شامل دریافت تغییرات و وصله‌ها از جامعه برنامه نویس‌ها است، تغییر کرده است (^ و ^).

نظرات نظرسنجی‌ها
برای توسعه برنامه‌های مبتنی بر NET Core. از چه محیطی استفاده می‌کنید؟
یه مدت روی اوبونتو از vsCode استفاده کردم. خیلی خوبه و سبک و راضی کننده ست. منتها مشکل اصلی من دیباگ کردن پروژه‌های docker base بود. راه حل هایی توی نت بود. منتها ساده نبودن و به همین خاطر فعلا بیخیال شدم و روی ویندوز با  2017 vs کار میکنم. اگر بشه به راحتی از داکر استفاده کرد برمیگردم روی vsCode
مطالب
چگونه در یک پروژه سورس باز مشارکت کنیم؟
مشارکت در پروژه‌های سورس باز الزاما به معنای هدیه کدهای جدیدی به آن پروژه یا حتی مشارکت مالی در آن نیست. در ادامه لیستی از مواردی را مرور خواهیم کرد که سبب زنده نگه داشته شدن یک پروژه سورس باز خواهند شد:

مشارکت در نگهداری پروژه
  • مشکلی را در این کتابخانه پیدا کرده‌اید؟ آن‌را در سیستم bug tracking پروژه گزارش کنید و بی‌تفاوت از کنار آن عبور نکنید.
  • مشکلی برطرف شده است؟ بررسی کنید، آیا واقعا این تغییرات مفید بوده است یا خیر و نتیجه را اعلام کنید.

بهبود کدهای موجود
  • در بهترین حالت، کدی را جهت رفع یک مشکل ارسال کنید. همچنین در این حالت سعی کنید یک مطلب جدید را ایجاد کرده و در مورد کدهای خود توضیح دهید. برای ارسال کدی جدید بهتر است تنها قسمت‌های تغییر کرده را ارسال کنید و اصطلاحا باید بتوانید توسط قابلیت‌های سورس کنترل‌ها یک patch را تهیه نمائید.
  • یک unit test جدید را به پروژه اضافه کنید. یک مثال جدید را برای قسمتی خاص تهیه نمائید.
  • ثوابت برنامه را به زبان‌های دیگر ترجمه کنید.
  • یک گزینه و قابلیت جدید را درخواست دهید.

بهبود مستندات پروژه
  • اگر توضیحات قسمت‌های مختلف و commentهای ارائه شده به نظر شما کافی نیست؛ آن‌ها را تکمیل کرده و یک patch برای آن ارائه دهید.
  • مستندات موجود را تکمیل کنید یا بهبود ببخشید.
  • یک مقاله‌ی جدید در مورد نحوه‌ی استفاده از آن پروژه بنویسید.
  • یک ویدیوی ساده آموزشی را در مورد آن تهیه کنید.

مشارکت در انجمن‌ها و شبکه‌های اجتماعی
  • به لیست سؤالات مطرح شده در یک پروژه مراجعه کرده و در آن مشارکت کنید. سعی کنید حضور مثبتی داشته باشید.
  • به دیگران در مورد وجود این پروژه اطلاع رسانی کنید.
  • اگر پروژه مفیدی است، به دیگران بگوئید این پروژه چقدر بر روی کار شما تاثیر داشته است و چه برنامه‌هایی را از طریق آن پیش برده‌اید.
 
مطالب
از NET Standard. به NET 5.
 ارائه‌ی NET 5. یا پایان NET Standard.

تا پیش از ارائه‌ی NET 5.، پیاده سازی‌های مجزایی از دات نت مانند Full .NET Framework ،.NET Core ،Xamarin و غیره وجود داشتند و دارند. در این حالت برای اینکه بتوان یک class library قابل اجرای بر روی تمام این‌ها را ارائه داد، نیاز به ارائه‌ی API ای بود که بین تمام آن‌ها به اشتراک گذاشته شود و این دقیقا هدف وجودی NET Standard. است؛ اما ... مشکلات زیر را نیز به همراه دارد:
هر زمانیکه نیاز به افزودن یک API جدید باشد، نیاز خواهد بود تا یک نگارش جدید از NET Standard. ارائه شود. سپس تمام نگارش‌های مختلف دات نت باید سعی کنند به صورت مجزایی این API جدید را پیاده سازی کنند. این پروسه بسیار کند است. همچنین همواره باید مراجع مختلف را دقیق بررسی کنید که برای مثال کدام نگارش از دات نت، کدام نگارش از NET Standard. را پیاده سازی کرده‌است.
با ارائه‌ی NET 5.، وضعیت کاملا فرق کرده‌است. در اینجا یک «کد پایه‌ی اشتراکی» را برای تمام نگارش‌های مختلف دات نت داریم و این نگارش می‌خواهد مخصوص دسکتاپ یا برنامه‌های موبایل باشد، تفاوتی نمی‌کند. اکنون که تمام نگارش‌های مختلف دات نت بر فراز یک کد اشتراکی پایه کار می‌کنند، دیگر نیازی به ارائه‌ی مجزای یک API استاندارد و سپس پیاده سازی مجزای دیگری از آن، نیست.


نگارش‌های ویژه‌ی NET 5.، مخصوص سکوهای کاری مختلف

همانطور که عنوان شد، NET 5. در اصل یک «مجموعه کد اشتراکی» بین NET Core ،Mono ،Xamarin. و سایر پیاده سازی‌های دات نت است. اما سکوهای کاری مختلف، مانند Android، iOS، ویندوز و غیره، به همراه کدهای قابل توجهی که مختص به آن سیستم عامل‌های خاص باشند نیز هستند. برای رفع این مشکل، یکسری TFM یا target framework name/Target Framework Moniker ارائه شده‌اند. برای مثال net5.0 یکی از آن‌ها است. زمانیکه از این TFM استفاده می‌کنید، یعنی در حال کار با API ای هستید که در تمام نگارش‌های چندسکویی مختلف دات نت، مهیا و قابل استفاده‌است. نام جدید «net5.0» جایگزین کننده‌ی نام‌های قدیمی «netcoreapp» و «netstandard» است.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>
در اینجا اگر نیاز به کار با API مخصوص ویندوز را نیز داشتید، می‌توانید از TFM مخصوص آن که net5.0-windows نام دارد استفاده کنید. «net5.0-windows» به این معنا است که به تمام امکانات net5.0 دسترسی دارید؛ به علاوه‌ی API ای که مختص به سیستم عامل ویندوز است (مانند Windows Forms و WPF). در دات نت 6، دو TFM جدید net6.0-android و net6.0-ios را نیز شاهد خواهیم بود.
کار کردن با این اسامی و درک آن‌ها نیز ساده‌است. برای مثال net6.0-ios به این معنا است که این قطعه کد و اسمبلی آن، می‌تواند تمام کتابخانه‌های مخصوص net5.0 و net6.0 را نیز استفاده کند؛ اما نه کتابخانه‌هایی که به صورت اختصاصی برای net5.0-windows و یا net6.0-android کامپایل شده‌اند.
این توضیحات به معنای پایان کار «NET Standard.» است. پس از NET Standard 2.1. فعلی، دیگر هیچ نگارش جدیدتری از آن ارائه نخواهد شد و البته net5.0 و تمام نگارش‌های پس از آن، قابلیت استفاده‌ی از کتابخانه‌های مبتنی بر NET Standard 2.1. و پیش از آن‌را نیز دارا هستند. بنابراین از این پس، net5.0 را به عنوان پایه‌ی به اشتراک گذاری کدها مدنظر داشته باشید.


سؤال: اگر امروز خواستیم کتابخانه‌ای را تولید کنیم، باید از کدام TFM استفاده کرد؟

net5.0 و تمام نگارش‌های پس از آن، از کتابخانه‌های مبتنی بر NET Standard 2.1. و قبل از آن نیز پیشیبانی می‌کنند. در این حالت تنها دلیل تغییر TFM کتابخانه‌های قدیمی موجود به net5.0، می‌تواند دسترسی به یکسری API جدید باشد. اما در مورد کتابخانه‌های جدید چطور؟ آیا باید برای مثال از netstandard2.0 استفاده کرد و یا از net5.0؟ این مورد بستگی به نوع پروژه‌ی در حال تهیه دارد:
- اجزای مختلف یک برنامه: اگر از کتابخانه‌ها برای شکستن برنامه‌ی خود به چندین قسمت استفاده می‌کنید، بهتر است از نام جدید netX.Y استفاده کنید (مانند net5.0). که در اینجا X.Y، منظور پایین‌ترین شماره نگارش NET. ای است که برنامه‌ی شما قرار است بر مبنای آن تهیه شود.
- کتابخانه‌های با قابلیت استفاده‌ی مجدد: اگر قرار است از کتابخانه‌ی شما در NET 4x. نیز استفاده شود، با netstandard2.0 شروع کنید. بهتر است netstandard1x را فراموش کنید؛ چون دیگر پشتیبانی نمی‌شود. اگر نیازی به پشتیبانی از NET 4x. ندارید، می‌توانید یا از netstandard2.1 و یا از net5.0 استفاده کنید و اگر در این حالت نیازی به پشتیبانی از NET Core 3x. ندارید، می‌توانید مستقیما با net5.0 شروع کنید.
بنابراین به صورت خلاصه:
- netstandard2.0 امکان اشتراک کدها را بین NET 4x. و سایر سکوهای کاری میسر می‌کند.
- netstandard2.1 امکان اشتراک کدها را بین Mono ،Xamarin و NET Core 3x. میسر می‌کند.
- net5.0، مخصوص نگارش فعلی و آینده‌ی دات نت است.

و یا حتی می‌توانید یک کتابخانه را به صورت multi-targeting با پشتیبانی از تمام TFMهای یاد شده‌ی فوق نیز تولید کنید:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net5.0;netstandard2.1;netstandard2.0;net461</TargetFrameworks>
  </PropertyGroup>
</Project>
نظرات مطالب
مروری بر کتابخانه ReactJS - قسمت دوم - نصب و پیکربندی React‌JS برای Visual Studio Code
سلام؛ بر اساس مستند‌ات React  این کتابخانه بدون مشکل با زبان‌های NET. و ASP.NET MVC کار میکنه و مثال‌هایی هم برای کار با این کتابخانه در پروژه‌های ASP.NET MVC در اینجا و اینجا میتونید ببینید. بسته به پروژه ممکنه ملاحظاتی وجود داشته باشه، اما در مجموع منعی برای استفاده هم زمان بین این دو ندیدم. 
مطالب
نصب dotnet core framework روی اوبونتو 16.04
مایکروسافت در چند سال اخیر و به خصوص بعد از روی کار آمدن ساتیا نادلا،  رویکرد خاصی را به مباحث Cross Platform پیدا کرد، تا جایی که dotnet core شکل گرفت. این فناوری جدید به شما این امکان را میدهد تا دات نت فریمورک را بر روی سیستم عامل‌های دیگری چون لینوکس و مک نصب کنید. در سایت اختصاصی این فناوری،  نحوه نصب آن بر روی توزیع‌های مختلف سیستم عامل  لینوکس،  توضیحاتی داده شده است و یکی از این آموزش‌ها مربوط به پرچم دار توزیع‌های لینوکس و به خصوص خانواده دبیان یعنی اوبونتو است. در این راهنما، تنها نسخه خاصی از اوبونتو یعنی نسخه 14.04 آن مدنظر می‌باشد ولی آخرین نسخه اوبونتو 16.04 است که در اینباره توضیحی داده نشده است و با نصب آن به مشکل بر می‌خورد. در این مقاله میخواهیم نصب dotnet core را بر روی آخرین نسخه این سیستم عامل، بررسی کنیم.

با توجه به ابتدای آموزش، کدهای زیر را در ترمینال وارد میکنیم:
sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'

sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893

sudo apt-get update
اولین خط از لینوکس، مخزنی را که فایل‌های مربوط به دات نت، در آن قرار دارند، در لینوکس ثبت می‌کند. دستور sh وظیفه‌ی اجرای اسکریپت را بر عهده دارد که میتوانید یک فایل اسکریپت را به آن معرفی کنید. ولی اگر با سوپیچ c به کار رود، می‌توانید خود دستور ارسالی را به آن معرفی کنید. اجرای این اسکریپت منجر به معرفی مخازن دات نت می‌شود که میتواند برای نصب و به روزرسانی آن به کار رود. در ساختار فایل‌های خانواده‌ی دبیان، فایلی به نام Sources.list وجود دارد که شامل آدرس مخازن رسمی اوبونتو جهت دریافت نرم افزاری‌ها آن می‌شود. ولی اگر قرار باشد مخازنی جدای از مخازن رسمی معرفی گردند، باید داخل دایرکتوری sources.list.d قرار گیرند و با نامی مشخص و با همان فرمت مشخص، ذخیره گردند.

در خط  دوم،  کلید اختصاصی این پکیج جهت اعتبارسنجی معرفی می‌گردد که در سایت جاری قبلا به آن پرداخته شده است. در خط آخر هم مخازن موجود را به روزرسانی می‌کنیم تا آماده استفاده شود.
در سایت مایکروسافت از شما خواسته می‌شود که کد زیر را وارد کنید:
sudo apt-get install dotnet-dev-1.0.0-preview1-002702
ولی بهتر است به جای آن از جدیدترین بسته استفاده کنید که باگ آن رفع شده است و علت باگ قبلا به آن پرداخته شده است. پس کد زیر را به جای کد بالا وارد می‌کنیم:
sudo apt-get install dotnet-dev-1.0.0-preview2-003096
چه بسته قبلی و چه جدید را نصب کنید، به خطای زیر برخورد خواهید کرد:
The following packages have unmet dependencies:
 dotnet-dev-1.0.0-preview1-002702 : Depends: dotnet-sharedframework-microsoft.netcore.app-1.0.0-rc2-3002702 but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
که برای حل آن، باید ابتدا بسته‌ی وابسته نصب گردد و سپس دستور بالا دوباره اجرا شود. برای دریافت این وابستگی، به این لینک مراجعه کنید و فایل مربوطه را که با پسوند deb است، دریافت کنید. بعد از آن باید فایل دریافتی را نصب نمایید که برای نصب این نوع بسته‌ها از دستور زیر استفاده می‌کنیم:
sudo dpkg -i libicu52_52.1-3ubuntu0.4_amd64.deb
بعد از نصب موفقیت آمیز این بسته، دستورات زیر را اجرا میکنیم تا بسته dotnet core نصب شود:
sudo apt-get install dotnet-sharedframework-microsoft.netcore.app-1.0.0-rc2-3002702
sudo apt-get install dotnet-dev-1.0.0-preview2-003096
بعد از اتمام نصب، دستور زیر را جهت اطمینان از صحت نصب وارد کنید، تا نسخه نصب شده جاری به شما نمایش داده شود:
dotnet --version
خروجی:
1.0.0-preview2-003096
البته ممکن است خروجی دفعه اول به خاطر پیام‌های خوش آمدگویی، خطوط بیشتری را داشته باشد، ولی برای دفعات آینده همین یک خط است.
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 15 - بررسی تغییرات Caching
با سلام؛
- لطفا اگر تجربه ای از استفاده‌ی از کش در دات نت کور دارید که منجر به بهبود سرعت سایت یا کاهش استفاده از منابع سرور شده رو با ما هم در میان بگزارید که از چه نوع کش با چه تنظیماتی استفاده کردید؟
- ضمنا اگر پروژه با SPA باشد مثلا با VueJS آیا باز هم کش مورد استفاده است؟
نظرات مطالب
تعیین شماره نگارش IE مورد استفاده در Web Browser Control
ممنون. حداقل دو گزینه سورس باز 100 درصد تهیه شده با کدهای دات نت نیز برای رندر HTML وجود دارند:
الف) تبدیلگر HTML به XAML نوشته شده توسط خود مایکروسافت
ب) پروژه فوق العاده جالب HTML Renderer 
نظرات مطالب
ASP.NET MVC #20
ضمن تشکر فراوان از این همت عالی و وقتی که میذارید جناب نصیری!

بنده یک سوال داشتم:
اگر شما در محل کارتون، قرار بود یک پروژه بزرگ تحت وب با دات نت را راه اندازی کنید، آیا انتخابتون MVC بود یا اینکه فعلا از WebForm ها استفاده می کردید تا MVC بالغ تر شود و بعدا سراغش می رفتید؟

بازم ممنونم ازتون
اشتراک‌ها
قسمت 4 از آموزش سی شارپ

در این ویدیو در مورد ساختار دات نت، معماری runtime، CLR و هر چیزی که مربوط به فضای دات نت است صحبت کردیم.

 
قسمت 4 از آموزش سی شارپ