From 4213e63ca436224554f146f131503cffbeb9a9bb Mon Sep 17 00:00:00 2001 From: pkellner Date: Tue, 29 Nov 2016 22:06:45 -0800 Subject: [PATCH 1/8] Added Sample VS Project. Updated AnchorTagHelper.md to include reference to SpeakerController.cs. Improved AnchorTagHelper.md documentation to be more consistent per docs guide. --- .../builtin/resources/AnchorTagHelper.md | 60 ++++--- .../TagHelpersBuiltInAspNetCore/global.json | 6 + .../Areas/Blogs/Controllers/HomeController.cs | 21 +++ .../Areas/Blogs/Views/Home/AboutBlog.cshtml | 7 + .../Areas/Blogs/Views/Home/Index.cshtml | 7 + .../Controllers/BuiltInTag.cs | 24 +++ .../Controllers/HomeController.cs | 55 ++++++ .../Controllers/SpeakerController.cs | 52 ++++++ .../PrettyTagHelperTagHelper.cs | 96 ++++++++++ .../TagHelpersBuiltInAspNetCore/Program.cs | 24 +++ .../TagHelpersBuiltInAspNetCore/Startup.cs | 65 +++++++ .../TagHelpersBuiltInAspNetCore.xproj | 23 +++ .../Views/BuiltInTag/AnchorTagHelper.cshtml | 166 ++++++++++++++++++ .../Views/Home/About.cshtml | 7 + .../Views/Home/Contact.cshtml | 17 ++ .../Views/Home/Index.cshtml | 109 ++++++++++++ .../Views/Shared/Error.cshtml | 14 ++ .../Views/Shared/_Layout.cshtml | 67 +++++++ .../Views/Speaker/Detail.cshtml | 7 + .../Views/Speaker/Evaluations.cshtml | 7 + .../Views/Speaker/Index.cshtml | 13 ++ .../Views/_ViewImports.cshtml | 3 + .../Views/_ViewStart.cshtml | 3 + .../appsettings.json | 10 ++ .../TagHelpersBuiltInAspNetCore/bower.json | 10 ++ .../bundleconfig.json | 24 +++ .../TagHelpersBuiltInAspNetCore/project.json | 65 +++++++ .../TagHelpersBuiltInAspNetCore/web.config | 14 ++ 28 files changed, 947 insertions(+), 29 deletions(-) create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/global.json create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Controllers/HomeController.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/AboutBlog.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/Index.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/BuiltInTag.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/HomeController.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/PrettyTagHelperTagHelper.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Program.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Startup.cs create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/TagHelpersBuiltInAspNetCore.xproj create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/BuiltInTag/AnchorTagHelper.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/About.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Contact.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Index.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/Error.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/_Layout.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Detail.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Evaluations.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Index.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewImports.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewStart.cshtml create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/appsettings.json create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bower.json create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bundleconfig.json create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/project.json create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/web.config diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md index 4b8e07bf1919..395b5a585716 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md @@ -3,44 +3,48 @@ # AnchorTagHelper +By [Peter Kellner](http://peterkellner.net) -The AnchorTagHelper enhances the anchor (``). A new set of attributes are defined that work with the anchor tag such that the link generated (on the href tag) is based on a combination of these new attributes that work together to form the final redirect URL which includes an optional protocol update such as https. -For reference, the following ASP.NET ```startup.cs``` and ```SpeakerController.cs``` are defined as though in a default Visual Studio .Net Core Web Project. +The ```AnchorTagHelper``` enhances the html anchor (``) tag. A new set of attributes are defined that work with the anchor tag. The link generated (on the href tag) is based on a combination of these new attributes that work together to form the final redirect URL. That URL can include an optional protocol such as https. + +For reference, the following ASP.NET ```startup.cs``` and ```SpeakerController.cs``` are defined as you would expect in a default Visual Studio .Net Core Web Project. ![](../_static/ProjectControllers.png) **Startup.cs** ``` // This method gets called by the runtime. -// Use this method to configure the HTTP request pipeline. +// Use this method to configure the +// HTTP request pipeline. public void Configure(IApplicationBuilder app, - IHostingEnvironment env, ILoggerFactory loggerFactory) + IHostingEnvironment env, + ILoggerFactory loggerFactory) { app.UseMvcWithDefaultRoute(); //... } ``` -**SpeakerController.cs** Missing +
+**SpeakerController.cs** - +
These attributes are defined as follows: ## asp-controller -```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details we would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely be meaningless. +```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details you would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely not be what you expect. ## asp-action -```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in our example, if the route to the Speaker Detail page is desired then the attribute should be set to ```asp-action=Detail```. It is recommended to always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely be meaningless. +```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to ```asp-action=Detail```. You should always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely not be what you expect. ## asp-route- -```asp-route-``` is a wild card route prefix of sorts. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: +```asp-route-``` is basically a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: ```Speaker 11``` @@ -48,11 +52,11 @@ the href generated will be ```Speaker 11``` -This is because a route was found that matched a single parameter "id" in the speaker controller method Detail. If there was no parameter match, say for example you create the tag helper +This is because a route was found that matched a single parameter "id" in the ```SpeakerController``` method ```Detail```. If there was no parameter match, say for example you created the tag helper ```Ronald``` -you would get generate the html +you would get generated the html ```Ronald``` @@ -60,11 +64,11 @@ This is because there was no route found that matched a controller that had a me ## asp-route -```asp-route``` provides a way to create a URL that links directly to a **named route**. Using routing attributes, you can name your routes as shown in the Evaluations method above of the Speaker controller. ```Name = "speakerevals"``` tell the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action```. +```asp-route``` provides a way to create a URL that links directly to a named route. Using routing attributes, you can name your routes as shown in the Evaluations method above of the ```SpeakerController```. ```Name = "speakerevals"``` tells the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action``` to avoid a route conflict. ## asp-all-route-data -```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As an example, create an inline dictinary on your razor page and then create the ```AnchorTagHelper``` right after that (you could of course pass in the dictionary with or as your model also). +```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As the example below shows, you can create an inline dictionary on your razor page and then create the ```AnchorTagHelper``` right after that. You could of course pass in the dictionary with your model or as your model. That avoids having extra c# code on your razor page and gives you better control of the data passed to your view. ``` @{ @@ -82,18 +86,16 @@ This is because there was no route found that matched a controller that had a me The code that this generates looks as follows: ``` -http://localhost:1392/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true +http://localhost/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true ``` -When clicked, this will call the controller method ```EvaluationsCurrent``` because that controller has two string parameters that match what has been created from the -``` -asp-all-route-data -``` +When the link is clicked, this will call the controller method ```EvaluationsCurrent``` because that controller has two string parameters that match what has been created from the ``` +asp-all-route-data``` dictionary. ## asp-fragment -```asp-fragment``` appends after a ```#``` tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag +```asp-fragment``` appends after a hash (```#```) tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag ``` Blogs About ``` -The generated HTML will include the areas segment and be as follows: +The generated HTML will include the areas segment and will be as follows: ``` Blogs About ``` > [!TIP] -> For MVC Areas to work in your web application, the route template must include a reference to the area if it is exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. +> For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. ## asp-protocol -The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example AnchorTagHelper that includes the protocl will look as follows. +The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. ```About``` -will generate HTML as follows. +and will generate HTML as follows. ```About``` -(of course the domain, in the case above, is localhost but this will be substituted for whatever the actual domain hosting the web site is). +(of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/global.json b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/global.json new file mode 100644 index 000000000000..e793049cd534 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/global.json @@ -0,0 +1,6 @@ +{ + "projects": [ "src", "test" ], + "sdk": { + "version": "1.0.0-preview2-003121" + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Controllers/HomeController.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Controllers/HomeController.cs new file mode 100644 index 000000000000..befbd44e601c --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Controllers/HomeController.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Mvc; +namespace TagHelpersBuiltInAspNetCore.Areas.Blogs.Controllers +{ + [Area("Blogs")] + public class HomeController : Controller + { + // GET: // + // need route and attribute on controller: [Area("Blogs")] + //[Area("Blogs")] + public IActionResult Index() + { + return View(); + } + + //[Area("Blogs")] + public IActionResult AboutBlog() + { + return View(); + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/AboutBlog.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/AboutBlog.cshtml new file mode 100644 index 000000000000..95619e2184f0 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/AboutBlog.cshtml @@ -0,0 +1,7 @@ +@model dynamic + +@{ + ViewBag.Title = "About Blog Home Index (Area)"; +} + +

About Blog Home Index

diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/Index.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/Index.cshtml new file mode 100644 index 000000000000..85c9c91237b9 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Areas/Blogs/Views/Home/Index.cshtml @@ -0,0 +1,7 @@ +@model dynamic + +@{ + ViewBag.Title = "Blog (Area) Home Index"; +} + +

Blog Home Index

diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/BuiltInTag.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/BuiltInTag.cs new file mode 100644 index 000000000000..bc13a9bb964a --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/BuiltInTag.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 + +namespace TagHelpersBuiltInAspNetCore.Controllers +{ + public class BuiltInTag : Controller + { + // GET: // + public IActionResult Index() + { + return View(); + } + + public IActionResult AnchorTagHelper() + { + return View(); + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/HomeController.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/HomeController.cs new file mode 100644 index 000000000000..b9a2595bc98d --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/HomeController.cs @@ -0,0 +1,55 @@ +using Microsoft.AspNetCore.Mvc; + +namespace TagHelpersBuiltInAspNetCore.Controllers +{ + public class HomeController : Controller + { + public IActionResult Index() + { + return View(); + } + + public IActionResult Index(int number) + { + ViewData["Id"] = number.ToString(); + + return View(); + } + + public IActionResult About() + { + ViewData["Message"] = "Your application description page."; + + return View(); + } + + public IActionResult NonSuckyYouTubeEmbed() + { + return View(); + } + + public IActionResult Sample() + { + return View(); + } + + + + public IActionResult Contact() + { + ViewData["Message"] = "Your contact page."; + + return View(); + } + + public IActionResult Error() + { + return View(); + } + + public IActionResult AboutBlog() + { + return View(); + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs new file mode 100644 index 000000000000..d6b6007fc7c1 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; + +namespace TagHelpersBuiltInAspNetCore.Controllers +{ + public class SpeakerController : Controller + { + public List Speakers = + new List + { + new ModelData {SpeakerId = 10}, + new ModelData {SpeakerId = 11}, + new ModelData {SpeakerId = 12} + }; + + [Route("Speaker/{id:int}")] + public IActionResult Detail(int id) + { + return View(Speakers. + FirstOrDefault(a => a.SpeakerId == id)); + } + + + [Route("/Speaker/Evaluations", + Name = "speakerevals")] + public IActionResult Evaluations() + { + return View(); + } + + [Route("/Speaker/EvaluationsCurrent", + Name = "speakerevalscurrent")] + public IActionResult + EvaluationsCurrent(string speakerId, + string currentYear) + { + return View(); + } + + // GET: // + public IActionResult Index() + { + return View(Speakers); + } + } + + public class ModelData + { + public int SpeakerId { get; set; } + } +} \ No newline at end of file diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/PrettyTagHelperTagHelper.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/PrettyTagHelperTagHelper.cs new file mode 100644 index 000000000000..d7857e62062a --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/PrettyTagHelperTagHelper.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.Runtime.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace TagHelpersBuiltInAspNetCore +{ + // You may need to install the Microsoft.AspNetCore.Razor.Runtime package into your project + [HtmlTargetElement("PrettyTagHelper")] + public class PrettyTagHelperTagHelper : TagHelper + { + protected IHtmlGenerator Generator { get; } + + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + + [HtmlAttributeName("replacement-text")] + public string RepacementText { get; set; } + + public PrettyTagHelperTagHelper(IHtmlGenerator generator) + { + Generator = generator; + } + + + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) + { + var childContent = await output.GetChildContentAsync(); + var innerHtml = childContent.GetContent(); + + var str = innerHtml; + + + + var strEncoded = WebUtility.HtmlEncode(str); + + var finalStr = str.Replace(RepacementText, strEncoded); + + + + + + output.Content.SetHtmlContent(finalStr); // www version + } + + //public override void Process(TagHelperContext context, TagHelperOutput output) + //{ + // var innerHtml = output.Content.GetContent(); + // output.Content.SetHtmlContent("---" + innerHtml + "---"); // www version + //} + + // public override void Process(TagHelperContext context, TagHelperOutput output) + // { + // var content = output.Content.GetContent(); + + // //var tagBuilder = Generator.GenerateActionLink( + // // ViewContext, + // // "LinkText", + // // "About", + // // "Home", + // // null, + // // null, + // // null, + // // null, + // // null); + + + // output.Content.SetHtmlContent("abcd"); + + + // //var builder = new TagBuilder("a"); + + // //output.Attributes.Add("data-controller", Controller); + // //output.Attributes.Add("data-action", Action); + + // //if (!string.IsNullOrEmpty(Text)) + // //{ + // // builder.InnerHtml.Append(Text); // INNER HTML IS HERE!!! + // //} + // //builder.AddCssClass("btn btn-link"); + // //output.Content.SetContent(builder); + // //base.Process(context, output); + + // } + + + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Program.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Program.cs new file mode 100644 index 000000000000..a679850fba38 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; + +namespace TagHelpersBuiltInAspNetCore +{ + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Startup.cs b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Startup.cs new file mode 100644 index 000000000000..cf04ef619c4d --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Startup.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace TagHelpersBuiltInAspNetCore +{ + public class Startup + { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + // Add framework services. + services.AddMvc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseBrowserLink(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } + + app.UseStaticFiles(); + + app.UseMvc(routes => + { + // need route and attribute on controller: [Area("Blogs")] + routes.MapRoute(name: "areaRoute", + template: "{area:exists}/{controller=Home}/{action=Index}"); + + // default route for non-areas + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/TagHelpersBuiltInAspNetCore.xproj b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/TagHelpersBuiltInAspNetCore.xproj new file mode 100644 index 000000000000..8853e382cbd9 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/TagHelpersBuiltInAspNetCore.xproj @@ -0,0 +1,23 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 1830b28a-9b83-4220-b59b-9ee27650bff8 + TagHelpersBuiltInAspNetCore + .\obj + .\bin\ + v4.6.1 + + + 2.0 + + + + + + + diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/BuiltInTag/AnchorTagHelper.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/BuiltInTag/AnchorTagHelper.cshtml new file mode 100644 index 000000000000..70e4d8e87597 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/BuiltInTag/AnchorTagHelper.cshtml @@ -0,0 +1,166 @@ +@model dynamic + +@{ + ViewBag.Title = "AnchorTagHelper"; +} + + + + + + + + + + + + +

AnchorTagHelper

+ +@Html.Raw(Html.Encode("Speakers"))

+ + + + + + + + + + + + + @*@Html.Raw("Speakers")*@ + + + + @*@Html.Raw(@Html.Encode("Text")) + + + +

+ %3Ca+asp-action%3D%22AboutBlog%22+asp-controller%3D%22Home%22+asp-area%3D%22Blogs%22%3EText%3C%2Fa%3E*@ + + + @*About Speaker Evals*@ + + + @*Simplest Usage
+ About +

+ + + Simplest Usage (being more explicit)
+ About +

+ + + Simplest Usage (being more explicit)
+ About +

+ + + + Simplest Usage (being more explicit)
+ About +

+ + Simplest Usage (being more explicit)
+ Blogs About +

+ + *@ + + @*Ronald + Speaker 11*@ + + @*SpeakerEvals*@ + + + @*@{ + var dict = + new Dictionary + { + {"speakerId", "11"}, + {"currentYear", "true"} + }; + } + SpeakerEvals*@ diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/About.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/About.cshtml new file mode 100644 index 000000000000..50476d1fbd4c --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewData["Title"] = "About"; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +

Use this area to provide additional information.

diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Contact.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Contact.cshtml new file mode 100644 index 000000000000..15c12c6d1269 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Contact.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"].

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Index.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Index.cshtml new file mode 100644 index 000000000000..3cd243ddaab4 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Home/Index.cshtml @@ -0,0 +1,109 @@ +@{ + ViewData["Title"] = "Home Page"; +} + + + + diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/Error.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/Error.cshtml new file mode 100644 index 000000000000..e514139c454a --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/Error.cshtml @@ -0,0 +1,14 @@ +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/_Layout.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/_Layout.cshtml new file mode 100644 index 000000000000..97297ade79e7 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Shared/_Layout.cshtml @@ -0,0 +1,67 @@ + + + + + + @ViewData["Title"] - TagHelpersBuiltInAspNetCore + + + + + + + + + + + + +
+ @RenderBody() +
+
+

© 2016 - TagHelpersBuiltInAspNetCore

+
+
+ + + + + + + + + + + + + @RenderSection("scripts", required: false) + + diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Detail.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Detail.cshtml new file mode 100644 index 000000000000..8dae850e6cd3 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Detail.cshtml @@ -0,0 +1,7 @@ +@model TagHelpersBuiltInAspNetCore.Controllers.ModelData +@{ + ViewBag.Title = "Speaker Detail"; +} + +

Speaker Detail


+Number: @Model.SpeakerId
\ No newline at end of file diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Evaluations.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Evaluations.cshtml new file mode 100644 index 000000000000..9994dbd3e2ee --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Evaluations.cshtml @@ -0,0 +1,7 @@ +@model dynamic + +@{ + ViewBag.Title = "Evaluations"; +} + +

Evaluations

diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Index.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Index.cshtml new file mode 100644 index 000000000000..b5e3e91042e2 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/Speaker/Index.cshtml @@ -0,0 +1,13 @@ +@model System.Collections.Generic.List + +@{ + ViewBag.Title = "Speakers"; +} + +

Speakers

+ diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewImports.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewImports.cshtml new file mode 100644 index 000000000000..43bc039f6c8f --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using TagHelpersBuiltInAspNetCore +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, TagHelpersBuiltInAspNetCore diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewStart.cshtml b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewStart.cshtml new file mode 100644 index 000000000000..96b5e60389ba --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + //Layout = "_Layout"; +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/appsettings.json b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/appsettings.json new file mode 100644 index 000000000000..fa8ce71a97a3 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bower.json b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bower.json new file mode 100644 index 000000000000..69159b66670a --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bower.json @@ -0,0 +1,10 @@ +{ + "name": "asp.net", + "private": true, + "dependencies": { + "bootstrap": "3.3.6", + "jquery": "2.2.0", + "jquery-validation": "1.14.0", + "jquery-validation-unobtrusive": "3.2.6" + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bundleconfig.json b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bundleconfig.json new file mode 100644 index 000000000000..04754ba7135f --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/bundleconfig.json @@ -0,0 +1,24 @@ +// Configure bundling and minification for the project. +// More info at https://go.microsoft.com/fwlink/?LinkId=808241 +[ + { + "outputFileName": "wwwroot/css/site.min.css", + // An array of relative input file paths. Globbing patterns supported + "inputFiles": [ + "wwwroot/css/site.css" + ] + }, + { + "outputFileName": "wwwroot/js/site.min.js", + "inputFiles": [ + "wwwroot/js/site.js" + ], + // Optionally specify minification options + "minify": { + "enabled": true, + "renameLocals": true + }, + // Optinally generate .map file + "sourceMap": false + } +] diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/project.json b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/project.json new file mode 100644 index 000000000000..dd01a7fa1212 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/project.json @@ -0,0 +1,65 @@ +{ + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0", + "type": "platform" + }, + "Microsoft.AspNetCore.Diagnostics": "1.0.0", + "Microsoft.AspNetCore.Mvc": "1.0.0", + "Microsoft.AspNetCore.Razor.Tools": { + "version": "1.0.0-preview2-final", + "type": "build" + }, + "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", + "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", + "Microsoft.AspNetCore.StaticFiles": "1.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", + "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Logging": "1.0.0", + "Microsoft.Extensions.Logging.Console": "1.0.0", + "Microsoft.Extensions.Logging.Debug": "1.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", + "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0" + }, + + "tools": { + "BundlerMinifier.Core": "2.0.238", + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" + }, + + "frameworks": { + "netcoreapp1.0": { + "imports": [ + "dotnet5.6", + "portable-net45+win8" + ] + } + }, + + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true + }, + + "runtimeOptions": { + "configProperties": { + "System.GC.Server": true + } + }, + + "publishOptions": { + "include": [ + "wwwroot", + "Views", + "Areas/**/Views", + "appsettings.json", + "web.config" + ] + }, + + "scripts": { + "prepublish": [ "bower install", "dotnet bundle" ], + "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] + } +} diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/web.config b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/web.config new file mode 100644 index 000000000000..dc0514fca5eb --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/web.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + From ca0ff6bd829b1778c61f3469e9c10227912fd7a1 Mon Sep 17 00:00:00 2001 From: pkellner Date: Tue, 24 Jan 2017 08:55:04 -0800 Subject: [PATCH 2/8] Updated AnchorTagHelper to not include startup.cs and image of VS solution. Added new documentation for ImageTagHelper.md --- aspnetcore/mvc/views/tag-helpers/builtin.md | 2 +- .../builtin/resources/AnchorTagHelper.md | 16 +------- .../builtin/resources/ImageTagHelper.md | 41 +++++++++++++++++++ 3 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md diff --git a/aspnetcore/mvc/views/tag-helpers/builtin.md b/aspnetcore/mvc/views/tag-helpers/builtin.md index 9097c27c41bb..436b515ad7d5 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin.md @@ -21,7 +21,7 @@ Microsoft has included 17 Tag Helpers that can be immediately used in .net Core [comment]: **[FormTagTagHelper](builtin/resources/FormTagHelper.md)** -[comment]: **[ImageTagHelper](builtin/resources/ImageTagHelper.md)** +**[ImageTagHelper](builtin/resources/ImageTagHelper.md)** [comment]: **[InputTagHelper](builtin/resources/InputTagHelper.md)** diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md index 395b5a585716..41808e1d0e99 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md @@ -8,23 +8,9 @@ By [Peter Kellner](http://peterkellner.net) The ```AnchorTagHelper``` enhances the html anchor (``) tag. A new set of attributes are defined that work with the anchor tag. The link generated (on the href tag) is based on a combination of these new attributes that work together to form the final redirect URL. That URL can include an optional protocol such as https. -For reference, the following ASP.NET ```startup.cs``` and ```SpeakerController.cs``` are defined as you would expect in a default Visual Studio .Net Core Web Project. +For reference, the following ASP.NET ```SpeakerController.cs``` is defined as you would expect in a default Visual Studio .Net Core Web Project. -![](../_static/ProjectControllers.png) -**Startup.cs** -``` -// This method gets called by the runtime. -// Use this method to configure the -// HTTP request pipeline. -public void Configure(IApplicationBuilder app, - IHostingEnvironment env, - ILoggerFactory loggerFactory) -{ - app.UseMvcWithDefaultRoute(); - //... -} -```
**SpeakerController.cs** diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md new file mode 100644 index 000000000000..eb9269157bbd --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md @@ -0,0 +1,41 @@ +[Back To Built In Tag Helpers List](../../builtin.md) + + +# ImageTagHelper + +By [Peter Kellner](http://peterkellner.net) + + +The ```ImageTagHelper``` enhances the html img (``) tag. It requires a src tag be present as well as the boolean attribute ```asp-append-version``` be included. + +If the image source (```src```) is a static file on the host web server, a unique cache bursting string is appended as a parameter to the image source. This insures that if the file on the host web server changes, a unique request url will be generated that includes the updated request parameter. The cache bursting string is a unique value representing the sha512 value of the static image file. + +If the image source (```src```) is not a static file (possibly a remote url or the file does not exist) then no unique parameter will be generated. + +
+These attributes are defined as follows: + +## asp-append-version + + + +```asp-append-version``` is the only attribute available for the Image Tag Helper. When specified along with a src attribute, this tag helper is invoked. + +An example of a valid ```img``` tag helper is as follows: + +`````` + +If the static file exists on the web server, typically in the directory ```..wwwroot/images/asplogo.png``` the generated html will be + +`````` + +The value assigned to the parameter v is the hash value of the file on disk generated using the .net library method ```CryptographyAlgorithms.CreateSHA256().ComputeHash()```. If the web server is unable to get read access to the static file referenced (in our case ```..wwwroot/images/asplogo.png```) no v parameters is added to the src attribute and the original src attribute is used unchanged. + +## src + +The ```src``` attribute is required on the ```img``` html element. For the ```ImageTagHelper``` to be activated, this attribute must be included. + +> [!NOTE] +> The Image Tag Helper uses the Cache on the local web server to store the calculated sha512 of a given file. If the file is requested again the sha512 does not need to be recalculated. The Cache is invalidated by a file watcher that is attached to the file when the file's sha512 is calculated. + + From 410b43ba9212a75873c00955981d8e4b9505af5d Mon Sep 17 00:00:00 2001 From: pkellner Date: Wed, 25 Jan 2017 12:20:35 -0800 Subject: [PATCH 3/8] Started Working on CacheTagHelper --- aspnetcore/mvc/views/tag-helpers/builtin.md | 2 +- .../builtin/resources/AnchorTagHelper.md | 33 ++++- .../builtin/resources/CacheTagHelper.md | 131 ++++++++++++++++++ 3 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md diff --git a/aspnetcore/mvc/views/tag-helpers/builtin.md b/aspnetcore/mvc/views/tag-helpers/builtin.md index 436b515ad7d5..e015bab8ac41 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin.md @@ -11,7 +11,7 @@ Microsoft has included 17 Tag Helpers that can be immediately used in .net Core **[AnchorTagHelper](builtin/resources/AnchorTagHelper.md)** -[comment]: **[CacheTagHelper](builtin/resources/AnchorTagHelper.md)** +**[CacheTagHelper](builtin/resources/CacheTagHelper.md)** [comment]: **[DistributedTagHelper](builtin/resources/AnchorTagHelper.md)** diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md index 41808e1d0e99..22189656f267 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md @@ -97,10 +97,32 @@ Hash tags are useful when doing client side applications. They can be used for e ## asp-area -```asp-area``` allows for a razor view area to be associated with the hyperlink URL. That is, if you have a project setup in a similar fashion to the project pictured below, the link generated will include as its first segment the area you mention. +```asp-area``` sets the area name that ASP.NET core will use to set the appropriate route with. Below are examples of how the area attribute causes a remapping of routes. That is, by setting ```asp-area``` to Blogs will invoke the Areas functionality such that the directory Areas/Blogs will prefix the associated controllers and views for this anchor tag. -![](../_static/ProjectControllersArea.png) +* Project name + * wwwroot + + * Areas + + * Blogs + + * Controllers + + * HomeController.cs + + * Views + + * Home + + * Index.cshtml + + * AboutBlog.cshtml + + * Controllers + + + Specifying an area tag that is valid, such as ```area="Blogs"``` when referencing the ```AboutBlog.cshtml``` file will look like the following using the ```AnchorTagHelper```. ``` @@ -117,7 +139,6 @@ The generated HTML will include the areas segment and will be as follows: > For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. - ## asp-protocol The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. @@ -130,4 +151,10 @@ and will generate HTML as follows. (of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). +## See Also + +* [Areas](../../../../controllers/areas.md) + + + diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md new file mode 100644 index 000000000000..7455bbc28bd7 --- /dev/null +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -0,0 +1,131 @@ +[Back To Built In Tag Helpers List](../../builtin.md) + + +# CacheTagHelper + +By [Peter Kellner](http://peterkellner.net) + + +The ```CacheTagHelper``` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. + + + +
+These attributes are defined as follows: + +## asp-controller + +```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details you would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely not be what you expect. + +## asp-action + +```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to ```asp-action=Detail```. You should always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely not be what you expect. + +## asp-route- + +```asp-route-``` is basically a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: + +```Speaker 11``` + +the href generated will be + +```Speaker 11``` + +This is because a route was found that matched a single parameter "id" in the ```SpeakerController``` method ```Detail```. If there was no parameter match, say for example you created the tag helper + +```Ronald``` + +you would get generated the html + +```Ronald``` + +This is because there was no route found that matched a controller that had a method named ```Detail``` with one string parameter titled ```name```. + +## asp-route + +```asp-route``` provides a way to create a URL that links directly to a named route. Using routing attributes, you can name your routes as shown in the Evaluations method above of the ```SpeakerController```. ```Name = "speakerevals"``` tells the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action``` to avoid a route conflict. + +## asp-all-route-data + +```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As the example below shows, you can create an inline dictionary on your razor page and then create the ```AnchorTagHelper``` right after that. You could of course pass in the dictionary with your model or as your model. That avoids having extra c# code on your razor page and gives you better control of the data passed to your view. + +``` +@{ + var dict = + new Dictionary + { + {"speakerId", "11"}, + {"currentYear", "true"} + }; +} +SpeakerEvals +``` + +The code that this generates looks as follows: + +``` +http://localhost/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true +``` + +When the link is clicked, this will call the controller method ```EvaluationsCurrent``` because that controller has two string parameters that match what has been created from the ``` +asp-all-route-data``` +dictionary. + +## asp-fragment + +```asp-fragment``` appends after a hash (```#```) tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag + +``` +About Speaker Evals +``` +The generated URL will be + +``` +http://localhost/Speaker/Evaluations#SpeakerEvaluations +``` +Hash tags are useful when doing client side applications. They can be used for easy marking and searching in JavaScript for example. + + +## asp-area + +```asp-area``` allows for a razor view area to be associated with the hyperlink URL. That is, if you have a project setup in a similar fashion to the project pictured below, the link generated will include as its first segment the area you mention. + +![](../_static/ProjectControllersArea.png) + +Specifying an area tag that is valid, such as ```area="Blogs"``` when referencing the ```AboutBlog.cshtml``` file will look like the following using the ```AnchorTagHelper```. + +``` +Blogs About +``` + +The generated HTML will include the areas segment and will be as follows: + +``` +Blogs About +``` + +> [!TIP] +> For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. + + + +## asp-protocol + +The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. + +```About``` + +and will generate HTML as follows. + +```About``` + +(of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). + + + + +REFERENCES: + +https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory From 101ce59011223a65b769e4ef0f7858d5b75c584e Mon Sep 17 00:00:00 2001 From: pkellner Date: Thu, 26 Jan 2017 11:18:35 -0800 Subject: [PATCH 4/8] Working on CacheTagHelper, found default of 20 minutes in razor init --- .../views/tag-helpers/builtin/resources/CacheTagHelper.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md index 7455bbc28bd7..9b21f03d30b7 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -8,7 +8,13 @@ By [Peter Kellner](http://peterkellner.net) The ```CacheTagHelper``` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. +A simple example that shows the ```CacheTagHelper``` in action set's the current time inside the HTML Element Cache. The Razor View Engine sets the default cache value to be 20 minutes so that there is no need to set any attributes if 20 minutes is a reasonable cache value. +Here is an example of the code you would include in your cshtml page to achieve caching the current date and time for 20 minutes. + +```@DateTime.Now``` + +You can get much more control of the cache duration by setting any of the following attributes.
These attributes are defined as follows: From c3f1c52aa5947206814f36a3c595dd3d1345d502 Mon Sep 17 00:00:00 2001 From: pkellner Date: Thu, 26 Jan 2017 15:43:59 -0800 Subject: [PATCH 5/8] Working on CacheTagHelper --- .../builtin/resources/CacheTagHelper.md | 126 +++--------------- 1 file changed, 21 insertions(+), 105 deletions(-) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md index 9b21f03d30b7..d1c78744296f 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -8,130 +8,46 @@ By [Peter Kellner](http://peterkellner.net) The ```CacheTagHelper``` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. -A simple example that shows the ```CacheTagHelper``` in action set's the current time inside the HTML Element Cache. The Razor View Engine sets the default cache value to be 20 minutes so that there is no need to set any attributes if 20 minutes is a reasonable cache value. +A simple example that shows the ```CacheTagHelper``` in action set's the current time in the content area of the Cache Tag Helper. The Razor View Engine sets the default of ```expires-after``` to be 20 minutes (this is the default if you specify no attributes). -Here is an example of the code you would include in your cshtml page to achieve caching the current date and time for 20 minutes. +Here is an example of the code you would include in your cshtml page to achieve the 20 minute cache of the current system date and time. ```@DateTime.Now``` You can get much more control of the cache duration by setting any of the following attributes.
-These attributes are defined as follows: +All attributes are defined as follows: -## asp-controller +## vary-by +x -```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details you would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely not be what you expect. +## vary-by-header +x -## asp-action +##vary-by-query +x -```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to ```asp-action=Detail```. You should always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely not be what you expect. +##vary-by-route -## asp-route- +##vary-by-cookie -```asp-route-``` is basically a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: +##vary-by-user -```Speaker 11``` +##expires-on -the href generated will be - -```Speaker 11``` - -This is because a route was found that matched a single parameter "id" in the ```SpeakerController``` method ```Detail```. If there was no parameter match, say for example you created the tag helper - -```Ronald``` - -you would get generated the html - -```Ronald``` - -This is because there was no route found that matched a controller that had a method named ```Detail``` with one string parameter titled ```name```. - -## asp-route - -```asp-route``` provides a way to create a URL that links directly to a named route. Using routing attributes, you can name your routes as shown in the Evaluations method above of the ```SpeakerController```. ```Name = "speakerevals"``` tells the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action``` to avoid a route conflict. - -## asp-all-route-data - -```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As the example below shows, you can create an inline dictionary on your razor page and then create the ```AnchorTagHelper``` right after that. You could of course pass in the dictionary with your model or as your model. That avoids having extra c# code on your razor page and gives you better control of the data passed to your view. - -``` -@{ - var dict = - new Dictionary - { - {"speakerId", "11"}, - {"currentYear", "true"} - }; -} -SpeakerEvals -``` - -The code that this generates looks as follows: - -``` -http://localhost/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true -``` - -When the link is clicked, this will call the controller method ```EvaluationsCurrent``` because that controller has two string parameters that match what has been created from the ``` -asp-all-route-data``` -dictionary. - -## asp-fragment - -```asp-fragment``` appends after a hash (```#```) tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag - -``` -About Speaker Evals -``` -The generated URL will be - -``` -http://localhost/Speaker/Evaluations#SpeakerEvaluations -``` -Hash tags are useful when doing client side applications. They can be used for easy marking and searching in JavaScript for example. - - -## asp-area - -```asp-area``` allows for a razor view area to be associated with the hyperlink URL. That is, if you have a project setup in a similar fashion to the project pictured below, the link generated will include as its first segment the area you mention. - -![](../_static/ProjectControllersArea.png) - -Specifying an area tag that is valid, such as ```area="Blogs"``` when referencing the ```AboutBlog.cshtml``` file will look like the following using the ```AnchorTagHelper```. - -``` -Blogs About -``` - -The generated HTML will include the areas segment and will be as follows: - -``` -Blogs About -``` - -> [!TIP] -> For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. - - - -## asp-protocol - -The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. - -```About``` - -and will generate HTML as follows. - -```About``` - -(of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). +##expires-sliding +##enabled +>[!NOTE] +>The ```CacheTagHelper``` is dependent on the built in Memory Cache service being included in the ```startup.cs``` ConfigureServices method. Adding this service is not necessary because the built in Tag Helper extensions take care of this in the AddMvc() method call. REFERENCES: +AFTER CHECKING BELOW REFERENCE REMOVE THESE TWO LINES https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory + + +* [In memory caching](../../../../performance/caching/memory.md) From fb05a48cfc2fcd6967d64a0dece0d3f79edd0c1a Mon Sep 17 00:00:00 2001 From: pkellner Date: Mon, 30 Jan 2017 10:04:44 -0800 Subject: [PATCH 6/8] fixed link to cache --- .../mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md index d1c78744296f..19e183886ec8 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -50,4 +50,4 @@ AFTER CHECKING BELOW REFERENCE REMOVE THESE TWO LINES https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory -* [In memory caching](../../../../performance/caching/memory.md) +* [In memory caching](../../../../../performance/caching/memory.md) From 2aad68aa7a6100b5b528dbe309bede1c7f7812c9 Mon Sep 17 00:00:00 2001 From: pkellner Date: Wed, 1 Feb 2017 10:11:41 -0800 Subject: [PATCH 7/8] Finished Updates to AnchorTagHelper and new Tag Helpers CacheTagHelper and ImageTagHelper. --- .../builtin/resources/AnchorTagHelper.md | 38 ++- .../builtin/resources/CacheTagHelper.md | 275 ++++++++++++++++-- .../builtin/resources/ImageTagHelper.md | 33 ++- 3 files changed, 296 insertions(+), 50 deletions(-) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md index 22189656f267..659d0f92f49f 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md @@ -17,18 +17,24 @@ For reference, the following ASP.NET ```SpeakerController.cs``` is defined as yo [!code-csharp[SpeakerController](../sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs)] -
-These attributes are defined as follows: -## asp-controller +## The attributes are defined as follows + +- - - + +### asp-controller ```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details you would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely not be what you expect. -## asp-action +- - - + +### asp-action ```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to ```asp-action=Detail```. You should always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely not be what you expect. -## asp-route- +- - - + +### asp-route- ```asp-route-``` is basically a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: @@ -48,11 +54,15 @@ you would get generated the html This is because there was no route found that matched a controller that had a method named ```Detail``` with one string parameter titled ```name```. -## asp-route +- - - + +### asp-route ```asp-route``` provides a way to create a URL that links directly to a named route. Using routing attributes, you can name your routes as shown in the Evaluations method above of the ```SpeakerController```. ```Name = "speakerevals"``` tells the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action``` to avoid a route conflict. -## asp-all-route-data +- - - + +### asp-all-route-data ```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As the example below shows, you can create an inline dictionary on your razor page and then create the ```AnchorTagHelper``` right after that. You could of course pass in the dictionary with your model or as your model. That avoids having extra c# code on your razor page and gives you better control of the data passed to your view. @@ -79,7 +89,9 @@ When the link is clicked, this will call the controller method ```EvaluationsCur asp-all-route-data``` dictionary. -## asp-fragment +- - - + +### asp-fragment ```asp-fragment``` appends after a hash (```#```) tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag @@ -94,8 +106,9 @@ http://localhost/Speaker/Evaluations#SpeakerEvaluations ``` Hash tags are useful when doing client side applications. They can be used for easy marking and searching in JavaScript for example. +- - - -## asp-area +### asp-area ```asp-area``` sets the area name that ASP.NET core will use to set the appropriate route with. Below are examples of how the area attribute causes a remapping of routes. That is, by setting ```asp-area``` to Blogs will invoke the Areas functionality such that the directory Areas/Blogs will prefix the associated controllers and views for this anchor tag. @@ -138,8 +151,9 @@ The generated HTML will include the areas segment and will be as follows: > [!TIP] > For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. +- - - -## asp-protocol +### asp-protocol The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. @@ -151,7 +165,9 @@ and will generate HTML as follows. (of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). -## See Also +- - - + +## Additional Resources * [Areas](../../../../controllers/areas.md) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md index 19e183886ec8..ea17f78cc428 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -6,48 +6,273 @@ By [Peter Kellner](http://peterkellner.net) -The ```CacheTagHelper``` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. +The `CacheTagHelper` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. -A simple example that shows the ```CacheTagHelper``` in action set's the current time in the content area of the Cache Tag Helper. The Razor View Engine sets the default of ```expires-after``` to be 20 minutes (this is the default if you specify no attributes). +A simple example that shows the `CacheTagHelper` in action sets the current time in the content area of the Cache Tag Helper. The Razor View Engine sets the default of `expires-after` to be 20 minutes (this is the default if you specify no addional attributes). -Here is an example of the code you would include in your cshtml page to achieve the 20 minute cache of the current system date and time. +Here is an example of the code you would include in your `cshtml` page to achieve the default cache behavior described above. -```@DateTime.Now``` +```HTML +@DateTime.Now +``` -You can get much more control of the cache duration by setting any of the following attributes. +If you repeatedly refresh the page that contains the`Cache`tag above, the first time the current`DateTime`will be shown. Then, repeated refreshes of the page will continue to show the first`DateTime` shown until the cache expires (which is likely 20 minutes in this example). -
-All attributes are defined as follows: +You can achieve more control of the cache duration of the content by setting any of the following attributes. -## vary-by -x -## vary-by-header -x -##vary-by-query -x +## The attributes are defined as follows -##vary-by-route +- - - -##vary-by-cookie +### enabled -##vary-by-user -##expires-on +| Attribute Type | Valid Values | +|---------------- |---------------- | +| boolean | "true","false" | -##expires-sliding -##enabled +The attribute`enabled` determines whether any caching is performed of the content inside the `Cache` tag helper. The default is `true` which means that all other attributes will be active. It also means that if this attribute is left out, its default value will be set to true. If set to `false` then regardless of what other attributes are specified, this cache tag will have no caching effect on the rendered output. +Usage Example: ->[!NOTE] ->The ```CacheTagHelper``` is dependent on the built in Memory Cache service being included in the ```startup.cs``` ConfigureServices method. Adding this service is not necessary because the built in Tag Helper extensions take care of this in the AddMvc() method call. +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### expires-on + +| Attribute Type | Example Value | +|---------------- |---------------- | +| DateTimeOffset | "@new DateTime(2025,1,29,17,02,0)" | + + +The attribute `expires-on` sets a deterministic expiration date for caching the content of the `Cache` tag helper when the tag helper is first rendered. The example below will cache the contents of the `Cache` tag helper until 5:02 PM on January 29, 2025. + +Usage Example: + +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### expires-after + +| Attribute Type | Example Value | +|---------------- |---------------- | +| TimeSpan | "@TimeSpan.FromSeconds(5)" | + + +The attribute `expires-after` sets a specific amount of time from the current `DateTime` that the contents of the `Cache` tag helper will be kept. This value is set when the `Cache` tag helper is first rendered. The example below will likely cache the contents of the `Cache` tag for 5 seconds. + +Usage Example: + +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### expires-sliding + +| Attribute Type | Example Value | +|---------------- |---------------- | +| TimeSpan | "@TimeSpan.FromSeconds(5)" | + + +The attribute `expires-after` sets a specific amount of time from the current `DateTime` that the contents of the `Cache` tag helper will be kept in cache. This value is set when the `Cache` tag helper is first rendered. + +Usage Example: + +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### vary-by-header + +| Attribute Type | Example Values | +|---------------- |---------------- | +| String | "User-Agent" | +| | "User-Agent,content-encoding" | + +The attribute `vary-by-header` allows for either a single header or a comma separated list of headers to be identified that will cause a cache refresh when changed. That is, when any header in the `vary-by-header` list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the header value `User-Agent` which will effectively cache the content for every different `User-Agent` presented to the web server. + +Usage Example: + + + Current Time Inside Cache Tag Helper: @DateTime.Now + + +- - - + +### vary-by-query + +| Attribute Type | Example Values | +|---------------- |---------------- | +| String | "Make" | +| | "Make,Model" | + +The attribute `vary-by-query` allows for either a single query parameter or a comma separated list of query parameters to be identified that will cause a cache refresh when the passed in query value or values change. That is, when any query parameter in the `vary-by-query` list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the values of Make and Model and when either or both change, the content of the `Cache` tag helper will be rendered again and the cache is reset to that new value. + +Usage Example: + + + + Current Time Inside Cache Tag Helper: @DateTime.Now + + +- - - + +### vary-by-route + +| Attribute Type | Example Values | +|---------------- |---------------- | +| String | "Make" | +| | "Make,Model" | + +The attribute `vary-by-route` allows for either a single route parameter or a comma separated list of route parameters to be identified that will cause a cache refresh when the passed in route value or values change. That is, when any request causes one or more of the route parameters to change, the content of the `Cache` tag helper will be updated. The example below looks at the values of Make and Model. When either or both change, the content of the `Cache` tag helper will be rendered again and the cache is reset. + +Usage Example: -REFERENCES: +Startup.cs -AFTER CHECKING BELOW REFERENCE REMOVE THESE TWO LINES -https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory +```C# +routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{Make?}/{Model?}"); +``` + + +Index.cshtml + +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### vary-by-cookie + +| Attribute Type | Example Values | +|---------------- |---------------- | +| String | ".AspNetCore.Identity.Application" | +| | ".AspNetCore.Identity.Application,HairColor" | + +The attribute `vary-by-cookie` allows for either a single request cookie or a comma separated list of request cookies to be identified that will cause a cache refresh when the current request's cookie value or values change. That is, when any cookie parameter in the vary-by-cookie list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the cookie associated with asp.net Identity. When a user is authenticated causing the request cookie to be set, The content of the `Cache` tag helper will be rendered again and the cache is reset. + +Usage Example: + + + Current Time Inside Cache Tag Helper: @DateTime.Now + + +- - - + +### vary-by-user + +| Attribute Type | Example Values | +|---------------- |---------------- | +| Boolean | "true" | +| | "false" | + +The attribute `vary-by-user` allows for the logged in user (or Context Principal) changes to cause a cache refresh. That is, when the authenticated user changes, the content of the `Cache` tag helper will be updated. The current user is also known as the Request Context Principal and can be viewed on a razor cshtml page by referencing `@User.Identity.Name`. + + +The example below looks at the current logged in user. When a different user is found, The content of the `Cache` tag helper will be rendered again and the cache is reset. + +Usage Example: + + + Current Time Inside Cache Tag Helper: @DateTime.Now + + +> [!NOTE] +> using the attribute `vary-by-user` will maintain the contents in cache through a log in and log out cycle. When using `vary-by-cookie` which references the `.AspNetCore.Identity.Application` as shown above, a log in and log out action will invalidate the cache for the same authenticated user because a new cookie value will be generated. Also, if no user is authenticated (or logged in), that state is considered a valid cache state which means that no logged in user is one cache state and the contents will be maintained for that condition as well. + +- - - + +### vary-by + +| Attribute Type | Example Values | +|---------------- |---------------- | +| String | "@Model" | + + +The attribute `vary-by` allows for customization of what data gets cached. When the string value changes of what is assigned to the attribute 'vary-by', the content of the `Cache` tag helper will be updated. Often a model value or combination of model values are assigned to this attribute. Otherwise, the value will never change and the cache will be updated only by the inclusion of other attributes in the `Cache` tag helper. + +The example below assumes the controller method rendering the view sums the integer value of the two route parameters, myParam1 and myParam2, and returns that as the single model property. When this sum changes, the content of the `Cache` tag helper will be rendered again and the cache is reset. + +Usage Example: + + +Controller + +```C# +public IActionResult Index + (string myParam1,string myParam2,string myParam3) +{ + int num1; + int num2; + int.TryParse(myParam1, out num1); + int.TryParse(myParam2, out num2); + return View(viewName, num1 + num2); +} +``` + +Index.cshtml + +```HTML + + Current Time Inside Cache Tag Helper: @DateTime.Now + +``` + +- - - + +### priority + +| Attribute Type | Example Values | +|---------------- |---------------- | +| CacheItemPriority | "High" | +| | "Low" | +| | "NeverRemove" | +| | "Normal" | + +The attribute `priority` is used to give guidance to the built in cache provider on what priority to assign to the cache contents stored. That is, there is no guarantee of the cache not being invalidated prior to the expected expiration. If for example you set one `Cache` tag helper to have its priority `High` and another to `Low`, it is likely that if the web server experiences memory pressure and needs to evict one of your cached content values, it will evict the `Low` priority first. + +Usage Example: + + + Current Time Inside Cache Tag Helper: @DateTime.Now + + +> [!WARNING] +> using the `priority` attribute does not guarantee any specific level of cache retention. It is simply a suggestion to the Cache Provider. To be extra clear, setting this attribute to `NeverRemove` does not guarantee that the cache will not be evicted. More details can be found in the additional resources listed below. + +- - - + + +>[!NOTE] +>The ```CacheTagHelper``` is dependent on the built in Memory Cache service being included in the ```startup.cs``` ConfigureServices method. Adding this service is not necessary because the built in Tag Helper extensions take care of this in the AddMvc() method call. +## Additional Resources -* [In memory caching](../../../../../performance/caching/memory.md) +* [In Memory Caching](../../../../../performance/caching/memory.md) +* [ASP.NET Core Identity (Authentication)](../../../../../security/authentication/identity.md) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md index eb9269157bbd..7aa1e08f2d33 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md @@ -6,36 +6,41 @@ By [Peter Kellner](http://peterkellner.net) -The ```ImageTagHelper``` enhances the html img (``) tag. It requires a src tag be present as well as the boolean attribute ```asp-append-version``` be included. +The `ImageTagHelper` enhances the html `img` (``````) tag. It requires a `src` tag be present as well as the `boolean` attribute `asp-append-version` be included. -If the image source (```src```) is a static file on the host web server, a unique cache bursting string is appended as a parameter to the image source. This insures that if the file on the host web server changes, a unique request url will be generated that includes the updated request parameter. The cache bursting string is a unique value representing the sha512 value of the static image file. +If the image source (```src```) is a static file on the host web server, a unique cache bursting string is appended as a parameter to the image source. This insures that if the file on the host web server changes, a unique request url will be generated that includes the updated request parameter. The cache bursting string is a unique value representing the `Sha512` value of the static image file. -If the image source (```src```) is not a static file (possibly a remote url or the file does not exist) then no unique parameter will be generated. +If the image source (```src```) is not a static file (possibly a remote url or the file does not exist on the server) then no unique parameter will be generated and the `img` tag will be generated with no additional cache bursting parameter. -
-These attributes are defined as follows: +## The attributes are defined as follows: -## asp-append-version +- - - +### asp-append-version +`asp-append-version` is the only attribute available for the Image Tag Helper. When specified along with a `src` attribute, this `Image` tag helper is invoked. -```asp-append-version``` is the only attribute available for the Image Tag Helper. When specified along with a src attribute, this tag helper is invoked. - -An example of a valid ```img``` tag helper is as follows: +An example of a valid `img` tag helper is as follows `````` -If the static file exists on the web server, typically in the directory ```..wwwroot/images/asplogo.png``` the generated html will be +If the static file exists on the web server, typically in the directory `..wwwroot/images/asplogo.png` the generated html will be `````` -The value assigned to the parameter v is the hash value of the file on disk generated using the .net library method ```CryptographyAlgorithms.CreateSHA256().ComputeHash()```. If the web server is unable to get read access to the static file referenced (in our case ```..wwwroot/images/asplogo.png```) no v parameters is added to the src attribute and the original src attribute is used unchanged. +The value assigned to the parameter `v` is the hash value of the file on disk generated using the .net library method ```CryptographyAlgorithms.CreateSHA256().ComputeHash()```. If the web server is unable to get read access to the static file referenced (in our case ```..wwwroot/images/asplogo.png```) no v parameters is added to the src attribute and the original src attribute used is unchanged. + +- - - -## src +### src -The ```src``` attribute is required on the ```img``` html element. For the ```ImageTagHelper``` to be activated, this attribute must be included. +The `src` attribute is required on the `img` html element. For the `ImageTagHelper` to be activated, this `src` attribute must be included as one of the tag helper attributes. > [!NOTE] -> The Image Tag Helper uses the Cache on the local web server to store the calculated sha512 of a given file. If the file is requested again the sha512 does not need to be recalculated. The Cache is invalidated by a file watcher that is attached to the file when the file's sha512 is calculated. +> The Image Tag Helper uses the `Cache` provider on the local web server to store the calculated `Sha512` of a given file. If the file is requested again the `Sha512` does not need to be recalculated. The Cache is invalidated by a file watcher that is attached to the file when the file's `Sha512` is calculated. + +## Additional Resources + +* [In Memory Caching](../../../../../performance/caching/memory.md) From dc87a81a892c713c18b204e3440387a153768349 Mon Sep 17 00:00:00 2001 From: pkellner Date: Tue, 7 Feb 2017 16:52:10 -0800 Subject: [PATCH 8/8] Went through all @GuardRex edits and made my corrections to all 3 tag helpers in progress. Anchor, Image and Cache. --- aspnetcore/mvc/views/tag-helpers/builtin.md | 14 +- .../builtin/resources/AnchorTagHelper.md | 81 +++++------ .../builtin/resources/CacheTagHelper.md | 132 ++++++++++-------- .../builtin/resources/ImageTagHelper.md | 34 +++-- 4 files changed, 138 insertions(+), 123 deletions(-) diff --git a/aspnetcore/mvc/views/tag-helpers/builtin.md b/aspnetcore/mvc/views/tag-helpers/builtin.md index e015bab8ac41..1a63ff8061e6 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin.md @@ -2,16 +2,16 @@ By [Peter Kellner](http://peterkellner.net) -Microsoft has included 17 Tag Helpers that can be immediately used in .net Core web projects. These Tag Helpers are complete and production quality and are recommended to be used in projects where appropriate. In this section we will outline all the built in Tag Helpers along with a sample of each tag helper in use. +Microsoft has included multiple Tag Helpers that can be immediately used in .net Core web projects. These Tag Helpers are complete and production quality and are recommended to be used in projects where appropriate. In this section we will outline all the built in Tag Helpers along with a sample of each tag helper in use. > [!NOTE] > There are other Tag Helpers built in that are not discussed as they are used internally in the Razor view engine. This includes a tag helper for the ~ character which expands to the root path of the web site (among others). ## Built in ASP.NET Core Tag Helpers -**[AnchorTagHelper](builtin/resources/AnchorTagHelper.md)** +**[Anchor Tag Helper](builtin/resources/AnchorTagHelper.md)** -**[CacheTagHelper](builtin/resources/CacheTagHelper.md)** +**[Cache Tag Helper](builtin/resources/CacheTagHelper.md)** [comment]: **[DistributedTagHelper](builtin/resources/AnchorTagHelper.md)** @@ -21,7 +21,7 @@ Microsoft has included 17 Tag Helpers that can be immediately used in .net Core [comment]: **[FormTagTagHelper](builtin/resources/FormTagHelper.md)** -**[ImageTagHelper](builtin/resources/ImageTagHelper.md)** +**[Image Tag Helper](builtin/resources/ImageTagHelper.md)** [comment]: **[InputTagHelper](builtin/resources/InputTagHelper.md)** @@ -39,9 +39,9 @@ Microsoft has included 17 Tag Helpers that can be immediately used in .net Core [comment]: **[ValidationMessageTagHelper](builtin/resources/ValidationMessageTagHelper.md)** -[comment]: **[ValidationSummaryHelper](builtin/resources/ValidationSummaryTagHelper.md)** - -
+[comment]: **[ValidationSummaryTagHelper](builtin/resources/ValidationSummaryTagHelper.md)** + + ## Additional Resources diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md index 659d0f92f49f..679e22edcb95 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/AnchorTagHelper.md @@ -1,16 +1,14 @@ [Back To Built In Tag Helpers List](../../builtin.md) -# AnchorTagHelper +# Anchor Tag Helper By [Peter Kellner](http://peterkellner.net) -The ```AnchorTagHelper``` enhances the html anchor (``) tag. A new set of attributes are defined that work with the anchor tag. The link generated (on the href tag) is based on a combination of these new attributes that work together to form the final redirect URL. That URL can include an optional protocol such as https. - -For reference, the following ASP.NET ```SpeakerController.cs``` is defined as you would expect in a default Visual Studio .Net Core Web Project. - +The Anchor Tag Helper enhances the html anchor (``) tag. A new set of attributes are defined that work with the anchor tag. The link generated (on the `href` tag) is based on a combination of these new attributes that work together to form the final URL. That URL can include an optional protocol such as https. +The speaker controller used in attribute definitions below is shown here.
**SpeakerController.cs** @@ -18,53 +16,57 @@ For reference, the following ASP.NET ```SpeakerController.cs``` is defined as yo [!code-csharp[SpeakerController](../sample/TagHelpersBuiltInAspNetCore/src/TagHelpersBuiltInAspNetCore/Controllers/SpeakerController.cs)] -## The attributes are defined as follows +## Anchor Tag Helper Attributes - - - ### asp-controller -```asp-controller``` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. In our case, to get to a list of all speakers or speaker details you would specify ```asp-controller="Speaker"```. If you only specify ```asp-controller``` and no ```asp-action``` the URL will generate without an error but will likely not be what you expect. +`asp-controller` is used to associate which controller will be used to generate the final URL. The only valid choices are controllers that exist in the current project. To get to a list of all speakers specifying `asp-controller="Speaker"` is required. If only the `asp-controller` and no `asp-action` is specified, the default asp-action will be the name of the the controller method calling this view page. - - - - + ### asp-action -```asp-action``` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to ```asp-action=Detail```. You should always set ```asp-controller``` when specifying ```asp-action```. If no ```asp-action``` is specified then a URL will generate without an error but will likely not be what you expect. +`asp-action` is the name of the method in the controller that will be included in the final URL. That is, in the example, if the route to the Speaker Detail page is wanted, then the attribute should be set to `asp-action=Detail`. You should always set `asp-controller` when specifying `asp-action`. If no `asp-action` is specified then the default `asp-controller` will be the current executing controller. - - - + +### asp-route-{value} -### asp-route- - -```asp-route-``` is basically a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if you create a tag as follows: +`asp-route-` is a wild card route prefix. Any value you put after the trailing dash will be interpreted as the parameter to pass into the route. For example, if a tag is created as follows: -```Speaker 11``` +`Speaker 11` -the href generated will be +the `href` generated will be -```Speaker 11``` +`Speaker 11` This is because a route was found that matched a single parameter "id" in the ```SpeakerController``` method ```Detail```. If there was no parameter match, say for example you created the tag helper -```Ronald``` +`Ronald` you would get generated the html -```Ronald``` +`Ronald` -This is because there was no route found that matched a controller that had a method named ```Detail``` with one string parameter titled ```name```. +This is because there was no route found that matched a controller that had a method named `Detail` with one string parameter titled `name`. - - - ### asp-route -```asp-route``` provides a way to create a URL that links directly to a named route. Using routing attributes, you can name your routes as shown in the Evaluations method above of the ```SpeakerController```. ```Name = "speakerevals"``` tells the AnchorTagHelper to generate a route directly to that controller method using the URL ```/Speaker/Evaluations```. If ```asp-controller``` or ```asp-action``` is specified in addition to ```asp-route``` then the route generated will not be what you expect. ```asp-route``` should not be used with either of the attributes ```asp-controller``` or ```asp-action``` to avoid a route conflict. +`asp-route` provides a way to create a URL that links directly to a named route. Using routing attributes, a route can be named as shown in the `SpeakerController` and used in its `Evaluations` method. + +`Name = "speakerevals"` tells the Anchor Tag Helper to generate a route directly to that controller method using the URL `/Speaker/Evaluations`. If `asp-controller` or `asp-action` is specified in addition to `asp-route`, the route generated may not be what you expect. `asp-route` should not be used with either of the attributes `asp-controller` or `asp-action` to avoid a route conflict. - - - ### asp-all-route-data -```asp-all-route-data``` allows you to create on your current .net context (that is, the running c# associated with your razor page) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. As the example below shows, you can create an inline dictionary on your razor page and then create the ```AnchorTagHelper``` right after that. You could of course pass in the dictionary with your model or as your model. That avoids having extra c# code on your razor page and gives you better control of the data passed to your view. +`asp-all-route-data` allows creating on a .NET context (that is, the running C# associated with your Razor view) a dictionary of key value pairs where the key is the parameter name and the value is the value associated with that key. + +As the example below shows, an inline dictionary is created and the data is passed to the razor view. The data could also be passed in with your model to keep the Razor view simpler. ``` @{ @@ -85,58 +87,59 @@ The code that this generates looks as follows: http://localhost/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true ``` -When the link is clicked, this will call the controller method ```EvaluationsCurrent``` because that controller has two string parameters that match what has been created from the ``` -asp-all-route-data``` -dictionary. +When the link is clicked, this will call the controller method `EvaluationsCurrent` because that controller has two string parameters that match what has been created from the `asp-all-route-data` dictionary. - - - ### asp-fragment -```asp-fragment``` appends after a hash (```#```) tag at the end of the URL whatever the value assigned to it is. That is, if you create a tag +`asp-fragment` defines a URL fragment to append to the URL. The Anchor Tag Helper will add the hash character (#) automatically. If you create a tag: ``` About Speaker Evals ``` + The generated URL will be + ``` http://localhost/Speaker/Evaluations#SpeakerEvaluations ``` + Hash tags are useful when doing client side applications. They can be used for easy marking and searching in JavaScript for example. - - - ### asp-area -```asp-area``` sets the area name that ASP.NET core will use to set the appropriate route with. Below are examples of how the area attribute causes a remapping of routes. That is, by setting ```asp-area``` to Blogs will invoke the Areas functionality such that the directory Areas/Blogs will prefix the associated controllers and views for this anchor tag. +`asp-area` sets the area name that ASP.NET Core uses to set the appropriate route. Below are examples of how the area attribute causes a remapping of routes. Setting `asp-area` to Blogs prefixes the directory Areas/Blogs to the routes of the associated controllers and views for this anchor tag.. * Project name - * wwwroot + * *wwwroot* - * Areas + * *Areas* - * Blogs + * *Blogs* - * Controllers + * *Controllers* - * HomeController.cs + * *HomeController.cs* - * Views + * *Views* - * Home + * *Home* - * Index.cshtml + * *Index.cshtml* - * AboutBlog.cshtml + * *AboutBlog.cshtml* - * Controllers + * *Controllers* -Specifying an area tag that is valid, such as ```area="Blogs"``` when referencing the ```AboutBlog.cshtml``` file will look like the following using the ```AnchorTagHelper```. +Specifying an area tag that is valid, such as ```area="Blogs"``` when referencing the ```AboutBlog.cshtml``` file will look like the following using the Anchor Tag Helper. ``` Blogs About @@ -149,13 +152,13 @@ The generated HTML will include the areas segment and will be as follows: ``` > [!TIP] -> For MVC Areas to work in your web application, the route template must include a reference to the area if it exists. That template (which is the second parameter of the ```routes.MapRoute``` method call) will look as follows: ```template: "{area:exists}/{controller=Home}/{action=Index}"```. +> For MVC areas to work in a web application, the route template must include a reference to the area if it exists. That template, which is the second parameter of the `routes.MapRoute` method call, will appear as: template: '"{area:exists}/{controller=Home}/{action=Index}"' - - - ### asp-protocol -The ```asp-protocol``` is for specifying a particular protocol (such as ```https```) in your URL. An example ```AnchorTagHelper``` that includes the protocol will look as follows. +The `asp-protocol` is for specifying a particular protocol (such as `https`) in your URL. An example Anchor Tag Helper that includes the protocol will look as follows. ```About``` @@ -163,7 +166,7 @@ and will generate HTML as follows. ```About``` -(of course the domain, in the case above is localhost, but this will be substituted for whatever the actual domain hosting the web site is hosted at). +The domain in the example is localhost, but the Anchor Tag Helper uses the website's public domain when generating the URL. - - - diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md index ea17f78cc428..a666b9ebc796 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/CacheTagHelper.md @@ -1,28 +1,25 @@ [Back To Built In Tag Helpers List](../../builtin.md) - -# CacheTagHelper +# Cache Tag Helper By [Peter Kellner](http://peterkellner.net) -The `CacheTagHelper` provides the ability to dramatically improve the performance of your ASP.NET core app by caching its content to the internal ASP.NET core cache provider. +The Cache Tag Helper provides the ability to dramatically improve the performance of your ASP.NET Core app by caching its content to the internal ASP.NET Core cache provider. -A simple example that shows the `CacheTagHelper` in action sets the current time in the content area of the Cache Tag Helper. The Razor View Engine sets the default of `expires-after` to be 20 minutes (this is the default if you specify no addional attributes). +A simple example that shows the Cache Tag Helper in action sets the current time in its content area. The Razor View Engine sets the default `expires-after` to twenty minutes, which is the default if you specify no additional attributes. -Here is an example of the code you would include in your `cshtml` page to achieve the default cache behavior described above. +Here is an example of the code you include in your `cshtml` page to achieve the default cache behavior described above. -```HTML +```html @DateTime.Now ``` -If you repeatedly refresh the page that contains the`Cache`tag above, the first time the current`DateTime`will be shown. Then, repeated refreshes of the page will continue to show the first`DateTime` shown until the cache expires (which is likely 20 minutes in this example). - -You can achieve more control of the cache duration of the content by setting any of the following attributes. - +If you repeatedly refresh the page that contains `CacheTagHelper`, the first time the current`DateTime`will be shown. Repeated refreshes of the page will continue to show the first `DateTime` shown until the cache expires (which is likely to be twenty minutes unless server memory pressure evicts the cache sooner). +You can achieve more control of the cache duration of the content by setting any of the following attributes: -## The attributes are defined as follows +## Cache Tag Helper Attributes - - - @@ -31,16 +28,16 @@ You can achieve more control of the cache duration of the content by setting any | Attribute Type | Valid Values | |---------------- |---------------- | -| boolean | "true","false" | +| boolean | "true" (default) | +| | "false" | -The attribute`enabled` determines whether any caching is performed of the content inside the `Cache` tag helper. The default is `true` which means that all other attributes will be active. It also means that if this attribute is left out, its default value will be set to true. If set to `false` then regardless of what other attributes are specified, this cache tag will have no caching effect on the rendered output. - +The attribute `enabled` determines whether any caching is performed of the content inside the Cache Tag Helper. The default is `true`, which results in all other attributes being valid. The default value is `true`. If set to `false`, regardless of what other attributes are specified, this Cache Tag Helper will have no caching effect on the rendered output. Usage Example: -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -53,13 +50,13 @@ Usage Example: | DateTimeOffset | "@new DateTime(2025,1,29,17,02,0)" | -The attribute `expires-on` sets a deterministic expiration date for caching the content of the `Cache` tag helper when the tag helper is first rendered. The example below will cache the contents of the `Cache` tag helper until 5:02 PM on January 29, 2025. +The attribute `expires-on` sets a deterministic expiration date for caching the content of the Cache Tag Helper when it is first rendered. The example below will cache the contents of the Cache Tag Helper until 5:02 PM on January 29, 2025. Usage Example: -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -69,16 +66,16 @@ Usage Example: | Attribute Type | Example Value | |---------------- |---------------- | -| TimeSpan | "@TimeSpan.FromSeconds(5)" | +| TimeSpan | "@TimeSpan.FromSeconds(120)" | -The attribute `expires-after` sets a specific amount of time from the current `DateTime` that the contents of the `Cache` tag helper will be kept. This value is set when the `Cache` tag helper is first rendered. The example below will likely cache the contents of the `Cache` tag for 5 seconds. +The attribute `expires-after` sets a specific amount of time from the current `DateTime` to cache the contents of the Cache Tag Helper. This value is set when it is first rendered. The example below caches the contents of the Cache Tag Helper for one hundred twenty seconds. If there is memory pressure on the server, the cache may be evicted sooner. Usage Example: -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -95,9 +92,9 @@ The attribute `expires-after` sets a specific amount of time from the current `D Usage Example: -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -110,13 +107,15 @@ Usage Example: | String | "User-Agent" | | | "User-Agent,content-encoding" | -The attribute `vary-by-header` allows for either a single header or a comma separated list of headers to be identified that will cause a cache refresh when changed. That is, when any header in the `vary-by-header` list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the header value `User-Agent` which will effectively cache the content for every different `User-Agent` presented to the web server. +The attribute `vary-by-header` accepts a single header value or a comma-separated list of header values that trigger a cache refresh when they change. The example below looks at the header value `User-Agent`, which will cache the content for every different `User-Agent` presented to the web server. Usage Example: +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now +``` - - - @@ -127,14 +126,16 @@ Usage Example: | String | "Make" | | | "Make,Model" | -The attribute `vary-by-query` allows for either a single query parameter or a comma separated list of query parameters to be identified that will cause a cache refresh when the passed in query value or values change. That is, when any query parameter in the `vary-by-query` list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the values of Make and Model and when either or both change, the content of the `Cache` tag helper will be rendered again and the cache is reset to that new value. +The attribute `vary-by-query` accepts a single header value or a comma-separated list of header values that trigger a cache refresh when they change. The example below looks at the values of `Make` and `Model`; and when either or both change, the content of the Cache Tag Helper is rendered again, and the cache is reset. Usage Example: - +``` +html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now +``` - - - @@ -145,24 +146,23 @@ Usage Example: | String | "Make" | | | "Make,Model" | -The attribute `vary-by-route` allows for either a single route parameter or a comma separated list of route parameters to be identified that will cause a cache refresh when the passed in route value or values change. That is, when any request causes one or more of the route parameters to change, the content of the `Cache` tag helper will be updated. The example below looks at the values of Make and Model. When either or both change, the content of the `Cache` tag helper will be rendered again and the cache is reset. +The attribute `vary-by-route` accepts a single header value or a comma-separated list of header values that trigger a cache refresh when they change. The example below looks at the values of `Make` and `Model`. When either or both change, the content of the Cache Tag Helper is rendered again, and the cache is reset. Usage Example: -Startup.cs +*Startup.cs* -```C# +```csharp routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{Make?}/{Model?}"); + name: "default", + template: "{controller=Home}/{action=Index}/{Make?}/{Model?}"); ``` +*Index.cshtml* -Index.cshtml - -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -175,13 +175,15 @@ Index.cshtml | String | ".AspNetCore.Identity.Application" | | | ".AspNetCore.Identity.Application,HairColor" | -The attribute `vary-by-cookie` allows for either a single request cookie or a comma separated list of request cookies to be identified that will cause a cache refresh when the current request's cookie value or values change. That is, when any cookie parameter in the vary-by-cookie list is seen for the first time or changed, the content of the `Cache` tag helper will be updated. The example below looks at the cookie associated with asp.net Identity. When a user is authenticated causing the request cookie to be set, The content of the `Cache` tag helper will be rendered again and the cache is reset. +The attribute `vary-by-cookie` accepts a single header value or a comma-separated list of header values that trigger a cache refresh when they change. The example below looks at the cookie associated with asp.net Identity. When a user is authenticated causing the request cookie to be set, The content of the Cache Tag Helper is rendered again, and the cache is reset. Usage Example: +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now +```` - - - @@ -190,21 +192,22 @@ Usage Example: | Attribute Type | Example Values | |---------------- |---------------- | | Boolean | "true" | -| | "false" | - -The attribute `vary-by-user` allows for the logged in user (or Context Principal) changes to cause a cache refresh. That is, when the authenticated user changes, the content of the `Cache` tag helper will be updated. The current user is also known as the Request Context Principal and can be viewed on a razor cshtml page by referencing `@User.Identity.Name`. +| | "false" (default) | +The attribute `vary-by-user` specifies whether or not the cache should reset when the logged-in user (or Context Principal) changes. The current user is also known as the Request Context Principal and can be viewed in a Razor view by referencing `@User.Identity.Name`. -The example below looks at the current logged in user. When a different user is found, The content of the `Cache` tag helper will be rendered again and the cache is reset. +The example below looks at the current logged in user. When a different user is found, The content of the Cache Tag Helper is rendered again, and the cache is reset. Usage Example: +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now +``` > [!NOTE] -> using the attribute `vary-by-user` will maintain the contents in cache through a log in and log out cycle. When using `vary-by-cookie` which references the `.AspNetCore.Identity.Application` as shown above, a log in and log out action will invalidate the cache for the same authenticated user because a new cookie value will be generated. Also, if no user is authenticated (or logged in), that state is considered a valid cache state which means that no logged in user is one cache state and the contents will be maintained for that condition as well. +> Using the attribute `vary-by-user` maintains the contents in cache through a log-in and log-out cycle. When using `vary-by-cookie` which references the `.AspNetCore.Identity.Application` as shown above, a log-in and log-out action invalidates the cache for the same authenticated user because a new cookie value is generated. If no user is authenticated, that state is considered a valid cache state, which means that no logged-in user is one cache state, and the contents will be maintained for that condition as well. - - - @@ -215,20 +218,19 @@ Usage Example: | String | "@Model" | -The attribute `vary-by` allows for customization of what data gets cached. When the string value changes of what is assigned to the attribute 'vary-by', the content of the `Cache` tag helper will be updated. Often a model value or combination of model values are assigned to this attribute. Otherwise, the value will never change and the cache will be updated only by the inclusion of other attributes in the `Cache` tag helper. +The attribute `vary-by` allows for customization of what data gets cached. When the object referenced by the attribute's string value changes, the content of the Cache Tag Helper is updated. Often a string-concatenation of model values are assigned to this attribute. Effectively, that means any update to any of the concatenated values invalidates the cache. -The example below assumes the controller method rendering the view sums the integer value of the two route parameters, myParam1 and myParam2, and returns that as the single model property. When this sum changes, the content of the `Cache` tag helper will be rendered again and the cache is reset. +The example below assumes the controller method rendering the view sums the integer value of the two route parameters, `myParam1` and `myParam2`, and returns that as the single model property. When this sum changes, the content of the Cache Tag Helper is rendered again, and the cache is reset. Usage Example: -Controller +*Controller* -```C# -public IActionResult Index - (string myParam1,string myParam2,string myParam3) +```csharp +public IActionResult Index(string myParam1,string myParam2,string myParam3) { - int num1; + int num1; int num2; int.TryParse(myParam1, out num1); int.TryParse(myParam2, out num2); @@ -236,11 +238,11 @@ public IActionResult Index } ``` -Index.cshtml +*Index.cshtml* -```HTML +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now ``` @@ -255,13 +257,15 @@ Index.cshtml | | "NeverRemove" | | | "Normal" | -The attribute `priority` is used to give guidance to the built in cache provider on what priority to assign to the cache contents stored. That is, there is no guarantee of the cache not being invalidated prior to the expected expiration. If for example you set one `Cache` tag helper to have its priority `High` and another to `Low`, it is likely that if the web server experiences memory pressure and needs to evict one of your cached content values, it will evict the `Low` priority first. +The attribute `priority` provides cache ejection guidance to the built-in cache provider. If the web server experiences memory pressure and evicts one or more of your cached entities, it will evict Low priority cache entities first. Usage Example: +```html - Current Time Inside Cache Tag Helper: @DateTime.Now + Current Time Inside Cache Tag Helper: @DateTime.Now +``` > [!WARNING] > using the `priority` attribute does not guarantee any specific level of cache retention. It is simply a suggestion to the Cache Provider. To be extra clear, setting this attribute to `NeverRemove` does not guarantee that the cache will not be evicted. More details can be found in the additional resources listed below. @@ -270,9 +274,13 @@ Usage Example: >[!NOTE] ->The ```CacheTagHelper``` is dependent on the built in Memory Cache service being included in the ```startup.cs``` ConfigureServices method. Adding this service is not necessary because the built in Tag Helper extensions take care of this in the AddMvc() method call. +> The Cache Tag Helper is dependent on the built in Memory Cache service being included in the `startup.cs` ConfigureServices method. Adding this service is not necessary because the built in Tag Helper extensions take care of this in the `AddMvc` method call. ## Additional Resources -* [In Memory Caching](../../../../../performance/caching/memory.md) -* [ASP.NET Core Identity (Authentication)](../../../../../security/authentication/identity.md) +* +* + + + + diff --git a/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md index 7aa1e08f2d33..0f0621ec6b89 100644 --- a/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md +++ b/aspnetcore/mvc/views/tag-helpers/builtin/resources/ImageTagHelper.md @@ -1,46 +1,50 @@ [Back To Built In Tag Helpers List](../../builtin.md) - # ImageTagHelper By [Peter Kellner](http://peterkellner.net) +The Image Tag Helper enhances the `img` (``) tag. It requires a `src` tag as well as the `boolean` attribute `asp-append-version`. -The `ImageTagHelper` enhances the html `img` (``````) tag. It requires a `src` tag be present as well as the `boolean` attribute `asp-append-version` be included. - -If the image source (```src```) is a static file on the host web server, a unique cache bursting string is appended as a parameter to the image source. This insures that if the file on the host web server changes, a unique request url will be generated that includes the updated request parameter. The cache bursting string is a unique value representing the `Sha512` value of the static image file. +If the image source (`src`) is a static file on the host web server, a unique cache busting string is appended as a query parameter to the image source. This insures that if the file on the host web server changes, a unique request URL is generated that includes the updated request parameter. The cache busting string is a unique value representing the `SHA256` hash of the static image file. -If the image source (```src```) is not a static file (possibly a remote url or the file does not exist on the server) then no unique parameter will be generated and the `img` tag will be generated with no additional cache bursting parameter. +If the image source (`src`) isn't a static file, possibly a remote URL or the file doesn't exist on the server, the `` tag's `src` attribute is generated with no cache busting query string parameter. -## The attributes are defined as follows: +## Image Tag Helper Attributes - - - ### asp-append-version -`asp-append-version` is the only attribute available for the Image Tag Helper. When specified along with a `src` attribute, this `Image` tag helper is invoked. +`asp-append-version` is the only attribute available for the Image Tag Helper. When specified along with a `src` attribute, this Image Tag Helper is invoked. -An example of a valid `img` tag helper is as follows +An example of a valid `img` tag helper is: -`````` +```html + +``` -If the static file exists on the web server, typically in the directory `..wwwroot/images/asplogo.png` the generated html will be +If the static file exists on the web server, typically in the directory `..wwwroot/images/asplogo.png` the generated html is: -`````` +```html + +``` -The value assigned to the parameter `v` is the hash value of the file on disk generated using the .net library method ```CryptographyAlgorithms.CreateSHA256().ComputeHash()```. If the web server is unable to get read access to the static file referenced (in our case ```..wwwroot/images/asplogo.png```) no v parameters is added to the src attribute and the original src attribute used is unchanged. +The value assigned to the parameter `v` is the hash value of the file on disk generated using the .NET library method `CryptographyAlgorithms.CreateSHA256().ComputeHash()`. If the web server is unable to obtain read access to the static file referenced, `wwwroot/images/asplogo.png`, no `v` parameters is added to the `src` attribute, and the original src attribute is unchanged. - - - ### src -The `src` attribute is required on the `img` html element. For the `ImageTagHelper` to be activated, this `src` attribute must be included as one of the tag helper attributes. +To activate the Image Tag Helper, the src attribute is required on the `` element. > [!NOTE] > The Image Tag Helper uses the `Cache` provider on the local web server to store the calculated `Sha512` of a given file. If the file is requested again the `Sha512` does not need to be recalculated. The Cache is invalidated by a file watcher that is attached to the file when the file's `Sha512` is calculated. -## Additional Resources +## Additional Resource -* [In Memory Caching](../../../../../performance/caching/memory.md) +*