Category Archives: Kinect

Tag Helper Authoring in ASP .NET Core 3.1

By Shahed C on May 18, 2020

This is the twentieth of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

NOTE: The NetLearner suite of apps doesn’t currently use custom tag helpers in the main branch, so you can check out the new sample code in the experimental subfolder, merged from a branch:

In this Article:

T is for Tag Helper Authoring

Tag Helpers are very useful for ASP .NET Core developers in creating HTML elements with server-side attributes. They work equally well in both Razor Pages and MVC views. Better yet, the syntax allows a front-end developer to easily customize the UI, with HTML/CSS knowledge.

If you need a refresher on built-in tag helpers in ASP .NET Core, you may revisit an earlier post in this series:

Tag Helpers in ASP .NET Core
Tag Helpers in ASP .NET Core

Authoring your own tag helpers is as easy as implementing the ITagHelper interface. To make things easier, the TagHelper class (which already implements the aforementioned interface) can be extended to build your custom tag helpers.

Custom Tag Helpers

As with most concepts introduced in ASP .NET Core, it helps to use named folders and conventions to ease the development process. In the case of Tag Helpers, you should start with a “TagHelpers” folder at the root-level of your project for your convenience. You can save your custom tag helper classes in this folder.

This blog post and its corresponding code sample builds upon the official tutorial for authoring tag helpers. While the official tutorial was originally written to cover instructions for MVC views, this blog post takes a look at a Razor Page example. The creation of Tag Helpers involves the same process in either case. Let’s start with the synchronous and asynchronous versions of a Tag Helper that formats email addresses.

The class EmailTagHelper.cs defines a tag helper that is a subclass of the TagHelper class, saved in the “TagHelpers” folder. It contains a Process() method that changes the output of the HTML tag it is generating.

public class EmailTagHelper : TagHelper
{
   ...
   // synchronous method, CANNOT call output.GetChildContentAsync();
   public override void Process(TagHelperContext context, TagHelperOutput output)
   {
      // ...
   } 
} 

The class AsyncEmailTagHelper.cs defines a tag helper that is also a subclass of the TagHelper class, saved in the aforementioned “TagHelpers” folder. It contains a ProcessAsync() method, which has a different signature (returns Task object instead of void) and grabs the child content from the output using output.GetChildContentAsync();

public class AsyncEmailTagHelper : TagHelper
{
   ...
   // ASYNC method, REQUIRED to call output.GetChildContentAsync();
   public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
   {
      // ... 
   }
}

In order to use the tag helper in a Razor Page, simply add a using statement for the Tag Helper’s namespace, and then include a custom HTML tag that has the same name as the Tag Helper’s class name (without the TagHelper suffix). For the Email and AsyncEmail Tag Helpers, the corresponding tags in your Razor Page would be <email> and <async-email> respectively.

In the EmailTester.cshtml page:

<email mail-to="Black.Widow"></email>

In the AsyncEmailTester.cshtml page:

<async-email>Black.Widow</async-email>

Note that the PascalCase capitalization in the class name corresponds to a lowercase tag in kebab-case. In a browser, the end result includes a clickable email link from the Razor Pages. Both the non-async and async version of the methods produce similar end results.

Email tag helper in a browser
Async Email tag helper in a browser
Async Email tag helper in a browser

Setting Attributes and Content

So how does the Process() method convert your custom tags into valid HTML tags? It does that in a series of steps.

  1. Set the HTML element as the tag name to replace it with, e.g. <a>
  2. Set each attribute within that HTML element, e.g. href
  3. Set HTML Content within the tags.

The process involved is slightly different between the synchronous and asynchronous versions of the Process method. In the synchronous EmailTagHelper.cs class, the Process() method does the following:

// 1. Set the HTML element
output.TagName = "a"; 

// 2. Set the href attribute
output.Attributes.SetAttribute("href", "mailto:" + address);

// 3. Set HTML Content
output.Content.SetContent(address);

In the asynchronous AsyncEmailTagHelper.cs class, the ProcessAsync() method does the following:

// 1. Set the HTML element
output.TagName = "a"; 

var content = await output.GetChildContentAsync();
var target = content.GetContent() + "@" + EmailDomain;

// 2. Set the href attribute within that HTML element, e.g. href
output.Attributes.SetAttribute("href", "mailto:" + target);

// 3. Set HTML Content
output.Content.SetContent(target);

The difference between the two is that the async method gets the output content asynchronously with some additional steps. Before setting the attribute in Step 2, it grabs the output content from GetChildContentAsync() and then uses content.GetContent() to extract the content before setting the attribute with output.Attributes.SetAttribute(). 

Updating Pre/Post Content

This section recaps the BoldTagHelper explained in the docs tutorial, by consolidating all the lessons learned. In the BoldTagHelper.cs class from the sample, you can see the following code:

[HtmlTargetElement("bold")]
[HtmlTargetElement(Attributes = "bold")]
public class BoldTagHelper : TagHelper
{
   public override void Process(TagHelperContext context, TagHelperOutput output)
   {
      output.Attributes.RemoveAll("bold");
      output.PreContent.SetHtmlContent("<strong>");
      output.PostContent.SetHtmlContent("</strong>");
   }
}

Let’s go over what the code does, line by line:

  • The [HtmlTargetElement] attribute forces a Tag Helper to target a specific element, e.g. [HtmlTargetElement(“bold”)], which will target a <bold> tag in a Razor Page or MVC View.
  • When one or more attributes are specified, e.g. [HtmlTargetElement(Attributes = “bold”)], the Tag Helper targets a bold attribute within an element, e.g. <p bold>
  • Combining the above one after the other gives you an OR condition, in which either scenario can be matched.
  • Combining them in a single [HtmlTargetElement] creates an AND condition, which would match a bold tag with a bold attribute, which is not very useful, e.g. [HtmlTargetElement(“bold”, Attributes = “bold”)]

Here is a snippet the corresponding Razor Page for testing the above scenario, BoldTester.cshtml:

<p bold>This paragraph uses a P tag with a bold attribute. 
Using a tag helper, the entire paragraph should be displayed with bold text.</p>

<bold>This statement uses a custom bold tag to be displayed in bold.</bold>

The tag helper affects both fragments, as seen in the screenshot below:

Bold tag helper in a browser
Bold tag helper in a browser

The statements in the Process() method accomplish the following:

  • The RemoveAll() method from output.Attributes removes the “bold” attribute within the tag, as it is essentially acting as a placeholder.
  • The SetHtmlContent() from output.PreContent adds an opening <strong> tag  inside the enclosing element, i.e. just after <p> or <bold>
  • The SetHtmlContent() from output.Postontent adds a closing </strong> tag  insidethe enclosing element, i.e. just before </p> or </bold>

Passing Complex Objects

What if you want to pass a more complex object, with properties and objects within it? This can be done by defining a C# model class, e.g. SuperheroModel.cs, that can be initialized inside in the Page Model class (SuperheroInfoTester.cshtml.cs) and then used in a Razor Page (SuperheroInfoTester.cshtml). The tag helper (SuperheroTagHelper.cs) then brings it all together by replacing <superhero> tags with whatever SuperHeroModel info is passed in.

Let’s take a look at all its parts, and how it all comes together.

Object ModelSuperheroModel.cs

public class SuperheroModel
{
   public string LastName { get; set; }
   public string FirstName { get; set; }
   public string SuperName { get; set; }
   public bool HasSurvived { get; set; }

   public bool ShowInfoWithSpoilers { get; set; }
}

Razor PageSuperheroInfoTester.cshtml

@page
@model SuperheroInfoTesterModel

... 

<h3>Black Widow Info:</h3>
<div condition="@Model.blackWidowInfo.ShowInfoWithSpoilers">
 <superhero hero-info="Model.blackWidowInfo" />
</div>
...

Page Model for Razor PageSuperheroInfoTester.cshtml.cs

public class SuperheroInfoTesterModel : PageModel
{
   public SuperheroModel blackWidowInfo { get; set; }
   // ...

   public void OnGet()
   {
      blackWidowInfo = new SuperheroModel
      {
         // ...
      }
      // ...
   }
}

Superhero Tag HelperSuperheroTagHelper.cs

public class SuperheroTagHelper : TagHelper
{
   public SuperheroModel HeroInfo { get; set; }

   public override void Process(TagHelperContext context, TagHelperOutput output)
   {
     // ...
   }
}

Going through the above code:

  1. The tag helper is named SuperheroTagHelper, implying that it can be used for <superhero> tags in a Razor Page, e.g. SuperHeroInfoTester.cshtml
  2. The tag helper also contains a SuperheroModel object called HeroInfo, which allows a hero-info attribute, i.e. <superhero hero-info=”Model.property”>
  3. The SuperheroModel class contains various public properties that provide information about a specific superhero.
  4. The SuperHeroInfoTesterModel page model class includes an OnGet() method that initializes multiple SuperheroModel objects, to be displayed in the Razor Page.

Inside the tag helper, the Process() method takes care of replacing the <superhero> tag with a <section> tag:

public override void Process(TagHelperContext context, TagHelperOutput output)
{
   string htmlContent = $@"<ul><li><strong>First Name:</strong> {HeroInfo.FirstName}</li>
<li><strong>Last Name:</strong> {HeroInfo.LastName}</li>
<li><strong>Superhero Name:</strong> {HeroInfo.SuperName}</li>
<li><strong>Survived Endgame? </strong> {HeroInfo.HasSurvived}</li></ul>";
 
   output.TagName = "section";
   output.Content.SetHtmlContent(htmlContent);
   output.TagMode = TagMode.StartTagAndEndTag; 
}

After initializing some HTML content to display a <ul> list, the above code in the Process() method accomplishes the following:

  1. Set the HTML element as the tag name to replace it with, e.g. <section>
  2. Set HTML Content within the tags.
  3. Set Tag Mode to include both start and end tags, e.g. <section> … </section>

End Result in Browser:

Superhero tag helper in a browser
Superhero tag helper in a browser

In a web browser, you can see that that the <superhero> tag has been converted into a <section> tag with <ul> content.

Handling Conditions

When you want to handle a UI element in different ways based on certain conditions, you may use a ConditionTagHelper. In this case, a condition is used to determine whether spoilers for the popular movie Avengers: Endgame should be displayed or not. If the spoiler flag is set to false, the character’s info is not displayed at all.

@page
@model SuperheroInfoTesterModel
...
<div condition="@Model.blackWidowInfo.ShowInfoWithSpoilers">
 <superhero hero-info="Model.blackWidowInfo" />
</div>
...

In the above code from the SuperheroInfoTester.cshtml page:

  • the <div> includes a condition that evaluates a boolean value, e.g. Model.blackWidowInfo.ShowInfoWithSpoilers
  • the Model object comes from the @model defined at the top of the page
  • the boolean value of ShowInfoWithSpoilers determines whether the <div> is displayed or not.

References

Your First Razor UI Library with ASP .NET Core

By Shahed C on December 2, 2018

This is the ninth of a new series of posts on ASP .NET Core. In this post, we’ll learn about Razor Class Libraries to build reusable UI for your web app. This post is also included in Matthew Groves‘ 2018 C# Advent Calendar, in the Dec 2 slot.

ASPNETCoreLogo-300x267

Introduction to Razor Class Libraries

From an earlier post on Pages in ASP .NET Core, we’ve seen various of ways of creating web pages with or without controllers, views and models to support each of your pages. If you’re an experienced developer, you already know how to reuse server-side code in class libraries.

Starting with ASP .NET Core 2.1, you can now “package your Razor views and pages (.cshtml files) along with your controllers, page models, and data models in reusable class libraries that can be packaged and shared. Apps can then include pre-built UI components by referencing these packages and customize the UI by overriding specific views and pages.”

Better yet, ASP .NET Core Identity is now available as a Razor Class Library, and can be scaffolded into your web application with just the pieces you need.

Before You Begin

Before you begin, take a look at the sample code project on GitHub:

Web GameConsoles on GitHub: https://github.com/shahedc/GameConsoles

Open the GameConsoles.sln file to load the 2 projects included with the solution:

  • Web App project (Set as StartUp Project)
  • Razor UI Class Library project (contains shared UI for reuse)

Steps to Create in Visual Studio 2017

Create Class Library project, add reusable UI: 

  1. Click File | New | Project
  2. Select ASP .NET Core Web Application, click OK
  3. Select Razor Class Library under ASP .NET Core 2.1

VS2017-Project-RazorClassLibrary

Add partial views under /Pages/Shared/

  • /Pages/Shared/_Header.cshtml
  • /Pages/Shared/_Footer.cshtml
  1. Create folder structure /Pages/Shared/
  2. Add new Razor View _Header.cshtml to Shared subfolder
  3. Add new Razor View _Footer.cshtml to Shared subfolder

Reference for adding new folders and views: https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-view?view=aspnetcore-2.1

Contents of _Header.cshtml:

<h3>_Header.cshtml partial view.</h3>

<p>/Pages/Shared/_Header.cshtml</p>

<a href="/">Home</a>

Contents of _Footer.cshtml:

<h3>_Footer.cshtml partial view.</h3>

<p>/Pages/Shared/_Footer.cshtml</p>

Source: <a href="https://en.wikipedia.org/wiki/List_of_home_video_game_consoles">https://en.wikipedia.org/wiki/List_of_home_video_game_consoles</a>

Continue reading

Celebrating 3 Years at Microsoft!

By Shahed C on April 1, 2017

It’s been three years since I joined Microsoft… how did I get here? Before you begin, check out my new Facebook page for developers: Shahed Codes! And then connect with me on LinkedIn!

mslogo Wake Up And Code!

With a background in ASP .NET web application development for enterprise customers, I recently published my first book, “ASP .NET Core Essentials”, via Packt Publishing. You can check it out at the following URL: https://www.packtpub.com/web-development/aspnet-core-essentials

But first, a little history…

Back in 2011, I published a couple of silly little indie games for Xbox 360, using XNA and C# in Visual Studio. While working at my day job, I had gotten a little bored with business applications and decided to teach myself game programming. I made a little profit with my games, including Angry Zombie Ninja Cats.

Ninja Cat Sprite Sheet

Ninja Cat Sprite Sheet

With mixed reviews, the ratings bounced back and forth between 3 stars and 4 stars, and finally settled on approximately 3.5 stars. The game even got a brutally honest review from Indie Gamer Chick, who later invited me to write a couple of dev articles for her website:

The latter article even got republished on Gamasutra:

By 2012, I branched out into make free dev tools for XBLIG indie devs, such as the XNA Sales Data Analyzer and XBLIG Basic Starter Kit. The Sales Data Analyzer tool was received well by the indie media (including my now-colleague Dave Voyles), and was used by XNA developers across the US and around the world! 🙂

statsUS analyticsMap

The first time I ever spoke at a public event was at NoVA Code Camp in 2013, while I was working at Excella Consulting. I joined my colleagues Sahil Talwar and Doguhan Uluca in delivering a 3-part presentation on a complete end-to-end lean web application architecture. Specifically, I talked about Entity Framework Code First Migrations.

Source: https://twitter.com/shahedC/status/326068261336788992

Combining my background in enterprise business applications and indie game development, I decided to start speaking on various topics ranging from ASP .NET to Xbox game development. By 2014, I achieved a triple-achievement with the following:

  1. mentioned in Official Xbox Magazine
  2. selected to received MVP Award
  3. received job offer from Microsoft

Source: Official Xbox Magazine, March 2014, Page 65

Source: Official Xbox Magazine, March 2014, Page 65

The MVP Award for Microsoft is only for members of the community who are not employees of Microsoft, so I gave up the award when I accepted a job offer from Microsoft in March 2014. Since then, I’ve had the chance to work with all sorts of development tools, technology and platforms, including:

All of the above allowed me to start working on customer projects ranging from Xamarin and Azure to ASP .NET Core and IoT. Upcoming projects will include Bot Framework, Cognitive Services and HoloLens! I also got a chance to build an internal Kinect v2 application called Speech Bubbles, which tracks passers-by and displays cartoon bubbles above their heads to follow them around as they continue walking.

I had the opportunity to record 3 courses for Microsoft Virtual Academy with my then-colleague James Quick. The primary topic was Game Development with Construct 2, including the use of Xbox One controllers and the publishing process of getting your game into the Windows Store and the Xbox Store.

mva

Over the years, I’ve had the chance to speak at various community events around the DC/MD/VA region, along the East Coast and even across the US. When Unity Technologies came to town, I hosted their official Unity Roadshow events with Carl Callewaert, Unity’s Global Director of Evangelism. I even took some time off to fly to Barcelona (Spain!) to teach a game dev workshop to a team of King employees. In case you haven’t heard of King, they’re the developers of a popular mobile game called Candy Crush.

carl-unity king

In addition to community events, I’ve delivered talks and mentored students at various hackathons, including: American University, Georgetown University, Gallaudet University, Howard University, University of Maryland @ College Park, University of Maryland @ Baltimore County, James Madison University, Johns Hopkins University, George Mason University, University of Pennsylvania, University of Virginia (UVA), Virginia Polytechnic Institute and State University (Virginia Tech) and Massachusetts Institute of Technology (MIT).

universities

One of these hackathons was HackMIT, where I had the opportunity to join my colleague Gavin Bauman in training a group of HackMIT attendees at the beginning of the hackathon. We also mentored the students throughout the event.

Fast-forward to 2017, I’ve been facilitating the NoVA Code Camp event at the Microsoft office in Reston VA (now twice a year). This community-led event owes its existence to volunteers from the community, including current organizers Ed Snider and Stan Reeser. Past organizers include Tasha Scott and Greg Hurlman.

The following Twitter Moment consolidates the tweets that mention our sponsors and speakers at NoVA Code Camp 2017.1 for Spring 2017:

FB-FindUsOnFacebook-printpackaging-2

I’ve continued to administer and moderate multiple developer groups on Facebook (and a real-life Meetup group):

Hope you found some inspiration in my journey. If you’ve made it this far… check out my previous anniversary blog post from 2016!

 

 

UMD Kinect Q&A: an interview with Gregory Kramida at the University of Maryland

By Shahed C on August 3, 2015

We’re here with Gregory Kramida to talk about his Kinect group projects at the University of Maryland.

Gregory Kramida at UMD

Gregory Kramida at UMD

1. Greg, tell us a little bit about yourself and your team.

I have received a BA in Graphic Design, and a BS and MS in Computer Science (CS) from the University of Maryland. Currently, I am a PhD student in CS at the same University. My team consists of four very talented young individuals and myself.

We currently have two other CS PhD students, one Physics Masters student, and one Computer Engineering undergraduate student. Neither one of us is fully finished with his educational goals, and some of us are still finidng our true calling, so we are forced to collaborate in an ad-hoc fashion.

Whenever any of us has the time and energy, they contribute. Hence, I am the only “permanent” member, and we are allways looking for like-minded, driven, and talented individuals.

Continue reading

Philly Code Camp 2015

By Shahed C on March 20, 2015

Presentation Material for Philly Code Camp 2015

1. Capturing Your Audience with Kinect (featuring Speech Bubbles)

2. Azure Mobile Services (+ Universal Apps)