Razor Syntax Reference Implicit Razor expressions <p>@DateTime.Now</p> <p>@DateTime.IsLeapYear(2016)</p> <p>@await DoSomething("hello", "world")</p> Explicit Razor expressions <p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p> @{ var joe = new Person("Joe", 33); } <p>Age@(joe.Age)</p> Expression encoding @("<span>Hello World</span>") @Html.Raw("<span>Hello World</span>") Implicit transitions @{ var inCSharp = true; <p>Now in HTML, was in C# @inCSharp</p> } Explicit delimited transition @for (var i = 0; i < people.Length; i++) { var person = people[i]; <text>Name: @person.Name</text> @:Name: @person.Name//Explicit Line Transition with @: } @try { throw new InvalidOperationException("You did something invalid."); } catch (Exception ex) { <p>The exception message: @ex.Message</p> } finally { <p>The finally statement.</p> } @lock (SomeLock) { // Do critical section work } using Microsoft.AspNetCore.Mvc.Razor; public abstract class CustomRazorPage<TModel> : RazorPage<TModel> { public string CustomText { get; } = "Hello World."; } @inherits CustomRazorPage<TModel> <div>Custom text: @CustomText</div> @functions { public string GetHello() { return "Hello"; } } <div>From method: @GetHello()</div> Razor keywords •functions •inherits •model •section •helper (Not supported by ASP.NET Core.) C# Razor keywords •case •do •default •for •foreach •if •lock •switch •try •using •while ---------------------------------------------------------------------------------------------------- Layout The "_ViewImports" file supports the following directives: •@addTagHelper, @removeTagHelper: all run, in order •@tagHelperPrefix: the closest one to the view overrides any others •@model: the closest one to the view overrides any others •@inherits: the closest one to the view overrides any others •@using: all are included; duplicates are ignored •@inject: for each property, the closest one to the view overrides any others with the same property name ----------------------------------------------------------------------------------------------------- Working with Forms The Templates Path: ------------------------------------------------------------------------------------------------------ @model Person @{ var index = (int)ViewData["index"]; } <form asp-controller="ToDo" asp-action="Edit" method="post"> @Html.EditorFor(m => m.Colors[index]) <label asp-for="Age"></label> <input asp-for="Age" /><br /> <button type="submit">Post</button> </form> Views/Shared/EditorTemplates/String.cshtml @model string <label asp-for="@Model"></label> <input asp-for="@Model" /> <br /> ----------------------------------------------------------------------------------------------------- @model CountryViewModel <form asp-controller="Home" asp-action="IndexEmpty" method="post"> @Html.EditorForModel() <br /><button type="submit">Register</button> </form> Views/Shared/EditorTemplates/CountryViewModel.cshtml @model CountryViewModel <select asp-for="Country" asp-items="Model.Countries"> <option value="">--none--</option> </select> ---------------------------------------------------------------------------------------------------- Authoring Tag Helpers @using AuthoringTagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper "AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers" <address> <strong>Support:</strong><email mail-to="Support"></email><br /> <strong>Marketing:</strong><email mail-to="Marketing"></email> </address> public class EmailTagHelper : TagHelper { private const string EmailDomain = "contoso.com"; // Can be passed via <email mail-to="..." />. // Pascal case gets translated into lower-kebab-case. //public string MailTo { get; set; } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "a";// Replaces <email> with <a> tag //var address = MailTo + "@" + EmailDomain; var content = await output.GetChildContentAsync(); var target = content.GetContent() + "@" + EmailDomain; output.Attributes.SetAttribute("href", "mailto:" + target); output.Content.SetContent(target); } } [HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)] public class EmailVoidTagHelper : TagHelper [HtmlTargetElement("Website-Information")] public class WebsiteInformationTagHelper : TagHelper { public WebsiteContext Info { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "section"; output.Content.SetHtmlContent( $@"<ul><li><strong>Version:</strong> {Info.Version}</li> <li><strong>Copyright Year:</strong> {Info.CopyrightYear}</li> <li><strong>Approved:</strong> {Info.Approved}</li> <li><strong>Number of tags to show:</strong> {Info.TagsToShow}</li></ul>"); output.TagMode = TagMode.StartTagAndEndTag; } } <website-information info="new WebsiteContext { Version = new Version(1, 3), CopyrightYear = 1638, Approved = true, TagsToShow = 131 }" /> [HtmlTargetElement(Attributes = nameof(Condition))] public class ConditionTagHelper : TagHelper { public bool Condition { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { if (!Condition) { output.SuppressOutput(); } } } <div condition="Model.Approved"> <p> This website has <strong surround="em"> @Model.Approved </strong> been approved yet. Visit www.contoso.com for more information. </p> </div> public class AutoLinkerHttpTagHelper : TagHelper { // This filter must run before the AutoLinkerWwwTagHelper as it searches and replaces http and // the AutoLinkerWwwTagHelper adds http to the markup. public override int Order { get { return int.MinValue; } } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent, @"(?:https?://)(S+)", "<a target="_blank" href="$0">$0</a>")); // http link version} } } [HtmlTargetElement("p")] public class AutoLinkerWwwTagHelper : TagHelper { public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var childContent = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); // Find Urls in the content and replace them with their anchor tag equivalent. output.Content.SetHtmlContent(Regex.Replace( childContent, @"(www.)(S+)", "<a target="_blank" href="http://$0">$0</a>")); // www version } } } ---------------------------------------------------------------------------------------------------- Partial Views @Html.Partial("AuthorPartial") @await Html.PartialAsync("AuthorPartial") @{ Html.RenderPartial("AuthorPartial"); } @Html.Partial("ViewName") @Html.Partial("ViewName.cshtml") @Html.Partial("~/Views/Folder/ViewName.cshtml") @Html.Partial("/Views/Folder/ViewName.cshtml") @Html.Partial("../Account/LoginPartial.cshtml") --------------------------------------------------------------------------------------------------- View Components View search path: •Views/<controller_name>/Components/<view_component_name>/<view_name> •Views/Shared/Components/<view_component_name>/<view_name> <div > @await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false }) </div> public IActionResult IndexVC() { return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false }); } //[ViewComponent(Name = "PriorityList")] //public class XYZ : ViewComponent public class PriorityListViewComponent : ViewComponent { private readonly ToDoContext db; public PriorityListViewComponent(ToDoContext context) { db = context; } public async Task<IViewComponentResult> InvokeAsync( int maxPriority, bool isDone) { string MyView = "Default"; // If asking for all completed tasks, render with the "PVC" view. if (maxPriority > 3 && isDone == true) { MyView = "PVC"; } var items = await GetItemsAsync(maxPriority, isDone); return View(MyView, items); } private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone) { return db.ToDo.Where(x => x.IsDone == isDone && x.Priority <= maxPriority).ToListAsync(); } } -----------------------------------------------------------------------------------------------