Danom.Mvc 2.1.0

dotnet add package Danom.Mvc --version 2.1.0
                    
NuGet\Install-Package Danom.Mvc -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Danom.Mvc" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Danom.Mvc" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Danom.Mvc" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Danom.Mvc --version 2.1.0
                    
#r "nuget: Danom.Mvc, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Danom.Mvc@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Danom.Mvc&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Danom.Mvc&version=2.1.0
                    
Install as a Cake Tool

Danom.Mvc

NuGet Version build

Danom.Mvc is a library that provides a set of utilities to help integrate the Danom library with common tasks in ASP.NET Core MVC and Razor Pages applications.

Key Features

  • Render views based on the presence of Option and Result types.
  • Inject ResultErrors into the model state for easy error reporting.

Design Goals

  • Make it easy to work with Option and Result types in ASP.NET MVC applications.
  • Provide sensible defaults while allowing customization.
  • Integrate seamlessly with existing ASP.NET Core MVC and Razor Pages patterns.

Getting Started

Install the Danom.Mvc NuGet package:

PM>  Install-Package Danom.Mvc

Or using the dotnet CLI

dotnet add package Danom.Mvc

MVC

The DanomController class extends the base controller class to provide a set of methods to help work with Result and Option types in ASP.NET Core MVC applications. These methods can also be accessed via extension methods on the Controller class.

Option

The ViewOption method is used to render a view based on the presence of an Option value.

If the Option is Some, the view is rendered with the value. If the Option is None, the noneAction is invoked. By default, the noneAction returns a NotFound result.

A custom view name can be provided to render a view with a different name than the action.

Some examples demonstrating the use of ViewOption are shown below:

using Danom.Mvc;
using Microsoft.AspNetCore.Mvc;

public sealed class OptionController : DanomController {
    public IActionResult OptionSome() =>
        ViewOption(
            option: Option.Some("Hello world"),
            viewName: "Detail");

    // Returns the ASP.NET default `NotFound` result
    public IActionResult OptionNone() =>
        ViewOption(
            option: Option<string>.NoneValue,
            viewName: "Detail");

    public IActionResult OptionNoneCustom() =>
        ViewOption(
            option: Option<string>.NoneValue,
            viewName: "Detail",
            noneAction: () => NotFound("Not found!"));
}

// or, using extension methods
public sealed class OptionController : Controller {
    public IActionResult OptionSome() =>
        this.ViewOption(
            option: Option.Some("Hello world"),
            viewName: "Detail");

    // Returns the ASP.NET default `NotFound` result
    public IActionResult OptionNone() =>
        this.ViewOption(
            option: Option<string>.NoneValue,
            viewName: "Detail");

    public IActionResult OptionNoneCustom() =>
        this.ViewOption(
            option: Option<string>.NoneValue,
            viewName: "Detail",
            noneAction: () => NotFound("Not found!"));
}

Result

The ViewResult method is used to render a view based on the presence of a Result value.

By default the ViewResult method will render the view with the value if the Result is Ok. If the Result is Error, the errorAction is invoked.

A custom view name can be provided to render a view with a different name than the action.

using Danom.Mvc;
using Microsoft.AspNetCore.Mvc;

public sealed class ResultController : DanomController {
    public IActionResult ResultOk() =>
        ViewResult(
            result: Result<string, string>.Ok("Success!"),
            viewName: "Detail");

    public IActionResult ResultError() =>
        ViewResult(
            result: Result<string, string>.Error("An error occurred."),
            errorAction: errors => View("Detail", errors),
            viewName: "Detail");
}

// or, using extension methods
public sealed class ResultController : Controller {
    public IActionResult ResultOk() =>
        this.ViewResult(
            result: Result<string, string>.Ok("Success!"),
            viewName: "Detail");

    public IActionResult ResultError() =>
        this.ViewResult(
            result: Result<string, string>.Error("An error occurred."),
            errorAction: errors => View("Detail", errors),
            viewName: "Detail");
}

Built into Danom is the ResultErrors type, which is particularly well suited for reporting model errors in ASP.NET Core MVC applications. The ViewResultErrors method, provided by the DanomController class, is a proxy for the View method that will inject the ResultErrors value into the model state.

When using ResultErrors as the error type, the ViewResultErrors will default the errorAction to inject the ResultErrors value into the model state.

using Danom.Mvc;
using Microsoft.AspNetCore.Mvc;

public sealed class ResultController : DanomController {
    public IActionResult ResultOk() =>
        ViewResult(
            // notice the lack of second type parameter, which is inferred to be ResultErrors
            result: Result<string>.Ok("Success!"),
            viewName: "Detail");

    public IActionResult ResultError() =>
        ViewResult(
            result: Result<string>.Error("An error occurred."),
            viewName: "Detail");


    public IActionResult ResultErrorView() =>
        // can be used directly
        ViewResultErrors(
            errors: new("An error occurred."));
}

// or, using extension methods
public sealed class ResultController : Controller {
    public IActionResult ResultOk() =>
        this.ViewResult(
            // notice the lack of second type parameter, which is inferred to be ResultErrors
            result: Result<string>.Ok("Success!"),
            viewName: "Detail");

    public IActionResult ResultError() =>
        this.ViewResult(
            result: Result<string>.Error("An error occurred."),
            viewName: "Detail");

    public IActionResult ResultErrorView() =>
        // can be used directly
        this.ViewResultErrors(
            errors: new("An error occurred."));
}

View

While not explicitly part of the Danom.Mvc library, there are some patterns that make rendering the Option type easier in Razor views. Two methods from the base library are especially valuable: TryGet and ToString.

The TryGet method is used to extract the value from an Option type. If the Option is Some, the value is assigned to the out parameter and the method returns true. If the Option is None, the method returns false.

The custom ToString method is used to convert the Option value to a string. If the Option is Some, the value is converted to a string. If the Option is None, the method returns the default value. The method optionally accepts a second parameter for the format string.

Consider the following type:

public record Person(
    string Name,
    Option<DateOnly> Birthdate,
    Option<string> Email);

The TryGet and ToString methods can be used in a Razor view to help render the optional properties.

@model Person

<h1>@Model.Name</h1>
<h2>Email: <i>@Model.Email.ToString("-")</i></h2>

@if (Model.Birthdate.TryGet(out var birthdate))
{
    var now = DateTime.Now;
    var a = (now.Year * 100 + now.Month) * 100 + now.Day;
    var b = (birthdate.Year * 100 + birthdate.Month) * 100 + birthdate.Day;
    var age = (a - b) / 10000;

    <p>You are born on @birthdate, and are @age years old.</p>
}
else
{
    <p>You are an ageless wonder!</p>
}

Razor Pages

The DanomPageModel class extends the base page model class to provide method(s) to help work with Result and Option types in ASP.NET Core Razor Pages applications.

using Danom.Mvc;

public sealed class IndexModel : DanomPageModel {
    public void OnGet() {
        var resultWithErrors = Result<string, string>.Error("An error occurred.");
        if(resultWithErrors.TryGetError(out var e)) {
            return Page(e);
        }
    }
}

Contributing

I kindly ask that before submitting a pull request, you first submit an issue.

If functionality is added to the API, or changed, please kindly update the relevant documentation. Unit tests must also be added and/or updated before a pull request can be successfully merged.

Only pull requests which pass all build checks and comply with the general coding standard can be approved.

Find a bug?

There's an issue for that.

License

Licensed under MIT.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 84 1/5/2026
2.0.0 331 9/17/2025
2.0.0-beta4 200 6/24/2025
2.0.0-beta2 249 5/16/2025
1.2.0 184 12/6/2024
1.0.0 160 11/20/2024
1.0.0-beta1 141 10/11/2024
1.0.0-alpha1 144 8/30/2024