Parsing markdown file and display in a razor view using asp.net core

3 minute read

Application overview Markdown has been huge popular for documentation and blog post. How to parse a markdown file and display in a razor view as blog post will be shown in this application. Let’s have a look on the implementation of the project.

Tools and Technology used The following tools and technologies has been used for this application

  • Visual Studio 2019
  • Visual C#
  • NuGet package “Westwind.AspNetCore.Markdown”
  • ASP.NET Core MVC
  • Razor view engine

Step1: Select ASP.NET Core Web Application
Select File->New->Project->ASP.NET Core Web Application

Step2: Choose project and solution name
Type project and solution name as “MarkdownBlog”

Step 3: Select project template

  • Select project template as Web Application (Model-View-Controller)
  • Click create button

Step 4: Install Nuget package “Westwind.AspNetCore.Markdown”
Run the following command in package manager console

PM> Install-Package Westwind.AspNetCore.Markdown

Step 5: Set up the markdown middleware
Once the Nuget package is installed, you can configure the middleware. Modify “ConfigureServices” and “Configure” Method as follows. Here, AddMarkdown() is used to configure the page processing. UseMarkdown() is used to hook up the middleware.

Startup.cs

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMarkdown(config =>
            {
                // optional Tag BlackList
                config.HtmlTagBlackList = "script|iframe|object|embed|form"; // default

                // Simplest: Use all default settings
                var folderConfig = config.AddMarkdownProcessingFolder("/docs/", "~/Pages/__MarkdownPageTemplate.cshtml");

                // Customized Configuration: Set FolderConfiguration options
                folderConfig = config.AddMarkdownProcessingFolder("/posts/", "~/Pages/__MarkdownPageTemplate.cshtml");

                // Optionally strip script/iframe/form/object/embed tags ++
                folderConfig.SanitizeHtml = false;  //  default

                // Optional configuration settings
                folderConfig.ProcessExtensionlessUrls = true;  // default
                folderConfig.ProcessMdFiles = true; // default

                // Optional pre-processing - with filled model
                folderConfig.PreProcess = (model, controller) =>
                {
                    // controller.ViewBag.Model = new MyCustomModel();
                };

                // folderConfig.BasePath = "https://github.com/RickStrahl/Westwind.AspNetCore.Markdow/raw/master";

                // Create your own IMarkdownParserFactory and IMarkdownParser implementation
                // to replace the default Markdown Processing
                //config.MarkdownParserFactory = new CustomMarkdownParserFactory();                 

                // optional custom MarkdigPipeline (using MarkDig; for extension methods)
                config.ConfigureMarkdigPipeline = builder =>
                {
                    builder.UseEmphasisExtras(Markdig.Extensions.EmphasisExtras.EmphasisExtraOptions.Default)
                        .UsePipeTables()
                        .UseGridTables()
                        .UseAutoIdentifiers(AutoIdentifierOptions.GitHub) // Headers get id="name" 
                        .UseAutoLinks() // URLs are parsed into anchors
                        .UseAbbreviations()
                        .UseYamlFrontMatter()
                        .UseEmojiAndSmiley(true)
                        .UseListExtras()
                        .UseFigures()
                        .UseTaskLists()
                        .UseCustomContainers()
                        //.DisableHtml()   // renders HTML tags as text including script
                        .UseGenericAttributes();
                };
            });

            services.AddControllersWithViews()
                 .AddApplicationPart(typeof(MarkdownPageProcessorMiddleware).Assembly);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            
            //For markdown
            app.UseMarkdown();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Step 6: Create a Markdown Container Razor Page
Create __MarkdownPageTemplate.cshtml in Pages folder as follows

@model Westwind.AspNetCore.Markdown.MarkdownModel
@{
    ViewBag.Title = Model.Title;
    Layout = "_Layout";
}

<div>
    @Model.RenderedMarkdown
</div>

Step 7: Now drop a markdown file in /wwwroot/
Here I have dropped MyArticle.md in /wwwroot/posts/2020/12/01/ folder. You can organize directory by yourself.

MyArticle.md

## Batting changes not yet bearing fruit
The buzzword in the Bangladesh camp before returning to international cricket after over 10 
months with the ODI series against the West Indies was long-term planning keeping the 2023 
ICC World Cup in mind.

The team management did try some tactical changes such as promoting young left-hander Nazmul 
Hossain Shanto to number three in place of Shakib Al Hasan, who had made the position his own 
during the 2019 ICC World Cup.

![Bangladesh Test Captain](image01.jpg)


Step 8: Build and run the application

Now the application is ready to run. Build and run the application. Now type the “https://localhost:yourport/posts/2020/12/01/markdownarticle” and watch the html output which you is writtern in the markdown tag. You can browse as https://localhost:44338/posts/2020/12/01/MyArticle.md to see output as github flavour.

Source Code