Alyio.AspNetCore.ApiMessages 7.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Alyio.AspNetCore.ApiMessages --version 7.1.0
NuGet\Install-Package Alyio.AspNetCore.ApiMessages -Version 7.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="Alyio.AspNetCore.ApiMessages" Version="7.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Alyio.AspNetCore.ApiMessages --version 7.1.0
#r "nuget: Alyio.AspNetCore.ApiMessages, 7.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.
// Install Alyio.AspNetCore.ApiMessages as a Cake Addin
#addin nuget:?package=Alyio.AspNetCore.ApiMessages&version=7.1.0

// Install Alyio.AspNetCore.ApiMessages as a Cake Tool
#tool nuget:?package=Alyio.AspNetCore.ApiMessages&version=7.1.0

Alyio.AspNetCore.ApiMessages

Build Status

The Alyio.AspNetCore.ApiMessages provides the mechanism to process unhandled exception occured during a HTTP context and writes machine-readable format for specifying errors in HTTP API responses based on https://tools.ietf.org/html/rfc7807.

You can throw any exception during a HTTP context if you want, and if the IApiMessage has been implemented by the exception, Alyio.AspNetCore.ApiMessages will produce a consistent response corresponding to it.

For 201 Created message,

[HttpPost]
public async Task<CreatedMessage> PostWeatherForecastAsync([FromBody] WeatherForecast weather)
{
    if (!ModelState.IsValid)
    {
        throw new BadRequestMessage(ModelState);
    }

    _ = _context.WeatherForecasts ?? throw new InternalServerErrorMessage("Entity set 'WeatherForecastDbContext.WeatherForecasts'  is null.");

    await _context.WeatherForecasts.AddAsync(weather);
    await _context.SaveChangesAsync();

    return this.CreatedMessageAtAction(nameof(GetWeatherForecastAsync), new { id = weather.Id }, weather.Id.ToString())!;
}
dotnet add package Alyio.AspNetCore.ApiMessages --version 7.0.3

To use Alyio.AspNetCore.ApiMessage, just call app.UseApiMessageHandler in Startup.Configure as below.

// . . .

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.Configure<ApiBehaviorOptions>(opt =>
{
    opt.InvalidModelStateResponseFactory = ctx =>
    {
        // Handle the default 404 response when the routing path is not found.
        ctx.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return new JsonResult(new BadRequestMessage(ctx.ModelState).ApiMessage);
    };
});

// . . .

var app = builder.Build();

//if (app.Environment.IsDevelopment())
//{
//    app.UseDeveloperExceptionPage();
//}
//else
//{
app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ExceptionHandler.WriteUnhandledMessageAsync });
app.UseApiMessageHandler();
//}

// . . .

app.Run();

You can also run the sample at test/Samples/WebApiMessages.Samples/:

$ dotnet run
Building...
. . .
info: Microsoft.EntityFrameworkCore.Update[30100]
      Saved 10 entities to in-memory store.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
. . .

And open another terminal, run httprepl:

To install the HttpRepl, run the following command:

dotnet tool install -g Microsoft.dotnet-httprepl

$ httprepl http://localhost:5000
(Disconnected)> connect http://localhost:5000
Using a base address of http://localhost:5000/
Using OpenAPI description at http://localhost:5000/swagger/v1/swagger.json
For detailed tool info, see https://aka.ms/http-repl-doc

http://localhost:5000/> ls
.                              []
oops                           [GET]
weather-forecast               [GET|POST]
weather-forecast-api-message   [GET|POST]

http://localhost:5000/> cd weather-forecast-api-message
/weather-forecast-api-message    [GET|POST]

http://localhost:5000/weather-forecast-api-message> get 20
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Content-Type: application/problem+json; charset=utf-8
Date: Fri, 20 Oct 2023 08:32:54 GMT
Expires: -1
Pragma: no-cache
Server: Kestrel
Transfer-Encoding: chunked

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "status": 404,
  "traceId": "00-2f8215f70a0e65011f461b61e333eab6-756e7aa8687a62ed-00"
}


http://localhost:5000/weather-forecast-api-message> post -c "{}"
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json; charset=utf-8
Date: Fri, 20 Oct 2023 08:38:04 GMT
Server: Kestrel
Transfer-Encoding: chunked

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-deca013d94134a78fc7c8aec27cf2d9d-b89466a9c2762913-00",
  "errors": {
    "Summary": [
      "The Summary field is required."
    ]
  }
}


http://localhost:5000/weather-forecast-api-message> post -c "{"summary": "coooool"}"
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Date: Fri, 20 Oct 2023 08:38:20 GMT
Location: /weather-forecast-api-message/11
Server: Kestrel
Transfer-Encoding: chunked

{
  "id": "11",
  "links": [
    {
      "href": "/weather-forecast-api-message/11",
      "rel": "self"
    }
  ]
}


http://localhost:5000/weather-forecast-api-message> get 11
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Fri, 20 Oct 2023 08:38:24 GMT
Server: Kestrel
Transfer-Encoding: chunked

{
  "id": 11,
  "date": null,
  "temperatureC": 0,
  "temperatureF": 32,
  "summary": "coooool"
}


http://localhost:5000/weather-forecast-api-message> delete 12
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Content-Type: application/problem+json; charset=utf-8
Date: Fri, 20 Oct 2023 08:38:36 GMT
Expires: -1
Pragma: no-cache
Server: Kestrel
Transfer-Encoding: chunked

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "status": 404,
  "traceId": "00-11152ee19a3b49a891e2a57cd860e8f2-8f806729dd06c2d8-00"
}

http://localhost:5000/weather-forecast-api-message> exit
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
8.0.0 564 11/24/2023
7.2.0 567 10/24/2023
7.1.0 493 10/20/2023
7.0.3 993 6/8/2022
7.0.1 937 6/4/2022
2.1.0 2,065 11/10/2018
2.0.2 2,740 1/11/2018
2.0.0 1,910 8/22/2017
1.1.3 1,781 8/11/2017
1.1.2 1,786 8/4/2017
1.1.1 1,750 7/18/2017
1.1.0 1,660 6/16/2017
1.0.6 1,658 5/5/2017
1.0.5 1,631 5/4/2017
1.0.4 1,784 4/11/2017
1.0.2 2,212 12/26/2016
1.0.1 2,078 12/19/2016

Trim the 'Async' suffix of action name for async methods.