ASP.NET Core Blog tutorial: Adding Markdown
Tags: dotnet, csharp, webdev
Published: 2019-12-02 19:25:02

## Welcome Back

Okay, so far we've gotten through a very basic MVC pattern, configured our database and successfully displayed our example data on our front page. Now that's all cool and good, if you wanna manually insert all your blog posts every time you can just stop here. But I assume you're here to learn a lot more than just what we've covered so far, am I right?

If you are, then let's start talk formatting. You most likely don't wanna display just simple plain unformatted text, you most likely want *italics*, **bold**, headings, quotes and what not to make your posts more presentable and fun to read.

Right here you have two options:

### HTML
Nothing is stopping you from writing HTML directly into your posts, but let's be honest writing HTML without something like emmet or code highlighting can be a real pain. Especially if you're on a non-english keyboard. However if you do choose to go with the HTML option you could easily set up a ton of predefined CSS styles and javascript functions that would allow you to make format your content in near unlimited ways.

### Markdown
But you don't need that many styles. Most of the time less is more and that rule especially applies to text content. Markdown has all the bare necessities that you might need and more.
![bear necessities](https://media.giphy.com/media/oQIghQgiGwSbu/giphy.gif)
In fact this very post was written in Markdown and automatically translated into HTML, and I never felt I was missing any functionality, I almost never use everything that Markdown has to offer in a single post.

Additionally Markdown is so simple you could teach just about anyone to use it in less than an hour.

## We'll Be Using Markdown
For the purposes of this tutorial series we'll be using markdown to write our posts, you are of course free to use HTML if you wish, that is completely up to you.

So the first thing we wanna do is install a markdown parser to convert our markdown posts into HTML posts.
Open up a terminal or command prompt in the root of your directory and run:
```bash
dotnet add package Markdig
```

## Single Post Display
Now that you've installed Markdig let's move into our Views directory and create another folder, we'll name it `Post`. Inside of our newly created Post folder create another view named `Index.cshtml` and finally create a new controlled named `PostController.cs`.

#### Controllers/PostController.cs
```csharp
using System.Linq;
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Blog.Models.Repos;
namespace Blog.Controllers{
    public class PostController : Controller{
        
        [Route("/post/{postTitle}")]
        public IActionResult Index([FromRoute] string postTitle){
            BlogRepo blogRepo = new BlogRepo();
            return View(
                blogRepo.Posts.Find(
                    p => p.Title ==postTitle.Replace("-", " ") 
                ).FirstOrDefault()
            );
        }
    }
}
```
That `[Route("/post/{postTitle}")]` part is called an attribute, basically attributes act as a sort of middleware allowing you to quickly modify your methods without much hassle. In this case we're using a routing attribute and specifying that we expect the user to visit `http://host.com/post/{postTitle}` the `{postTitle}` part of the route is essentially a route variable.

What's going on in the actual method itself is fairly simple, in the previous tutorial we've made a read more link and replaced all the spaces in the string to `-` symbols. 
Now go back to our `Views/Home/Index.cshtml` and modify that link to 

```html
<a href="/post/@post.Title.Replace(' ','-')">read more</a>
```

#### Post/Index.cshtml
```html
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<section class="post">
    <h1>@Model.Title</h1>
    <p class="content">
        @Html.Raw(Markdig.Markdown.ToHtml(Model.Content))
        <!-- 
            @Html.Row() -   Anything in between the ( ) will be rendered as actual HTML. 
                            Without this part all of our HTML tags would be automatically
                            escaped, which means we'd essentially be showing out users HTML 
                            code instead of simple plain text.
            ---------------------------------------------------------------------------------
            @Markdig    -   We're specifying that we wish to use something from the Markdig
                            namespace.
            ---------------------------------------------------------------------------------
            Markdown    -   A static class inside of the Markdig namespace.
            ---------------------------------------------------------------------------------
            ToHtml()    -   A method that turns everything between ( ) from markdown to HTML 
         -->
    </p>
    <a href="/">Back</a>
</section>
```

If we run our ASP.NET Blog application now and click on the read more link we'll see that it takes us to a new page that shows us the title of the post and it's content.

**That's pretty cool huh?** However we haven't really done anything with Markdown here. Let's check if it actually works as expected. Let's head back into our `BlogRepo.cs` and create a new example post in our **CreateExamplePosts method**
```csharp
public void CreateExamplePosts(){
            
            List<Post> PostList = new List<Post>(){
                new Post(){
                    Title = "First post",
                    Public = true,
                    CoverImagePath = "", // leave this blank for now
                    Excerpt = "Define the underlying",
                    Content = "Define the underlying principles that drive decisions and strategy for your design language bleeding edge onward and upward"
                    // The above text was generated by Office Ipsum http://officeipsum.com/index.php
                },
                new Post(){
                    Title = "Second post",
                    Public = true,
                    CoverImagePath = "", // still blank
                    Excerpt = "so what's our",
                    Content = "so what's our go to market strategy?. Customer centric all hands on deck yet where the metal hits the meat define"
                },
                new Post(){
                    Title = "Not visible",
                    Public = false,
                    CoverImagePath = "", // blank
                    Excerpt = "not important",
                    Content = "not important, you should not see this post"
                },
                new Post(){
                    Title = "Third post",
                    Public = true,
                    CoverImagePath = "", // blank
                    Excerpt = "the underlying",
                    Content = "the underlying principles that drive decisions and strategy for your design language not the long pole",
                    Deleted = true // this one should also not be visible
                },
                new Post(){
                    Title = "Fourth post",
                    Public = true,
                    CoverImagePath = "", // blank
                    Excerpt = "in the future",
                    Content = "Post scheduling made super easy",
                    Created = DateTime.Now.AddDays(3) // Post scheduling made easy
                },
                new Post(){
                    Title = "Markdown Test",
                    Public = true,
                    CoverImagePath = "", // blank
                    Excerpt = "Let's see what markdown can do",
                    Content =   "# Hello world\n"+ 
                                "**Lorem** ipsum dolor sit"+ 
                                "amet, *consectetur* adipiscing elit. Sed"+ 
                                "eu est nec metus luctus tempus. Pellentesque"+ 
                                "at elementum sapien, ac faucibus sem"+
                                "![surprise](https://media.giphy.com/media/fdyZ3qI0GVZC0/giphy.gif)"
                }
            };
```

And then head back into our `HomeController.cs` and add `blogRepo.CreateExamplePosts();` back in right after `BlogRepo blogRepo = new BlogRepo();`, if you deleted it in the first place that is.

**IMPORTANT** Do not forget to delete your `Data/Blog.db` file before you run your application.

Now let's run our ASP.NET Blog application again and see what happens when we click read more on our newly created post.
If everything worked well you should now see a formatted post with a gif at the bottom of it.
Congratulations you enabled Markdown on your blog posts.

## Disclaimer
I'm aware this part was a little bit chaotic and all over the place and that we didn't actually add all that much to our application. However we'll be getting to the really fun part in our next tutorial. Namely adding a very simple and primitive backend to our blog where you'll be able to create new posts and manage existing posts.

If you have any questions feel free to contact me at [@arctekdev](https://twitter.com/arctekdev) on twitter.