BaseController

Part 01 - Setup BaseController, ExceptionController and generic plumbing.

Following are a few concepts that I would implement when I start developing a new ASP.NET website. But, of course, these are my preferences, and alternative approaches could exist.

BaseController
After generating the ASP.NET website solution, the first step is to create a BaseController, which is the base controller from which all controllers will inherit.

ExceptionController
The next step is to create an ExceptionController to process the global error handling. I am moving this global error handler to an independent controller class to respect the Single Responsibility Principle (SRP) of the Object Oriented Principals (SOLID).

ErroVM
Rename the ErrorViewModel to ErrorVM to implement a standard naming convention. Eventually, we will move this ErrorVM to an external library (BPX.Domain) and delete the Models folder. All models (dbModels, viewModels, erroModel, and filterModels) will be in the new external domain library.

Global Exception Handling
Modify the error-handling middleware in Program.cs to point to the new Global Exception Handler (ExceptionController) all the time.

BaseController
using Microsoft.AspNetCore.Mvc;

namespace BPX.Website.Controllers
{
    public class BaseController<T> : Controller where T : class
    {
        protected readonly ILogger<T> logger;

        public BaseController(ILogger<T> logger)
        {
            this.logger = logger;
        }
    }
}

Notes:
Logger is moved to BaseController to allow all inheriting controllers to have access to the logger.

ExceptionController
using BPX.Website.Models;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;

namespace BPX.Website.Controllers
{
    public class ExceptionController : BaseController<ExceptionController>
    {
        public ExceptionController(ILogger<ExceptionController> logger) : base(logger)
        {
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Index()
        {
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Notes:
none.

HomeController
using Microsoft.AspNetCore.Mvc;

namespace BPX.Website.Controllers
{
    public class HomeController : BaseController<HomeController>
    {
        public HomeController(ILogger<HomeController> logger) : base(logger)
        {
        }

        public IActionResult Index()
        {
            return View();
        }
    }
}

Notes:
none.

ErrorVM
namespace BPX.Website.Models
{
    public class ErrorVM
    {
        public string? RequestId { get; set; }

        public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    }
}

Notes:
Rename class ErrorViewModel to class ErroVM.

Exception - Index
@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

Notes:
none.

_PartialValidationScripts.cshtml
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

Notes:
_ValidationScriptsPartial.cshtml is renamed to _PartialValidationScripts.cshtml

Error.cshtml
@model ErrorVM
@{
    ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>Development Mode</h3>
<p>
    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
    It can result in displaying sensitive information from exceptions to end users.
    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
    and restarting the app.
</p>

Notes:
@model ErrorViewModel changed to @model ErrorVM

Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseExceptionHandler("/Exception/Error");

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

Notes:
none.



 



Ginger CMS
the future of cms, a simple and intuitive content management system ...

ASP.NET MVC Application
best practices like Repository, LINQ, Dapper, Domain objects ...

CFTurbine
cf prototyping engine, generates boilerplate code and views ...

Search Engine LITE
create your own custom search engine for your web site ...

JRun monitor
monitors the memory footprint of JRun engine and auto-restarts a hung engine ...

Validation Library
complete validation library for your web forms ...