یکی دیگر از تغییرات مهم Razor در ASP.NET Core، معرفی Tag Helpers است که همانند HTML Helpers نگارشهای پیشین ASP.NET MVC، کار رندر کردن HTML را انجام میدهند و در اغلب موارد میتوان آنها را جایگزین HTML Helpers کرد. مزیت استفادهی از Tag helpers، شبیه بودن آنها به المانها و ویژگیهای HTML است. در کل اینکه باید از HTML Helpers استفاده کرد و یا از Tag Helpers، بیشتر یک انتخاب شخصی و سلیقهای است.
فعال سازی استفادهی از Tag Helpers برای تمام Viewهای برنامه
برای اینکه تمام Viewهای سایت بتوانند به امکانات Tag Helpers دسترسی پیدا کنند، باید یک سطر ذیل را
به فایل ViewImports.cshtml_ اضافه کرد:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
در اینجا * به معنای استفادهی از تمام Tag Helpers موجود در اسمبلی ذکر شدهاست.
Microsoft.AspNetCore.Mvc.TagHelpers به همراه افزودن وابستگی Microsoft.AspNetCore.Mvc
در حین فعال سازی ASP.NET MVC، به پروژه اضافه میشود:
فعال سازی Intellisense مربوط به Tag Helpers در ویژوال استودیو
هرچند فعال سازی ASP.NET MVC، تنها وابستگی است که برای کار با Tag Helpers نیاز است، اما برای فعال سازی Intellisense آنها باید بستهی Microsoft.AspNetCore.Razor.Tools را نیز به فایل prject.json برنامه، جهت نصب معرفی کرد:
{
"dependencies": {
//same as before
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0",
"Microsoft.AspNetCore.Razor.Runtime": "1.0.0",
"Microsoft.AspNetCore.Razor.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
}
},
"tools": {
//same as before
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final"
}
}
ضمنا اگر از ReSharper استفاده میکنید (تا نگارش resharper-2016.1)، فعلا مجبور هستید که آنرا غیرفعال کنید.
اطلاعات بیشتر یک مثال: ایجاد لینکی به یک اکشن متد <a asp-controller="Home" asp-action="Index" asp-route-id="123">Home</a>
در اینجا نحوهی ایجاد لینکی را مشاهده میکنید که به کنترلر Home و اکشن متد Index آن اشاره میکند. این syntax جدید، جایگزین ActionLink مربوط به HTML Helperها است. در اینجا asp-route-id را نیز مشاهده میکنید. قسمت asp-route آن جهت مقدار دهی پارامترهای مسیریابی است و قسمت id- بنابر نام پارامتری که قرار است مقدار دهی شود، متغیر خواهد بود.
اگر نیاز به اشارهی به مسیریابی خاصی از طریق نام آن وجود دارد (همان نامهایی که
در حین تعریف یک مسیریابی ذکر میشوند) میتوان به صورت ذیل عمل کرد:
<a asp-route="login">Login</a>
و یا برای مشخص سازی پروتکل خاصی و یا ذکر دقیق نام هاست، میتوان از روش زیر استفاده کرد:
<a asp-controller="Account"
asp-action="Register"
asp-protocol="https"
asp-host="asepecificdomain.com"
asp-fragment="fragment">Register</a>
راهنمای تبدیل HTML Helpers به Tag Helpers
در جدول ذیل، مثالهایی را از HTML Helpers متداول و معادلهای Tag Helper آنها مشاهده میکنید:
Tag Helper | HTML Helper |
<label asp-for="Email" class="col-md-2 control-label"></label> | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) |
<a asp-controller="MyController" asp-action="MyAction"
class="my-css-classname" my-attr="my-attribute">Click me</a> | @Html.ActionLink("Click me", "MyController", "MyAction",
{ @class="my-css-classname", data_my_attr="my-attribute"}) |
<input asp-for="FirstName" style="width:100px;"/> | @Html.TextBox("FirstName", Model.FirstName, new { style = "width: 100px;" }) |
<input asp-for="Email" class="form-control" /> | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) |
<input asp-for="Password" class="form-control" /> | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) |
<input asp-for="UserName" class="form-control" /> | @Html.EditorFor(l => l.UserName,
new { htmlAttributes = new { @class = "form-control" } }) |
<form asp-controller="Account" asp-action="Register"
method="post" class="form-horizontal" role="form"> | @using (Html.BeginForm("Register", "Account",
FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken() |
<span asp-validation-for="UserName" class="text-danger"></span> | @Html.ValidationMessageFor(m => m.UserName, "",
new { @class = "text-danger" }) |
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div> | @Html.ValidationSummary("", new { @class = "text-danger" }) |
نکات تکمیلی کار با فرمها توسط Tag Helpers
نمونهای از مثال Tag helper کار با فرمها را در جدول فوق ملاحظه میکنید. چند نکتهی تکمیلی ذیل را میتوان به آن اضافه کرد:
- در حین کار با Tag Helpers، درج anti forgery token به صورت خودکار صورت میگیرد. اگر میخواهید که این توکن ذکر نشود، آنرا توسط ویژگی "asp-anti-forgery="false خاموش کنید.
- برای درج پارامترهای مسیریابی خاص، از asp-route به همراه نام پارامتر مدنظر استفاده کنید:
<form asp-controller="Account"
asp-action="Login"
asp-route-returnurl="@ViewBag.ReturnUrl"
method="post" >
</form>
که در نهایت به یک چنین حالتی رندر میشود
<form action="/Account/Login?returnurl=%2FHome%2FAbout" method="post">
- همانند action linkها در اینجا نیز برای اشارهی به یک مسیریابی از طریق نام آن میتوان از ویژگی asp-route استفاده کرد
<form asp-route="login"
asp-route-returnurl="@ViewBag.ReturnUrl"
method="post" >
</form>
Tag helpers مخصوص تعریف اسکریپتها و CSSها
در اینجا Tag Helpers صرفا به عنوان جایگزینهای HTML Helpers مطرح نیستند. توسط آنها قابلیتهای جدیدی نیز ارائه شدهاست. برای مثال اگر تگ اسکریپت را به صورت ذیل تعریف کنیم:
<script asp-src-include="~/app/**/*.js"></script>
یک چنین خروجی فرضی را تولید میکند:
<script src="/app/app.js"></script>
<script src="/app/controllers/controller1.js"></script>
<script src="/app/controllers/controller2.js"></script>
<script src="/app/controllers/controller3.js"></script>
<script src="/app/controllers/controller4.js"></script>
<script src="/app/services/service1.js"></script>
<script src="/app/services/service2.js"></script>
به این معنا که یک سطر asp-src-include، بر اساس الگویی که دریافت میکند، تمام فایلهای اسکریپت موجود در یک پوشه را یافته و برای آنها، تگ اسکریپت تولید میکند. دراینجا ذکر ** به معنای بررسی تمام زیرپوشههای app است. اگر تنها پوشهی خاصی مدنظر است، باید ** را حذف کرد.
در این بین اگر میخواهید از پوشهی خاصی صرفنظر کنید، از asp-src-exclude استفاده کنید:
<script asp-src-include="~/app/**/*.js"
asp-src-exclude="~/app/services/**/*.js">
</script>
همچنین در اینجا امکان تعریف CDN و fallback هم وجود دارد. استفادهی از CDNها جهت کاهش ترافیک سرور و بهبود کارآیی برنامه با ارائهی نمونههای کش شدهی فریم ورکهای معروف، متداول هستند که در اینجا نمونهای از نحوهی تعریف آنها را مشاهده میکنید. همچنین تعریف fallback در اینجا به این معنا است که اگر CDN در دسترس نبود، به نمونهی محلی موجود بر روی سرور مراجعه شود.
<link rel="stylesheet" href="//ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/css/bootstrap.min.css"
asp-fallback-test-class="hidden"
asp-fallback-test-property="visibility"
asp-fallback-test-value="hidden" />
<script src="//ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/js/bootstrap.min.js"
asp-fallback-test="window.jQuery">
</script>
به علاوه اگر ویژگی asp-file-version را نیز ذکر کنید:
<link rel="stylesheet" href="~/css/site.min.css" asp-file-version="true"/>
یک چنین لینکی تولید میشود:
<link rel="stylesheet" href="/css/site.min.css?v=UdxKHVNJA5vb1EsG9O9uURFDfEE3j1E3DgwL6NiDGMc" />
هدف آن نیز اصطلاحا cache busting است. به این معنا که با تغییر محتوای این فایلها، کوئری استرینگ تولید شده، مجددا محاسبه شده و مرورگر همواره آخرین نگارش موجود را دریافت خواهد کرد و دیگر از نمونهی کش شدهی قدیمی استفاده نمیکند.
یک نکته: ویژگی asp-file-version را برای تصاویر هم میتوان بکار برد:
<img src="~/images/logo.png"
alt="company logo"
asp-file-version="true" />
که یک چنین خروجی را تولید میکند و هدف آن نیز جلوگیری از کش شدن تصویر، با تغییر محتوای آن است:
<img src="/images/logo.png?v=W2F5D366_nQ2fQqUk3URdgWy2ZekXjHzHJaY5yaiOOk"
alt="company logo"/>
بررسی Environment Tag Helper
با متغیرهای محیطی و نحوهی تعریف آنها
در قسمتهای قبل آشنا شدیم. در اینجا tag helper سفارشی خاصی برای کار با آنها ارائه شدهاست که شیبه به if/else عمل میکنند:
<environment names="Development">
<link rel="stylesheet" href="~/css/site1.css" />
<link rel="stylesheet" href="~/css/site2.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="~/css/site.min.css" asp-file-version="true"/>
</environment>
هدف این است که اگر متغیر محیطی به Development تنظیم شده بود، لینکهای ساده و اصلی فایلهای css یا اسکریپت در HTML نهایی درج شوند و اگر حالت توسعه تنظیم شده بود، لینکهای min یا فشرده شدهی آنها ارائه شوند؛ به همراه asp-file-version که cache busting را فعال میکند.
کار با دراپ داونها توسط Tag helpers
فرض کنید ViewModel یک view جهت نمایش یک دراپ داون به این صورت تنظیم شدهاست:
public class CustomerViewModel
{
public string Vehicle { get; set; }
public List<SelectListItem> Vehicles { get; set; }
برای نمایش SelectListItem توسط tag helpers میتوان به صورت ذیل عمل کرد:
<select asp-for="Vehicle" asp-items="Model.Vehicles">
</select>
asp-for به نام خاصیتی اشاره میکند که در نهایت مقدار انتخاب شده را دریافت میکند و asp-items لیست آیتمهای دراپ داون را رندر میکند.