Options for Adding a Blog to an Existing .NET Web App

rogerjin12

Roger Jin

Posted on June 20, 2017

Options for Adding a Blog to an Existing .NET Web App

For more content like this, follow ButterCMS on Twitter and subscribe to our blog.

What do you do if you have an existing website or application and there’s a sudden requirement for advanced content management features like blogging? Tear it apart and rebuild it on a blogging platform like WordPress? Roll your own blog as an integral part of the existing site? Both of these solutions are quite a lot of work. Rebuilding an application around a specific platform is not a trivial exercise, and your application will be forever coupled to it. And building your own blogging system seems wasteful given that blogging is a problem that’s been solved many times over.

Ideally, you could take an existing blog platform and integrate it into your website with minimal changes to what you already have. To find a platform that fits this bill, we need to start with a checklist of basic requirements. Here are some things we need:

  • Separation of concerns: Say we have a web application with existing business logic that has nothing to do with blogging. We don’t want to add blogging functionality to the application itself–we want to keep its implementation separate, but seamlessly integrated from the user’s perspective.
  • Minimal developer effort: We don’t want to have to maintain separate versions of our view templates just to get the same look and feel across both application and blog pages.
  • Common blogging features: We might as well define what we mean by a blog–we need the ability to create blog posts and single pages, deal with multiple authors, and have a publishing workflow.

While we’re at it, we should also consider things that would be “nice to have”:

  • Granularity: It would be nice to be able to drive specific pieces of a page with the blog, rather than having an all-or-nothing approach where certain pages are controlled entirely by the blog and others must exist completely without its support. For example, we might have an existing app that has a landing/login page. It would be nice if we could display a list of recent posts in a sidebar without having to turn over control of the entire page to the blog platform.

  • Language agnostic: We’d prefer a one-size-fits-all solution–one where we don’t have to worry about maintaining two separate runtimes if the CMS happens to be written in a different language than our existing application.

  • Hosted: It would be ideal if we could avoid supporting the implementation of the blog altogether. If we truly want to keep it separate from our existing app, we’ll probably end up maintaining two separate bodies of code and two separate databases. A best-case scenario would be one where we could use a hosted solution but show the content and pages as if they were part of our own website. This would potentially also free us from having to worry about the multiple runtimes issue mentioned above.

For the purposes of our example, let’s say we have an existing web application written in .NET. What blogging platform would meet our requirements?

WordPress

It’s only natural to give serious consideration to WordPress, given its popularity and excellent community support. It certainly has the features we need for creating pages and blog posts. However, we quickly run into problems beyond that.

There are hosted instances of WordPress available, but it’s not obvious how we could smoothly integrate these into an existing site. If our site is at example.com, we could point blog.example.com to our hosted WordPress, but what if we don’t want to do that? That solution lacks flexibility. It also means we can forget about granularity.

If we want our blog to reside at example.com/blog, we would need to host it ourselves and route certain pages to WordPress. Again, this lacks granularity. There’s no easy way to pull a list of recent post titles from WordPress and plug it into, say, the Razor templates that our .NET app would likely be using. It also means we have to maintain our own WordPress code, database, and PHP runtime, as well as separate versions of our view templates written for WordPress/PHP.

DotNetNuke / SiteFinity

DotNetNuke is a popular .NET CMS that supports blogging through plugin modules. Using DNN or another .NET CMS like SiteFinity would immediately ease the problem of having to maintain separate technology stacks–but only because our example web application happens to be written in .NET. This is hardly a universal solution.

We also still need to maintain a separate database or include the CMS database tables in our existing schema.

Roll Your Own

It’s starting to feel like rolling our own blog platform, while a poor solution, is just as good as those previously mentioned. We could make it as granular as we wanted, pulling individual content fields or entire pages into our existing templates at will. And maybe we could architect our code in such a way as to cleanly separate the blog code from the existing application. But this is still a huge amount of effort and expense.

When thinking about building our own blog, it becomes apparent that what we really need is a blogging engine. We need the logic and administrative UI to manage content, but without the front end–it should be utterly unopinionated about routing, templating, and rendering pages. This would give us the tools to deal with content while giving us the flexibility to display and integrate it however we see fit.

Headless Content Management

Another word for a “blogging engine” the way we’ve envisioned it might be a headless blog or headless CMS. This is a CMS that has a backend but no frontend. Content is fetched through the engine’s API, but displaying it to the user is left entirely up to a developer. This is an architecture that has actually become popular recently due to its flexibility and unintrusive integration.

One such platform is ButterCMS. It’s a hosted solution with an administrative dashboard for editing blog posts, handling authoring workflows, internationalization, and more. The content created through this backend is exposed through a REST API that’s accessible through various client libraries written in multiple languages (including C#/.NET).

This might work. Let’s look at our requirements and see if it does what we need:

  • Separation of concerns: Because ButterCMS is hosted, the code, database, and maintenance are handled entirely by ButterCMS.
  • Minimal developer effort: Content is fetched by calling the REST API using string keys to identify pages and blog posts. In most cases, displaying a page is as simple as asking the API for the raw HTML content, placing it in a view template, and rendering it.
  • Common CMS features: Blog posts, custom pages, multiple authors, and publishing workflows are all supported.
  • Granularity: ButterCMS allows the creation of multiple types of content from entire pages to text fields to simple object and array structures.
  • Language agnostic: Official Ruby, JavaScript, Python, PHP, and .NET clients currently exist.
  • Hosted: ButterCMS is an entirely hosted solution. All you need is an account, an API key, and a client for your chosen language.

Fetching content through an API client and rendering it certainly sounds simple enough, but let’s try it out to make sure. We’ll implement a simple ASP.NET MVC controller in C# to render the appropriate blog post for a route.

Before we do that, we need a ButterCMS account. Once we’ve signed up and logged in, we can click on our name in the top-left corner of the dashboard. In the dropdown menu that appears, click “Settings” and go the the API tab. This will show our API Token. We need to pass this token to our API client, which passes it the the ButterCMS API on each request to identify us.

We also need some blog posts to render. Click “New Post” on the left sidebar menu. Write “My First Test Post” for the title and add some content (doesn’t matter what, we just need something to render), then click the “Publish” button at the top. Then do the same thing to add another post, but title it “My Second Test Post”.

Each of these posts has a unique human-readable identifier called a “slug”, which is automatically generated from the post title by default. The slugs for the two posts we just created are “my-first-test-post” and “my-second-test-post”, respectively. We’ll use these in our MVC controller to handle routing to the appropriate post.

In our MVC app, we’ll first need to install the ButterCMS NuGet package. This package contains the client that we’ll use to communicate with the API.

After installing the package, let’s make a new MVC controller that we’ll use to render blog posts:

using ButterCMS;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Net;

namespace MyApp.Controllers 
{
  public class BlogController : Controller 
  {
    private static string _apiToken = "{your_api_token}";

    private ButterCmsClient _client;

    public BlogController() 
    {
      _client = new ButterCMSClient(_apiToken);
    }
  }
}

This creates a new ButterCMS client that’s configured to fetch content from the ButterCMS account we just created. Now let’s create a simple route and fetch our post.

public class BlogController : Controller 
{
  /// ...

  [Route("blog/{slug}")]
  public async Task<ActionResult> ShowPost(string slug) 
  {
    var response = await Client.RetrievePostAsync(slug);
    ViewBag.Post = response.Data;
    return View("Post");
  }
}

This gets us the content for a blog post based on the slug that we passed in through the URL. So if we start our app and navigate to http://{my_app_host}/blog/my-first-test-post, we’ll fetch the content for the first post we wrote.

Obviously this is incomplete–we haven’t yet made a “Post” view template to render to. Let’s do that now:

<h2>@ViewBag.Post.Title</h2>

@Html.Raw(ViewBag.Post.Body)

This simply renders the post’s title and body content. We should always use @Html.Raw() to render the post content because ButterCMS uses HTML tags for formatting, either manually or using its built in WYSIWYG editor.

That’s it! Pretty simple. The API client has other methods for listing and paginating posts, fetching posts by author or category, etc., but they’re all as easy to use as the example above.

This was originally posted here.

💖 💪 🙅 🚩
rogerjin12
Roger Jin

Posted on June 20, 2017

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related