loading...
Turner Software

Building a flat website with ASP.NET Core

turnerj profile image James Turner ・4 min read

As of last night, I launched the website for BrandVantage, my product I am building. I'm pretty proud of the site, I designed and built it myself as well as designed the logo. This all happened in just over one week since I left my job too!

I touched on a little what BrandVantage was about in a comment but this, and various other posts coming soon, are to talk about development and technologies, not me trying to sell you on it. When I do launch on Product Hunt, I will probably post about that though! 🙂

This new site, as well as my personal site and my company's website (both also launched not too long ago) are all built very similarly: a single-page, flat HTML with minified CSS.

I like having a flat site like this as it is hosting agnostic. These sites I have built, while are ASP.NET Core projects in code, they are deployed to PHP hosting. The rest of this post explains that setup a little.

The Base Project

I'm using Visual Studio with each of these projects starting out the same, an empty ASP.NET Core website project.

Visual Studio Solution Structure

For getting the actual project working in development, you will need to update your Startup.cs to be something similar to below:

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }

        app.UseDefaultFiles(new DefaultFilesOptions
        {
            DefaultFileNames = new List<string> { "index.html" }
        });

        app.UseStaticFiles();
    }
}

You want to make sure you have UseStaticFiles and set your index file to be a default otherwise it won't work as you expect.

Site Root

Site Root
This setup really is taking it back to basics, I'm not using any special features of ASP.NET Core itself, there isn't some Razor template I am exporting to flat HTML. It really is just one index.html file that I've manually built.

I did look into trying to export a site from CSHTML into plain HTML but it seemed a little too complicated for a single page site. I might revisit this in the future but for now, a flat HTML page is perfect for me.

Bundling and Minification

My setup relies on the Nuget package BuildBundlerMinifier which allow the minification of CSS by just simply building the codebase as you would any other .NET codebase.

It uses a JSON file which for me looks like:

[
  {
    "outputFileName": "wwwroot/bundles/site.min.css",
    "inputFiles": [
      "wwwroot/css/normalize.css",
      "wwwroot/css/layout.css",
      "wwwroot/css/product-hunt.css",
      "wwwroot/css/responsive.css",
      "wwwroot/css/compatibility.css"
    ],
    "sourceMap": true
  },
  {
    "outputFileName": "wwwroot/fonts/font-awesome/bundles/fontawesome.min.css",
    "inputFiles": [
      "wwwroot/fonts/font-awesome/css/fontawesome.min.css",
      "wwwroot/fonts/font-awesome/css/light.min.css"
    ]
  }
]

The bundler/minifier does support JavaScript but I don't have any JS in my site besides Google Analytics and a Product Hunt script.

You can see in my site root screenshot that there is a bundles folder, that is created by this process however I have that excluded from Git.

Because my site is flat HTML, I do need to reference the bundled files directly which I do as shown here:

    <link href="/bundles/site.min.css" rel="stylesheet" />
</head>
<body>
    <link href="fonts/font-awesome/bundles/fontawesome.min.css" rel="stylesheet" />

The reason for one being in the head and one being in the body is slightly increasing the perception of a faster page load.

One downside to this entire flat HTML method is that these bundled files aren't regenerated on the fly. This means I need to build again every time I want to view a CSS change. For major works, I might manually revert back to non-minified CSS just to make development easier. Ideally though, you would have it auto-generate on modification - this is something that many other tools provide but I don't (yet) have in my setup.

If I were to use CSHTML, I could actually reference both and use tag helpers to define what environment I am running in. Again, something I might consider for the future.

Continuous Delivery

You might have noticed in that first screenshot there is a cheeky build-pipeline.yml file, this is used by Azure DevOps Pipelines to allow me to automate my build and deployment setup.

My file looks like this:

resources:
- repo: self
queue:
  name: Hosted VS2017

steps:
- task: DotNetCoreInstaller@0
  inputs:
    version: '2.2.101'

- task: DotNetCoreCLI@2
  displayName: 'dotnet build'

- task: ArchiveFiles@2
  displayName: 'Archive src/Website/wwwroot'
  inputs:
    rootFolderOrFile: src/Website/wwwroot
    includeRootFolder: false
    archiveType: 7z
    archiveFile: '$(Build.ArtifactStagingDirectory)/website.7z'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: Web'
  inputs:
    ArtifactName: Web

I'm no expert on Azure DevOps Pipelines but the above is what I have working for me. First it installs a specific version of .NET Core, just so I have a stable and consistent environment (as .NET Core is already installed). I then run a build which really is just running the minification process. The next two tasks are required for getting the data to package up the build for the deployment pipeline.

At the time of making this setup, Azure didn't support a full YML config for the deployment side of the pipeline so I can't show that to you. The short version of what it does is:

  • Waits for a new build package coming from the master branch (allowing me to use other branches for dev without fear of deploying them)
  • Unpacks the artifact
  • Using FTPS, deploys all the changes to my hosting

Conclusion

Maybe not the greatest or most productive setup but one that works pretty well for me. What I can strongly say though is how much I love automated deployments - that stuff is amazing!

Discussion

pic
Editor guide
Collapse
krishnansriram profile image
Krishnan Sriram

Landing page is fantastic. I've been building solutions with React, Node & Golang for web. I see you took 1 to 2 weeks for development, which is around the same time I'd take to build it with React/Angular app. May be I should start putting sometime on ASP.NET core web app. I'm impressed with .NET core web API. In the process of moving some of my NodeJS into .NET core for type safety and easy of code sharing. Thanks for the article. Any idea on where/how to get started with ASP.NET core web app?

Collapse
turnerj profile image
James Turner Author

Thanks! Since writing this post, I've actually moved from a flat/static website to a full ASP.NET Core site running Razor Pages but the UI is basically the same as I originally had it.

The more people working on .NET the better in my opinion - I think it is a great platform to build on with lots of resources available.

Microsoft has an extremely short walk through of getting the basics up an running: docs.microsoft.com/en-us/aspnet/co...
It uses Razor Pages (my preferred technology for ASP.NET Core sites compared to more traditional MVC). There is a great site for Razor Pages information which I've referenced a lot in working on Razor Pages: learnrazorpages.com/
Further tutorials for Razor Pages here: docs.microsoft.com/en-us/aspnet/co...

Once you want to start dabbling in more custom configuration of the site, the series of docs here would help: docs.microsoft.com/en-us/aspnet/co...

Finally, the same site has docs about database access and security/authentication. With that, you'll have a solid foundation in ASP.NET Core.

Collapse
krishnansriram profile image
Krishnan Sriram

Would you not go Blazor route, as opposed to Razor. From the little I read, Blazor includes Razor, but has more too. Any thoughts?

Thread Thread
turnerj profile image
James Turner Author

Blazor is a very interesting technology though personally, I'm not yet moving towards it. My ideal scenario with something like Blazor is having it do client-side validation where I'd normally have JavaScript and have normal Razor Pages behind it. (Basically for me, I don't want Blazor per-se but I want client-side C#)

Currently with Blazor, it seems the idea isn't to gel with Razor Pages but be its own thing. There is a server-side component and a client-side component (WASM). The server-side one seems strange to me (to be honest) but is currently available for use. The client-side one is still under development as far as I know.

I'd say it is definitely worth knowing more about and keeping an eye on. If you like working on cutting edge, definitely mess around with it.

EDIT: To clarify something - so Blazor uses Razor but itself is its own thing. Razor is the syntax. When I say Razor Pages, that is its own thing that also uses Razor syntax.

Collapse
eekayonline profile image
Edwin Klesman

Nice read and interesting setup. Going to check this out for myself. I'm more into product development and simple pages I click together with services like carrd.co but I like this. For fast performing websites that need fast loading this is very nice 🙌🏻👌🏻

Collapse
benjiboy13 profile image
Benjamin Gil Flores

I must say you have pretty nice looking landing pages there, congrats on that!, putting that aside it looks very interesting the way you create your projects, you intrigue me to investigate more about the ASP.NET Core and trust me if i had time i would start learning that but as it right know i have a couple of important projects in development with REACT Js that i need to finish.

Collapse
turnerj profile image
James Turner Author

It is a bit like that isn't it - finding time to do all the different things we want to do. Glad you found this interesting 🙂

Collapse
jacksonelfers profile image
Jackson Elfers

Really well designed page. When I'm dealing with static sites I put them in S3 buckets, or on github pages.

Collapse
turnerj profile image
James Turner Author

Thanks! I'm really happy with how it turned out 🙂

Github was the first direction I was going to go for my personal sites but I changed my mind when I was looking at solutions for my business. My product code use to be hosted on Bitbucket but was to be deployed to Azure. Azure DevOps seemed like the best solution in terms of integration between my code and Azure.

Rather than maintain two separate processes for managing my personal site, my company site and my product's site, I decided to just roll it all the exact same way.