Announcing: Blazor Snippets for VS Code

I wrote some Blazor Snippets for VS Code. Download it here!

 

Now that VS Code has Razor support built-in to the C# extension, I wanted to write some Blazor in VS Code.  I was surprised to not see any Blazor-specific snippets created so I created my first VS Code extension for the Blazor Snippets.

 

Examples

  • Using bc to create a blank Blazor Component, bpara to create a parameter, boi to create OnInitAsync, and binjhttpto inject an HttpClient.

Snippets used together

  • Using bchttp to scaffold out a Blazor Component with an HttpClient call.

Snippets used together

 

There are over 20 snippets total right now and the full list of snippets is documented out on the GitHub readme.

 

Closing

Log an issue on the GitHub repo if you want to see new snippets or if you see any issues.

 

Hope this helps!

Strongly Typing Dapper Queries Using nameof

tldr;

Use nameof in order to strongly type your Dapper queries, so renaming a property on your C# doesn’t break your Dapper query or require you to remember to go fix them.

 

Before Stringly Typed (note lines 12-14):

 

After Strongly Typed (note lines 12-14):

 

What is Dapper?

Dapper is a lightweight micro-ORM, made by the Stack Exchange team, that transforms your SQL into strongly typed objects.  No longer do you have to deal with DataTables, DataSets, DataReaders, and the like.  You can just deal with your objects like a Customer object with FirstName, LastName, and ZipCode properties.

Dapper is a great alternative to a more full-featured ORM like Entity Framework.  Sometimes, Entity Framework is too much for a query (because the LINQ is hard/impossible to write) or sometimes it’s just overkill.

Dapper is implemented as a set of extension methods hanging off of DbConnection and a simple example is below:

Dapper will open and close the connection for you, parameterize your SQL query, and then it will hydrate the Customer object’s FirstNameLastName, and ZipCode properties, because they match the SQL column names.

But let’s say you have SQL column names that quite don’t match your C# properties like F_NameL_Name, and Zip_Code.  No big deal, all you do is alias the column name to match the C# property like below (lines 12-14):

As you can see, it’s pretty simple to use and results in super clean code.  Dapper is also much faster than Entity Framework, because it’s closer to the metal, but you also give up some features compared to something like Entity Framework such as LINQ queries, Change Tracking, Query Filters, Migrations, etc.

It’s really common for the projects I work on to use Dapper and EF together depending on what the best tool is for the job.

 

Downsides of Dapper

However, there are of course downsides to Dapper compared to Entity Framework.  With Entity Framework, you can be almost 100% guaranteed that your query won’t blow up when you go to run it (short of a schema problem, but that would be an issue in any data access library).

With Dapper, it’s up to you to write the correct SQL in a string.  If you misspell a column name, the C# compiler won’t yell at you, and you won’t find out until you go to run it.  Same goes for all the normal SQL goof ups like inserting too many or too few commas, forgetting a space, etc.

To  mitigate this, I like to write my queries in SQL Management Studio, with the help of RedGate’s SQL Prompt extension, and then copy and paste that query into my C# code to use with Dapper.

 

Problem When Renaming C# Properties

Unfortunately, using SQL Management Studio to build your queries doesn’t solve all the problems.  Let’s say I want to rename the ZipCode property to ZipCode9 to be more obvious that this is a 9 digit Zip Code and not a 5 or 4 digit one.  The problem is when I rename my property, if I don’t remember to go fix the Dapper query, then the ZipCode9 property will be null and everything will fail silently.  This is…. less than ideal.

 

Solution

To fix this, we can use the C# 6 feature nameof which lets you get the name of a variable, property, etc.  So if I change the query to look like below:

This will drop the Customer. at the beginning and just leave you with ZipCode9.  So it ends up being the exact same query that we had before, but now it’s strongly typed.

Now when you go to rename a property on your C# model, either your editor (like Visual Studio, Rider, etc.) will rename the property for you.  Or… if you forget to let your editor do the hard work for you, then your app won’t even compile and it’ll tell you this field is broken.  This effectively gives you strongly typed queries for your Dapper code and eliminates one of the headaches that most people have with Dapper.

Obviously, it comes at some cost of readability, but after using this approach for a few months, I can sift through the noise really quick and it’s saved me a handful of times.

 

Conclusion

A few months ago I tweeted this:

This was in reference to this nameof solution.  I fully recognize some of you will love this, some of you will hate this, and some of you will sit in the middle like I did originally.

That said, members of my team and I have started using this approach as our default and I’ve actually been fairly happy with it.  Like I said earlier, I can sift through the nameof noise quickly and the strongly typedness has already saved me a handful of times.

 

Hope this helps!

Walkthrough: Creating an HTML Email Template with Razor and Razor Class Libraries and Rendering it from a .NET Standard Class Library

tldr;

HtmlEmailExample

Full Code: https://github.com/scottsauber/RazorHtmlEmails

 

Usually I don’t blog walkthroughs and instead prefer to go a little deeper on a small topic, but I thought it would be useful to blog our approach on generating HTML emails using Razor for an ASP.NET Core insurance application at work.

 

If you’re looking to generate HTML Emails outside of ASP.NET Core (such as a Console app), I also recommend checking out Derek Comartin‘s post: Using Razor in a Console Application (outside of ASP.NET Core MVC).

 

Purpose

HTML emails are the absolute worst.  Inlined styles.  Nested tables.  Different apps and platforms render the markup differently.  It’s an absolute train wreck.  However, sending plain text emails isn’t a great way to impress your users and often makes emails look fake or like spam.  So fine, HTML emails.  Let’s do it.

 

What I would like to do is create an HTML Email Template library, and let developers focus on the content of their email, and not worry about the extra cruft that is HTML Emails.

 

Also, I want to be able to generate these HTML Emails from within a .NET Class Library (be it .NET Standard or .NET Core), so that the sending of the emails happens right next to all my other business logic.

 

So at a high level, the requirements are:

  1. Create a base Email Layout to enforce a consistent layout (Header, Footer, base styles, etc.) and to hide the complexity of HTML Email Layouts.
  2. Create re-usable HTML Email components (such as buttons) to enforce consistent styling and hide the complexity of the implementation of the HTML Email components.
  3. Use Razor.
  4. Be able to call it from a .NET Standard or .NET Core Class Library.

 

Razor checks the box for #1, because it already has the concept of a Layout view and a child view.  It also is a good fit for #2, because it lets you re-use UI components via Partials (among other methods).  In fact, you can actually achieve #1, #2, and #3 in regular ASP.NET 4.x fairly easily.  However, I haven’t ever been able to achieve #4 in regular ASP.NET or pre-2.1 ASP.NET Core.  That is, I want to use Razor in a non-ASP.NET/ASP.NET Core setting such as Class Libraries.

 

It’s super common for applications to put their business logic in a Class Library to remove any dependency on the UI project and to allow that logic to be re-used across other applications.  However, when I tried to send HTML Emails from a Class Library in ASP.NET 4.x and ASP.NET Core pre-2.1, I couldn’t figure out how to get the Class Library to find the Views I was creating and ultimately I gave up.

 

Enter Razor Class Libraries

I won’t go into much detail about Razor Class Libraries, when the documentation already does a fantastic job, but the basic idea behind them is that you can share UI between multiple ASP.NET Core applications.  This UI can be Views, Controllers, Razor Pages, etc.

 

The simplest way to think about Razor Class Libraries is if you add a View in your Razor Class Library, it essentially gets copied down into that same relative path into your main application.  So if you add an Index.cshtml file to the /Views/Home path of your Razor UI Class Library, then that file will be available at /Views/Home/Index.cshtml of your ASP.NET Core Application.  That’s pretty sweet and useful. But the question is would it find those files in a normal .NET Standard Class Library?  The answer is – yes.

 

One potential gotcha: Make sure that your Views have unique names/paths.  If you make an HTML Email view that matches the path of an actual like MVC View or Razor Page, then they will conflict.  Therefore, I try to make my folder and/or view names clearly unique like “ConfirmAccountEmail.cshtml” which is unlikely to have a matching route on my ASP.NET Core application.

 

Alright then, let the walkthrough begin!

 

Create an ASP.NET Core Web Application

First – create an ASP.NET Core Web Application or you can use an existing ASP.NET Core Web App.  It doesn’t really matter what it is.

With Visual Studio:

  1. File
  2. New Project
  3. ASP.NET Core Web Application
    1. I just called it RazorHtmlEmails.AspNetCore
  4. Web Application
  5. OK

 

Or with the command line:

  1. dotnet new sln -n RazorHtmlEmails
  2. dotnet new razor -n RazorHtmlEmails.AspNetCore
  3. dotnet sln RazorHtmlEmails.sln add RazorHtmlEmails.AspNetCore

GitHub commit here

 

Create a Razor Class Library

Next – create an ASP.NET Core Razor Class Library.

With Visual Studio:

  1. Right-click the Solution
  2. Add
  3. New Project
  4. ASP.NET Core Web Application
    1. I just called it RazorHtmlEmails.RazorClassLib
  5. Razor Class Library
  6. OK

 

Or… with the command line:

  1. dotnet new razorclasslib -n RazorHtmlEmails.RazorClassLib
  2. dotnet sln RazorHtmlEmails.sln add RazorHtmlEmails.RazorClassLib

 

After you’ve created your Razor Class Library, delete out the Areas folder, because we won’t need it.

GitHub commit here

 

Create the RazorViewToStringRenderer class

Tucked away in the aspnet/Entropy GitHub repo is the RazorViewToStringRenderer which shows you how to take a Razor View and render it to an HTML string.  This will be perfect for taking our Razor View, converting it to a string of HTML, and being able to stick the HTML into the body of an email.

 

Add this class to your Razor Class Library you just created.  I tucked mine under a folder called Services and then created an Interface for it called IRazorViewToStringRenderer:

GitHub commit here

 

Create your base HTML Email Layout

The next step in the process is we are going to leverage Razor’s Layout system to create a base HTML Email Layout.  There are many HTML Email Layout templates out there so you don’t have to write one yourself (and trust me… if you’ve never seen HTML Email code before, you’re not going to want to write this yourself).

I’m picking this one from Litmus, which is the leading vendor  (as far as I know) for testing your HTML Emails on multiple different platforms, devices, and applications.  No they didn’t pay me to say that (although if someone from Litmus is reading this, it’d be cool if you did).

The layout looks like this:

HtmlEmailExample

 

However, all I really care about for the layout is everything outside of the white box for my layout.  Inside the white box will change based on whatever I’m sending (Email Registration Confirmations, Forgot Password requests, Password Updated Alerts, etc.).

 

HtmlEmailLayout

Steps:

  1. In your Razor UI Class Library, create a /Views/Shared folder
  2. Add an EmailLayout.cshtml to that folder
  3. Add the following code and try not to pass out

When you finish throwing up in your mouth, let’s look at a couple important bits. Line 165 has the RenderBody() call which is where the white box is and where our child view will be placed dynamically based on the email I’m sending.

 

Another interesting spot is line 142 where I’m dynamically pulling an EmailTitle property from ViewDataViewData allows us to pass messages from a child view up to the parent view.  In the email screenshot above, this is the “Welcome” hero text.

 

ViewData

 

In a real application, I would have pulled that Welcome text down to the child view as well, but I left that as a demonstration of the ability for the child view to dynamically change the parent EmailLayout.  Some more examples of what you could do with ViewData could be the child view wants to dictate which Logo to use or what color the background is, or literally anything you want.  This is simply just leveraging a feature that’s been part of MVC for a long time.

 

 

Now that we’ve finished the Email Layout, let’s look at adding a custom button component.

GitHub commit here

 

Create a HTML Email Button Partial for re-usability

The next thing I want to do is start to make reusable components via partial views in order to abstract away the complexity of certain HTML Email components, as well as always providing a consistent look to the end user.

 

A good example of this is the button:

EmailButton

 

All that really needs to be dynamic about this is the text and the link. That should be easy enough.

Steps:

  1. Under /Views/Shared add a EmailButtonViewModel.cs class
  2. Add the following code:

3. Add an EmailButton.cshtml file
4. Add the following code:

 

Now we can re-use buttons in our child views by simply doing this:

 

That saves us from copying and pasting that crazy table code around every time we need a button for our Emails, which is useful.

GitHub commit here

Create your HTML Email Content

Now we’ve got all of our foundation pieces in place, let’s start building on top of them. The last thing we need to do in our Razor Class Library is add our custom email.

 

  1. Add a new folder under Views called Emails. This folder will house all of our custom HTML Emails.
  2. Add a _ViewStart.cshtml and add the following code so that every HTML Email has the EmailLayout.cshtml we created above as its parent layout

3. Add a ConfirmAccount folder under /Views/Emails.  This folder will house our ConfirmAccount email logic.

4. Add a ConfirmAccountEmailViewModel.cs file with the following code:

5.Add a ConfirmAccount.cshtml file with the following code:

 

Right now is where it all starts to come together, and you can see the power of being able to use Razor to build out our HTML emails.  On our day-to-day emails that we build out for the rest of our application, we no longer have to worry about gross table syntax or inline style craziness, we can just focus on the custom content that makes up that HTML Email.

GitHub commit here

 

Create a .NET Standard (or .NET Core) Class Library

But one of the coolest things about this, is the fact that we can call this code from regular .NET Standard (or .NET Core) Class Libraries, and have it all “just work.”  This means we can share our email templates across multiple applications to provide the same look and feel across all of them, and have all that logic live right next to the rest of our business logic.

 

So let’s create a .NET Standard Class Library.  If you want you can create a .NET Core Library and it’ll work as well.

With Visual Studio:

  1. Right-click the Solution
  2. Add
  3. New Project
  4. Class Library (.NET Standard)
    1. I just called it RazorHtmlEmails.Common
  5. OK

 

Or with the command line:

  1. dotnet new classlib -n RazorHtmlEmails.Common -f netstandard2.0
  2. dotnet sln RazorHtmlEmails.sln add RazorHtmlEmails.Common

 

Then delete out Class1.cs

GitHub commit here

 

Call the RazorViewToStringRenderer in your business logic

Now it’s time to hook up the .NET Core Class Library to the Razor Class Library.

  1. In the .NET Core Class Library (.Common), add a reference to the Razor Class Library (.RazorEmailLib)
  2. Install MailKit, a fantastic cross-platform, .NET Core-friendly email library
  3. Create a class called RegisterAccountService that will house our business logic for creating the account and sending the email.

The interesting bits are lines 25, where we create our ConfirmAccountEmailViewModel with the link we want to use and line 27 where we pass that model into our RazorViewToStringRenderer, and get back our Email’s HTML body.

 

As an aside, for testing local emails without an email server, I love using Papercut.  It’s a simple install and then you’re up and going with an email server that runs locally and also provides an email client.  No Papercut didn’t pay me to say that either.  It’s free.  If some paid service that does the same thing as Papercut does and wants to sponsor this blog, feel free to reach out to me and get rejected because you will never get me to give up Papercut.

GitHub commit here

 

Hook it up to the UI

The last step we have to do is to hook this up to the UI.  I’m just going to hook this up on a GET request of the /Index page just for demo purposes.  In reality, you’d have an input form that takes registration and have this happen on the POST.

 

  1. In your .AspNetCore project, add a project reference to .Common
  2. In Startup.cs under ConfigureServices wire up the IRegisterAccountService and the IRazorViewToStringRendererto their implementations.

3. In /Pages/Index.cshtml.cs, call the IRegisterAccountService in the OnGetAsync method

GitHub commit here

 

And you’re done!  When I run the app, and open up Papercut, I get my email in all its glory.

RazorEmail

 

Going forward, anytime I need an email, I can simply leverage the EmailLayout and EmailButton infrastructure I’ve created to make creating HTML emails incredibly easy and less table-y which is a huge win.

 

Just a reminder if somehow you’ve made it this far, all the code is out here on GitHub.

 

Hope this helps!