كيفية عمل Tag Helpers Custom حسب الاحتياج
-
قد تحتاج في بعض الأحيان الى انشاء أدوات مخصصه في التطبيق، بحيث يتم تطويرها وانشاءها حسب الحاجة، وغير مرتبطة بالأدوات المبنية داخل ASP.NET Core. لذلك سنتعلم في هذا الدرس كيفية انشاء مثل هذه الأدوات وكيفية استخدامها.
افتح المشروع الخاص بنا StudentsAcademy ثم قم أولاً بإنشاء مجلد TagHelpers داخل التطبيق كما في الصورة:

using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement(Attributes = "background-color")]
public class BackgroundColorBt:TagHelper
{
public string BackgroundColor { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
}
}
}
using Microsoft.AspNetCore.Razor.TagHelpers
public class BackgroundColorBt:TagHelper
{
}
- يجب أن يكون اسم attribute بأسلوب html مثل background-color. لا يمكنك تعيين أسماء attribute التي تبدأ بـ -asp أو –data (الكلمات المحجوزه في Net Core.)الخ.
- يحتوي Tag Helper أيضًا على function Process يقوم بعمل override لوظيفة base class.يعمل هذا ال function على اضافة CSS class attribute إلى HTML element المستهدف.
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
[HtmlTargetElement(Attributes = "background-color")]
@addTagHelper StudentsAcademy.TagHelpers.*, StudentsAcademy
StudentsAcademy.TagHelpers.*
StudentsAcademy.TagHelpers.
@model IEnumerable<CoursesModel>
@{ ViewBag.Title = "All Courses";}
<h2>All Reservations</h2>
<a asp-action="AddCourse" class="btn btn-success" >Add New Course</a>
<button type="submit" background-color="danger">Add New Course</button>
<table class="table table-sm table-striped table-bordered m-2">
<thead><tr><th>CourseNumber</th><th>CourseName</th><th>Course Description</th><th>Course Price</th></tr></thead>
<tbody>
@if (Model != null)
{
foreach (var r in Model)
{
<tr>
<td>@r.CourseNumber</td>
<td>@r.CourseName</td>
<td>@r.CourseDescription</td>
<td>@r.Price</td>
</tr>
}
}
</tbody>
</table>
https://localhost:44382/courses/allcourses

btn btn-{property value}
- TagHelperContext
- TagHelperOutput
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
}
Description | Name |
يحتوي على قاموس للقراءة فقط لجميع attributes المطبقة على العنصر الجاري عمل transformed له. | AllAttributes |
يحتوي على unique identifier للعنصر الجاري عمل transformed له. | UniqueId |
تقوم بإرجاع قاموس يستخدم للتنسيق بين tag helpers ، | Items |
Description | Name |
الحصول على أو تعيين اسم العلامة ل output element. | TagName |
تقوم بإرجاع قاموس يحتوي على جميع attributes ل output element. | Attributes |
يستخدم لتعيين محتويات output element. | Content |
يستخدم لإدراج Elements قبل output element | PreElement |
يستخدم لإدراج Elements بعد output element | PostElement |
يستخدم لإدراج محتويات في output element قبل أي محتوى موجود. | PreContent |
يستخدم لإدراج محتويات في output element بعد أي محتوى موجود. | PostContent |
Description | Name |
يستخدم لاستبعاد عنصر exclude an element | SupressOuput() |
Description | Name |
تنص هذه الخاصية على أنه يجب تطبيق tag helper على elements التي لديها مجموعة من attributes. لنأخذ مثال على ذلك: background-color-* في هذه الحالة فان tag helper سيتطابق مع attribute التي تبدأ ب background-color- وما بعدها مثل background-color-white background-color-black | Attributes |
تنص هذه الخاصية على أنه يجب تطبيق tag helper على elements الموجودة داخل element من نوع معين. | ParentTag |
تنص هذه الخاصية على أنه يجب تطبيق tag helper على العناصر التي لها tag structure تتوافق مع قيمة معينة. تُعطى هذه القيمة من TagStructure enumeration الذي يعرّف " Unspecified’" و "NormalOrSelf Closing" و "WithoutEndTag" | TagStructure |
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("button", Attributes = "background-color")]
public class BackgroundColorBt:TagHelper
{
public string BackgroundColor { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
}
}
}
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("button", Attributes = "background-color", ParentTag = "form")]
public class BackgroundColorBt:TagHelper
{
public string BackgroundColor { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
}
}
}
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("button", Attributes = "background-color", ParentTag = "form")]
[HtmlTargetElement("a", Attributes = "background-color")]
[HtmlTargetElement("h1", Attributes = "background-color")]
public class BackgroundColorBt:TagHelper
{
public string BackgroundColor { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
}
}
}
<Mybutton type="submit" background-color="danger" />
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("Mybutton")]
public class MyButtonTH : TagHelper
{
public string Type { get; set; } = "Submit";
public string BackgroundColor { get; set; } = "primary";
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "button";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.SetAttribute("class", $"btn btn-{BackgroundColor}");
output.Attributes.SetAttribute("type", Type);
output.Content.SetContent("Click to Add Record");
}
}
}
- Type تحديد طبيعة هذا element انه من نوع Submit
- BackgroundColor تحديد خاصية هذا element بلون خلفيه يساوي primary
الخاصية | الوصف |
TagNam | تعمل على جعل Mybutton من نوع html button element. حيث تم اعطاءها القيمة button |
TagMode | تستخدم ايضا لتحديد أن هذا العنصر سيكتب باستخدام علامات البداية والنهاية. |
()SetAttribute | تستخدم لإضافة class attribute وهنا تم تحديد هذا class بانه من نوع btn btn-{BackgroundColor} حيث يتم ارسال القيمة BackgroundColor له من المتغير BackgroundColor |
()SetAttribute | تستخدم لإضافة Type attribute ويتم ارسال قيمة هذا Type من المغير Type |
()SetContent | لاضافة اسم او وصف إلى هذا button. |
<Mybutton type="submit" background-color="danger" />
@addTagHelper StudentsAcademy.TagHelpers.*, StudentsAcademy

[HtmlTargetElement("div", Attributes = "pre-post")]
- h1 - وهو موجود داخل div element
- div - الذي يحتوي على h1 element. وتم ايضا اضافة Attributes الى div element هذا من نوع Bootstrap classes لغرض التصميم.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
asp-fallback-href-include="/lib/bootstrap/**/*.min.css"
asp-fallback-href-exclude="**/*reboot*,**/*grid*"
asp-fallback-test-class="btn"
asp-fallback-test-property="display"
asp-fallback-test-value="inline-block"
rel="stylesheet" />
<link rel="stylesheet" asp-href-include="/lib/bootstrap/**/*min.css"
asp-href-exclude="**/*reboot*,**/*grid*" />
<script asp-src-include="lib/bootstrap/**/*.js" asp-src-exclude="**.slim.*,**.min.*,**.bundle.*" asp-append-version="true"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
asp-fallback-src-include="/lib/jquery/**/*.js"
asp-fallback-src-exclude="**.slim.**"
asp-fallback-test="window.jQuery">
</script>
</head>
<body>
<div class="container-fluid">
<div class="bg-info text-warning">
<cache expires-sliding="@TimeSpan.FromSeconds(10)" vary-by="@ViewContext.RouteData.Values["action"]">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
</div>
<div pre-post="Tag Helpers">
@RenderBody()
</div>
</div>
</body>
</html>
https://localhost:44382/home/index

- PreContent : يتم إدراج المحتويات قبل جميع المحتويات الموجودة.
- PostContent: يتم إدراج المحتويات بعد كل المحتويات الموجودة.
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("td", Attributes = "underline")]
public class PrePostContentTH : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.PreContent.SetHtmlContent("<u>");
output.PostContent.SetHtmlContent("</u>");
}
}
}
@model IEnumerable<CoursesModel>
@{ ViewBag.Title = "All Courses";}
<h2>All Reservations</h2>
<a asp-action="AddCourse" class="btn btn-success" >Add New Course</a>
<button type="submit" background-color="danger">Add New Course</button>
<Mybutton type="submit" background-color="danger" />
<table class="table table-sm table-striped table-bordered m-2">
<thead><tr><th>CourseNumber</th><th>CourseName</th><th>Course Description</th><th>Course Price</th></tr></thead>
<tbody>
@if (Model != null)
{
foreach (var r in Model)
{
<tr>
<td underline>@r.CourseNumber</td>
<td underline>@r.CourseName</td>
<td >@r.CourseDescription</td>
<td >@r.Price</td>
</tr>
}
}
</tbody>
</table>
https://localhost:44382/courses/allcourses

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace StudentsAcademy.TagHelpers
{
[HtmlTargetElement("div", Attributes = "theme")]
public class ParentThemeTH : TagHelper
{
public string Theme { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
context.Items["theme"] = Theme;
}
}
[HtmlTargetElement("button", ParentTag = "div")]
[HtmlTargetElement("a", ParentTag = "div")]
public class ChildThemeTH : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context.Items.ContainsKey("theme"))
output.Attributes.SetAttribute("class", $"btn btn-{context.Items["theme"]}");
}
}
}
- ParentThemeTH : هذا ال Function يعمل على div elements في View التي لها theme attribute. حيث يقوم بإضافة القيمة theme من المتغير public string Theme { get; set; } إلى قاموس العناصر Items dictionary بحيث تكون متاحة في هذا tag helpers ، ثم يتم تطبيقها على العناصر الموجودة داخل div element هذا.
- ChildThemeTH: يعمل على tag التالية buttons و anchor بشرط ان تكون موجودة داخل div element. يحصل tag helper هذا على القيم (المخزنة بواسطة ParentThemeTH) من قاموس العناصر. ثم يقوم بتعيين bootstrap CSS على buttons و anchors.
@model CoursesModel
@{
ViewData["Title"] = "Add New Course";
}
<h2>Add New Course</h2>
<form method="post" asp-controller="Courses" asp-action="AddCourse" asp-antiforgery="true">
<div class="form-group">
<label asp-for="CourseName">Course Name:</label>
<input class="form-control" asp-for="CourseName" />
</div>
<div class="form-group">
<label asp-for="CourseDescription">Course Description:</label>
<input class="form-control" asp-for="CourseDescription" />
</div>
<div class="form-group">
<label asp-for="Price">Price:</label>
<input class="form-control" asp-for="Price" />
</div>
<div class="form-group">
<label asp-for="Capacity">Capacity:</label>
<select class="form-control" asp-for="Capacity">
<option disabled selected value="">Select Capacity</option>
<option>25</option>
<option>30</option>
<option>35</option>
<option>40</option>
</select>
</div>
<div theme="primary">
<button type="submit">Add</button>
<a href="/Home/Index">Cancel</a>
</div>
@*<button type="submit" class="btn btn-primary">Add</button>*@
</form>

<div theme="success">
<button type="submit">Add</button>
<a href="/Home/Index">Cancel</a>
</div>

[ViewContext][HtmlAttributeNotBound]public ViewContext ViewContextData { get; set; }
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Rendering;using Microsoft.AspNetCore.Mvc.Routing;using Microsoft.AspNetCore.Mvc.ViewFeatures;using Microsoft.AspNetCore.Razor.TagHelpers;namespace TagHelpers.CustomTagHelpers{[HtmlTargetElement("form")]public class FormTH : TagHelper{private IUrlHelperFactory urlHelperFactory;public FormTH(IUrlHelperFactory factory){urlHelperFactory = factory;}[ViewContext][HtmlAttributeNotBound]public ViewContext ViewContextData { get; set; }public override void Process(TagHelperContext context, TagHelperOutput output){IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContextData);output.Attributes.SetAttribute("action", urlHelper.Action(ViewContextData.RouteData.Values["action"].ToString(), ViewContextData.RouteData.Values["controller"].ToString()));}}}
urlHelper.Action(ViewContextData.RouteData.Values["action"].ToString(), ViewContextData.RouteData.Values["controller"].ToString())
<form method="post">....</form>
URL - https://localhost:44327/Home/Create
<form method="post" action="/Home/Create">....</form>
using Microsoft.AspNetCore.Mvc.Rendering;using Microsoft.AspNetCore.Mvc.ViewFeatures;using Microsoft.AspNetCore.Razor.TagHelpers;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace StudentsAcademy.TagHelpers{[HtmlTargetElement(Attributes = "action-name")]public class SuppressOutputTH :TagHelper{public string ActionName { get; set; }[ViewContext][HtmlAttributeNotBound]public ViewContext ViewContext { get; set; }public override void Process(TagHelperContext context, TagHelperOutput output){if (!ViewContext.RouteData.Values["action"].ToString().Equals(ActionName))output.SuppressOutput();}}}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
asp-fallback-href-include="/lib/bootstrap/**/*.min.css"
asp-fallback-href-exclude="**/*reboot*,**/*grid*"
asp-fallback-test-class="btn"
asp-fallback-test-property="display"
asp-fallback-test-value="inline-block"
rel="stylesheet" />
<link rel="stylesheet" asp-href-include="/lib/bootstrap/**/*min.css"
asp-href-exclude="**/*reboot*,**/*grid*" />
<script asp-src-include="lib/bootstrap/**/*.js" asp-src-exclude="**.slim.*,**.min.*,**.bundle.*" asp-append-version="true"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
asp-fallback-src-include="/lib/jquery/**/*.js"
asp-fallback-src-exclude="**.slim.**"
asp-fallback-test="window.jQuery">
</script>
</head>
<body>
<div class="container-fluid">
<div class="bg-info text-warning">
<cache expires-sliding="@TimeSpan.FromSeconds(10)" vary-by="@ViewContext.RouteData.Values["action"]">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
</div>
<div action-name="Index" class="bg-secondary">
<h2>Welcome To Students Academy</h2>
</div>
@*<div pre-post="Tag Helpers">*@
@RenderBody()
@*</div>*@
</div>
</body>
</html>
https://localhost:44382/home/index

https://localhost:44382/courses/allcourses

اترك تعليقك