How to Build Simple ASP.NET Core Website – Windows ASP.NET Core Hosting 2023 | Review and Comparison

This is simple tutorial how to build simple ASP.NET Core and upload it to hosting server. FYI, I have tested to build .net Core site on ASPHostPortal hosting If you want to host .NET site, you can always rely on this provider. See also ASPHostPortal reviews on our blog. Let’s get started!

The Base Project

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

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.UseDefaultFiles(new DefaultFilesOptions
            DefaultFileNames = new List<string> { "index.html" }


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

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": [
    "sourceMap": true
    "outputFileName": "wwwroot/fonts/font-awesome/bundles/fontawesome.min.css",
    "inputFiles": [

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" />
    <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:

- repo: self
  name: Hosted VS2017

- task: DotNetCoreInstaller@0
    version: '2.2.101'

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

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

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

I’m not too expert in ASP.NET Core 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.


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!