مقدمه في Built-In Tag Helpers
-
الغرض من Built-In Tag Helpers هو الدمج بين Server-side و Html Elements كما ذكرنا سابقا، وتستخدم داخليًا في ملفات Razor. تستخدم لتنفيذ مجموعة كبيرة من العمليات والاوامرعلى Html Elements . سنناقش هنا هذه Tag Helpers وكيفية ربطها مع Form, Input, Select, Label, Anchor Text Area elements, CSS, JS and Cache.
استخدام Tag Helper في Form Element
تُستخدم Built-in Tag Helpers فيForm Element لإنشاء action attribute. وهذه Tag Helpers
هي :
Description | Method |
يستخدم لتحديد Action التي سيتم الربط معها بناءً على نظام التوجيه.إذا تم حذفه ، فسيتم استخدام action في view الحالي. | asp-action |
تستخدم لتحديد controller التي سيتم الربط معها بناءً على نظام التوجيه.في حال عدم وجوده، فسيتم استخدام controller في view الحالي. | asp-controller |
يستخدم لتحديد اسم المسار المطلوب لتوليد action attribute | asp-route |
يستخدم لتحديد قيمة segment الإضافي لعنوان URL، على سبيل المثال ، يتم استخدام asp-route-id لتقديم قيمة ل id segment. | asp-route-* |
يولد رمزًا مخفيًا للتحقق من الطلب لمنع تزوير cross-site الطلبات عبر المواقع. يتم استخدامه مع [ValidateAntiForgeryToken] attribute في HTTP Post action method | asp-antiforgery |
يستخدم لتحديد اسم area المستهدفة. | asp-area |
اكيد ان معظم هذه الادوات استخدمناها في الدروس السابقه، سنقوم هنا باعادة استخدامها وتطبيقها بشكل موسع.
الوصف | Name |
تستخدم لتحديد controller المستهدف الذي سيتم ربط URL به | asp-controller |
تستخدم لتحديد action المستهدف الذي سيتم ربط URL به | asp-action |
تستخدم لتحديد action في حال استخدامها في التطبيق المستهدف الذي سيتم ربط URL به | asp-area |
تستخدم لتحديد fragment (جزء من الصفحه) ويتم عرضه باستخدام ‘#’ character | asp-fragment |
تستخدم لتحديد route name المستهدف الذي سيتم ربط URL به | as-route |
تحدد قيمة المتغيرلإضافيي لعنوان URL الذي سيتم ربط URL به. مثال asp-route-id = "10" يتم توفير القيمة 10 ل id segment الخاص بهذا route. | asp-route-* |

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Models
{
public class CoursesModel
{
public int ID { get; set; }
public string CourseNumber { get; set; }
public string CourseName { get; set; }
public string CourseDescription { get; set; }
public decimal Price { get; set; }
public int Capacity { get; set; }
public DateTime CreatedDate { get; set; }
}
}

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using StudentsAcademy.Area.StudentPortal.Models;
using StudentsAcademy.Interface;
using StudentsAcademy.Models;
using StudentsAcademy.Repository;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace StudentsAcademy.Controllers
{
public class CoursesController : Controller
{
public IConfiguration Configuration { get; }
private ICourses Coursesrepository;
public CoursesController(ICourses repo, IConfiguration configuration)
{
Coursesrepository = repo;
Configuration = configuration;
}
public IActionResult Index()
{
return View(Coursesrepository.coursesModel);
}
public IActionResult AllCourses()
{
List<CoursesModel> MyCoursesList = new List<CoursesModel>();
try
{
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataTable dataTable = new DataTable();
string sql = @"select * from courses";
SqlCommand command = new SqlCommand(sql, connection);
command.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
// filling records to DataTable
dataAdapter.Fill(dataTable);
foreach (DataRow item in dataTable.Rows)
{
MyCoursesList.Add(new CoursesModel
{
ID = Convert.ToInt32(item["CoursesId"]),
CourseNumber = Convert.ToString(item["CourseNumber"]),
CourseName = Convert.ToString(item["CourseName"]),
CourseDescription = Convert.ToString(item["CourseDescription"]),
Price = Convert.ToDecimal(item["Price"]),
Capacity = Convert.ToInt32(item["Capacity"]),
CreatedDate = Convert.ToDateTime(item["CreatedDate"]),
});
}
}
}
catch (Exception ex)
{
}
finally
{
}
return View(MyCoursesList);
}
}
}
List<MyCourses> MyCoursesList = new List<MyCourses>();
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataTable dataTable = new DataTable();
string sql = @"select * from courses";
SqlCommand command = new SqlCommand(sql, connection);
command.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
// filling records to DataTable
dataAdapter.Fill(dataTable);
}
foreach (DataRow item in dataTable.Rows)
{
MyCoursesList.Add(new MyCourses
{
ID = Convert.ToInt32(item["CoursesId"]),
CourseNumber = Convert.ToString(item["CourseNumber"]),
CourseName = Convert.ToString(item["CourseName"]),
CourseDescription = Convert.ToString(item["CourseDescription"]),
Price = Convert.ToDecimal(item["Price"]),
Capacity = Convert.ToInt32(item["Capacity"]),
CreatedDate = Convert.ToDateTime(item["CreatedDate"]),
});
}


@model IEnumerable<CoursesModel>
@{ ViewBag.Title = "All Courses";}
<h2>All Reservations</h2>
<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

<a asp-action="AddCourse" class="btn btn-success" >Add New Course</a>
asp-action="AddCourse"
https://localhost:44382/Courses/AllCourses

// HTTP GET VERSION
public IActionResult AddCourse()
{
return View();
}
[HttpPost]
public IActionResult AddCourse(CoursesModel coursesModel)
{
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = $"set dateformat dmy Insert Into Courses (CourseName,CourseDescription,Price,Capacity,CreatedDate) Values (@CourseName,@CourseDescription,@Price,@Capacity,@CreatedDate)";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandType = CommandType.Text;
// adding parameters
SqlParameter parameter = new SqlParameter
{
ParameterName = "@CourseName",
Value = coursesModel.CourseName,
SqlDbType = SqlDbType.NVarChar,
Size = 200
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@CourseDescription",
Value = coursesModel.CourseDescription,
SqlDbType = SqlDbType.NVarChar
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@Price",
Value = coursesModel.Price,
SqlDbType = SqlDbType.Int
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@Capacity",
Value = coursesModel.Capacity,
SqlDbType = SqlDbType.Int
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@CreatedDate",
Value = DateTime.Now,
SqlDbType = SqlDbType.DateTime
};
command.Parameters.Add(parameter);
connection.Open();
command.ExecuteNonQuery();
ViewBag.Result = "Success";
connection.Close();
}
}
return View("AllCourses");
}
@model CoursesModel
@{
ViewData["Title"] = "Add New Course";
}
<h2>Add New Course</h2>
<form method="post" asp-controller="Courses" asp-action="AddCourse">
<div class="form-group">
<label for="CourseName">Course Name:</label>
<input class="form-control" name="CourseName" />
</div>
<div class="form-group">
<label for="CourseDescription">Course Description:</label>
<input class="form-control" name="CourseDescription" />
</div>
<div class="form-group">
<label for="Price">Price:</label>
<input class="form-control" name="Price" />
</div>
<div class="form-group">
<label for="Capacity">Capacity:</label>
<input class="form-control" name="Capacity" />
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
asp-controller="Courses", asp-action="AddCourse"
<div class="form-group">
<label for="CourseName">Course Name:</label>
<input class="form-control" name="CourseName" />
</div>
for="CourseName"
name="CourseName".



<form method="post">
....
</form>
- يضيف security token في hidden input element إلى form.
- يضيف ملف cookie إلى response.
tag helper – asp-antiforgery="true"
@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 for="CourseName">Course Name:</label>
<input class="form-control" name="CourseName" />
</div>
<div class="form-group">
<label for="CourseDescription">Course Description:</label>
<input class="form-control" name="CourseDescription" />
</div>
<div class="form-group">
<label for="Price">Price:</label>
<input class="form-control" name="Price" />
</div>
<div class="form-group">
<label for="Capacity">Capacity:</label>
<input class="form-control" name="Capacity" />
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddCourse(CoursesModel coursesModel)
{
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = $"set dateformat dmy Insert Into Courses (CourseName,CourseDescription,Price,Capacity,CreatedDate) Values (@CourseName,@CourseDescription,@Price,@Capacity,@CreatedDate)";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandType = CommandType.Text;
// adding parameters
SqlParameter parameter = new SqlParameter
{
ParameterName = "@CourseName",
Value = coursesModel.CourseName,
SqlDbType = SqlDbType.NVarChar,
Size = 200
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@CourseDescription",
Value = coursesModel.CourseDescription,
SqlDbType = SqlDbType.NVarChar
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@Price",
Value = coursesModel.Price,
SqlDbType = SqlDbType.Int
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@Capacity",
Value = coursesModel.Capacity,
SqlDbType = SqlDbType.Int
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@CreatedDate",
Value = DateTime.Now,
SqlDbType = SqlDbType.DateTime
};
command.Parameters.Add(parameter);
connection.Open();
command.ExecuteNonQuery();
ViewBag.Result = "Success";
connection.Close();
}
}
return View("AllCourses");
}



@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>
<input class="form-control" asp-for="Capacity" />
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>

- يعين attribute الخاصة ب label وذلك بربط Label مع Model property’s name.
- يعين محتوى labels بخاصية Model Property.
<div class="form-group">
<label asp-for="CourseName">Course Name:</label>
<input class="form-control" asp-for="CourseName" />
</div>
Type attribute for Input Element | Model Type |
Number | byte, sbyte, int, uint, short, ushort, long, ulong |
text | float, double, decimal |
text | string |
checkbox | bool |
datetime | DateTime |
Description | Name |
يعمل على تعين Id، Name ل the Select element بناء على Model Property name. | asp-for |
يحدد مصدر القيم ل option elements الموجودة داخل Select element. | asp-items |
<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>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Share.Enums
{
public enum Capacity
{
Capacity1=25,
Capacity2=30,
Capacity3=35,
Capacity4=40
}
}
<cache>
Some Content
</cache>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
</head>
<body>
<div class="container-fluid">
<div class="bg-info text-warning">
<cache>
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
</div>
@RenderBody()
</div>
</body>
</html>

Description | Name |
ريعمل على تحدد وقت وتاريخ حيث ستنتهي فيه ذاكرة التخزين المؤقت. | expires-on |
يعمل على تحديد الوقت TimeSpan الذي ستنتهي عنده ذاكرة التخزين المؤقت. | expires-after |
Sliding time هو الفترة المنقضية منذ آخر استخدام.لذلك يعمل tag helper هذا على تحديد Sliding time الذي تنتهي فيه ذاكرة التخزين المؤقت. | expires-sliding |
يحدد query string key الذي سيتم استخدامه للإدارة ،الإصدارات المختلفة لمحتويات ذاكرة التخزين المؤقت. | vary-by-query |
يحدد cookie الذي سيتم استخدامه للإدارة الإصدارات المختلفة لمحتويات ذاكرة التخزين المؤقت. | vary-by-cookie |
يحدد مفتاحًا key لإدارة الإصدارات المختلفة لمحتويات ذاكرة التخزين المؤقت. | vary-by |
<cache expires-after="@TimeSpan.FromSeconds(50)">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
<cache expires-on="@DateTime.Parse("2050-01-01")">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
<cache expires-sliding="@TimeSpan.FromSeconds(20)">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
<cache expires-sliding="@TimeSpan.FromSeconds(10)" vary-by = "@ViewContext.RouteData.Values["action"]">
Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>
الوصف | الاسم |
يحدد ملفات JavaScript التي سيتم تضمينها في View. | asp-src-include |
يحدد ملفات JavaScript المراد استبعادها من View.. | asp-src-exclude |
يحدد ملف JavaScript المراد تضمينه في حالة وجود مشكلة ما مع شبكة توصيل المحتوى Content Delivery Network. | asp-fallback-src-include |
يحدد ملف JavaScript لاستبعاده إذا كانت هناك مشكلة ما مع شبكة توصيل المحتوى Content Delivery Network. | asp-fallback-src-exclude |
يحدد جزءًا من JavaScript سيتم استخدامه إذا تم تحميل JavaScript بشكل صحيح من شبكة توصيل المحتوى Content Delivery Network. | asp-fallback-test |
يحدد query string التي سيتم تطبيقها على مسار ملفات JavaScript كلما تغيرت محتويات الملف. يستخدم هذا في خرق ذاكرة التخزين المؤقت Cache Busting | asp-append-version |
Description | Example | Pattern |
يطابق نمطًا واحدًا فقط ، حيث يعمل على مطابقة ما بعد الاشارة / فقط ويعمل على استبعاد غير ذلك. امثلة التطابق JS/myscript1.js JS/myscriptZ.js JS/myscripts.js | JS/myscript?.js | ? |
يتطابق مع أي عدد من الأحرف لاول مقطع بعد "/" بحيث اذا توفر اكثر من مقطع سيتم استبعاده. امثلة التطابق JS/myscript.js JS/validate.js JS/js123.js | JS/*.js | * |
يتطابق مع أي عدد من الأحرف بما في ذلك "/" بحيث يتطابق مع اي عدد من المقاطع. امثلة التطابق JS/Validate/myscript.js JS/jQuery/validate.js JS/js123.js | JS/**.js | ** |

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></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>@RenderBody()
</div>
</body>
</html>
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width" /><title>@ViewBag.Title</title><link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" /><script asp-src-include="lib/bootstrap/**/*.js"></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>@RenderBody()</div></body></html>


<script asp-src-include="/lib/bootstrap/**/*bundle.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
<script asp-src-include="lib/bootstrap/**/*.js" asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"></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>
@RenderBody()
</div>
</body>
</html>

asp-append-version Tag Helper.
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
<script asp-src-include="lib/bootstrap/**/*.js" asp-src-exclude="**.slim.*,**.min.*,**.bundle.*" asp-append-version="true"></script>
</head>

asp-fallback-src-include
asp-fallback-src-exclude
asp-fallback-test
http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
asp-fallback-src-include="/lib/jquery/**/*.min.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>
@RenderBody()
</div>
</body>
</html>
Description | Name |
يحدد ملفات CSS التي سيتم تضمينها في طريقة View | asp-href-include |
يحدد ملفات CSS التي سيتم استبعادها من View. | asp-href-exclude |
يحدد query string التي سيتم تطبيقها على مسار ملف CSS، كلما تغيرت محتويات الملف. يستخدم هذا في Cache Busting. | asp-append-version |
يحدد ملف CSS المراد تضمينه في حالة وجود مشكلة ما في Content Delivery Network | asp-fallback-href-include |
يحدد ملف CSS لاستبعاده إذا كانت هناك مشكلة ما في Content Delivery Network | asp-fallback-href-exclude |
تحدد فئة CSS التي سيتم استخدامها لاختبار Content Delivery Network. | asp-fallback-href-test-class |
تحدد CSS class property التي سيتم استخدامها لاختبار Content Delivery Network | asp-fallback-href-test-property |
يحدد قيمة CSS class property التي سيتم استخدامها اختبار Content Delivery Network. | asp-fallback-href-test-property |

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@*<link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" />*@
<link rel="stylesheet" asp-href-include="/lib/bootstrap/**/*min.css" />
<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>
@RenderBody()
</div>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<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>
@RenderBody()
</div>
</body>
</html>

<!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>
@RenderBody()
</div>
</body>
</html>
- asp-backback-test-class
- asp-fallback-test-property
- asp-backback-test-value

اترك تعليقك