Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update TargetFramework to .NET 7 #112

Merged
merged 11 commits into from
Feb 23, 2023
2 changes: 1 addition & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.x'
dotnet-version: '7.x'
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-result-related.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: '7.x'
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-result.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: '7.x'
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
13 changes: 7 additions & 6 deletions Ardalis.Result.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.Sample.Core"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.FluentValidation", "src\Ardalis.Result.FluentValidation\Ardalis.Result.FluentValidation.csproj", "{43443B4B-2305-4CDF-A7A4-32A80ED1D19B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.AspNetCore.UnitTests", "tests\Ardalis.Result.AspNetCore.UnitTests\Ardalis.Result.AspNetCore.UnitTests.csproj", "{0BDA82F9-3602-4705-8DCD-A4724CAAF800}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.SampleMinimalApi", "sample\Ardalis.Result.SampleMinimalApi\Ardalis.Result.SampleMinimalApi.csproj", "{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.SampleMinimalApi.FunctionalTests", "sample\Ardalis.Result.SampleMinimalApi.FunctionalTests\Ardalis.Result.SampleMinimalApi.FunctionalTests.csproj", "{A9769533-C9B2-4AD4-8B24-70C474D8EBB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ardalis.Result.AspNetCore.UnitTests", "tests\Ardalis.Result.AspNetCore.UnitTests\Ardalis.Result.AspNetCore.UnitTests.csproj", "{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -69,10 +69,6 @@ Global
{43443B4B-2305-4CDF-A7A4-32A80ED1D19B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43443B4B-2305-4CDF-A7A4-32A80ED1D19B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43443B4B-2305-4CDF-A7A4-32A80ED1D19B}.Release|Any CPU.Build.0 = Release|Any CPU
{0BDA82F9-3602-4705-8DCD-A4724CAAF800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BDA82F9-3602-4705-8DCD-A4724CAAF800}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BDA82F9-3602-4705-8DCD-A4724CAAF800}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BDA82F9-3602-4705-8DCD-A4724CAAF800}.Release|Any CPU.Build.0 = Release|Any CPU
{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -81,6 +77,10 @@ Global
{A9769533-C9B2-4AD4-8B24-70C474D8EBB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9769533-C9B2-4AD4-8B24-70C474D8EBB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9769533-C9B2-4AD4-8B24-70C474D8EBB0}.Release|Any CPU.Build.0 = Release|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -96,6 +96,7 @@ Global
{43443B4B-2305-4CDF-A7A4-32A80ED1D19B} = {865A74CD-F478-4AA5-AFA5-6C26FB38B849}
{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5} = {FA061DC6-61B7-401F-87A4-D338B396CCD9}
{A9769533-C9B2-4AD4-8B24-70C474D8EBB0} = {FA061DC6-61B7-401F-87A4-D338B396CCD9}
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E} = {42693FB1-04E1-4635-B249-E1847609E801}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7CD0ED8C-3B1C-4F16-8B8D-3D8F1A8F1A5A}
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public async Task<ActionResult<CustomerDTO>>(int customerId)

Another approach is to return a `Tuple` of the expected result along with other things, like a status code and additional failure mode metadata. While tuples can be great for individual, flexible responses, they're not as good for having a single, standard, reusable approach to a problem.

The result pattern provides a standard, reusable way to return both success as well as multiple kinds of non-success responses from .NET services in a way that can easily be mapped to API response types. Although the [Ardalis.Result](https://www.nuget.org/packages/Ardalis.Result/) package has no dependencies on ASP.NET Core and can be used from any .NET Core application, the [Ardalis.Result.AspNetCore](https://www.nuget.org/packages/Ardalis.Result.AspNetCore/) companion package includes resources to enhance the use of this pattern within ASP.NET Core web API applications.
The Result pattern provides a standard, reusable way to return both success as well as multiple kinds of non-success responses from .NET services in a way that can easily be mapped to API response types. Although the [Ardalis.Result](https://www.nuget.org/packages/Ardalis.Result/) package has no dependencies on ASP.NET Core and can be used from any .NET Core application, the [Ardalis.Result.AspNetCore](https://www.nuget.org/packages/Ardalis.Result.AspNetCore/) companion package includes resources to enhance the use of this pattern within ASP.NET Core web API applications.

## Sample Usage

Expand Down Expand Up @@ -164,16 +164,16 @@ public ActionResult<WeatherForecastSummaryDto> CreateSummaryForecast([FromBody]
}
```

## Asp Net API Metadata
## ASP.NET API Metadata

By default, Asp Net Core and Api Explorer know nothing about `[TranslateResultToActionResult]` and what it is doing. To reflect `[TranslateResultToActionResult]` behavior in metadata generated by Api Explorer (which is then used by tools like Swashbuckle, NSwag etc.), you can use `ResultConvention`:
By default, Asp Net Core and API Explorer know nothing about `[TranslateResultToActionResult]` and what it is doing. To reflect `[TranslateResultToActionResult]` behavior in metadata generated by API Explorer (which is then used by tools like Swashbuckle, NSwag etc.), you can use `ResultConvention`:

```csharp
services.AddControllers(mvcOptions => mvcOptions.AddDefaultResultConvention());
```

This will add `[ProducesResponseType]` for every known `ResultStatus` to every endpoint marked with `[TranslateResultToActionResult]`.
To customize ResultConvention behavior, one may use `AddResultConvention` method:
To customize ResultConvention behavior, one may use the `AddResultConvention` method:

```csharp
services.AddControllers(mvcOptions => mvcOptions
Expand All @@ -182,9 +182,9 @@ services.AddControllers(mvcOptions => mvcOptions
));
```

This code is functionally equivalent to previous example.
This code is functionally equivalent to the previous example.

From here you can modify ResultStatus-to-HttpStatusCode mapping
From here you can modify the ResultStatus to HttpStatusCode mapping

```csharp
services.AddControllers(mvcOptions => mvcOptions
Expand All @@ -211,7 +211,7 @@ services.AddControllers(mvcOptions => mvcOptions
));
```

Alternatively, you can specify which (failure) result statuses are expected from certain endpoint:
Alternatively, you can specify which (failure) result statuses are expected from a certain endpoint:

```csharp
[TranslateResultToActionResult()]
Expand All @@ -223,9 +223,9 @@ public Result RemovePerson(int id)
}
```

`!!!` If you list certain result status in `ExpectedFailures`, it must be configured in `ResultConvention` on startup.
`!!!` If you list a certain Result status in `ExpectedFailures`, it must be configured in `ResultConvention` on startup.

Another configurability feature is what part of Result object is returned in case of specific failure:
Another configurable feature is what part of the Result object is returned in case of specific failure:

```csharp
services.AddControllers(mvcOptions => mvcOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<AssemblyName>Ardalis.Result.Sample.Core</AssemblyName>
<RootNamespace>Ardalis.Result.Sample.Core</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="6.0.13" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.13" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand All @@ -12,7 +12,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Ardalis.Result.AspNetCore\Ardalis.Result.AspNetCore.csproj">
<SetTargetFramework>TargetFramework=net6.0</SetTargetFramework>
<SetTargetFramework>TargetFramework=net7.0</SetTargetFramework>
</ProjectReference>
<ProjectReference Include="..\Ardalis.Result.Sample.Core\Ardalis.Result.Sample.Core.csproj" />
</ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions sample/Ardalis.Result.SampleMinimalApi/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<WeatherService>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.13" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

namespace Ardalis.Result.SampleWeb.FunctionalTests;

public class PersonControllerDelete : IClassFixture<WebApplicationFactory<Startup>>
public class PersonControllerDelete : IClassFixture<WebApplicationFactory<WebMarker>>
{
private const string MEDIATR_CONTROLLER_POST_ROUTE = "/mediatr/person/remove/{0}";
private const string CONTROLLER_POST_ROUTE = "/person/remove/{0}";
private const string ENDPOINT_POST_ROUTE = "/person/delete/{0}";

private readonly HttpClient _client;

public PersonControllerDelete(WebApplicationFactory<Startup> factory)
public PersonControllerDelete(WebApplicationFactory<WebMarker> factory)
{
_client = factory.CreateClient();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@

namespace Ardalis.Result.SampleWeb.FunctionalTests;

public class WeatherForecastControllerPost : IClassFixture<WebApplicationFactory<Startup>>
public class WeatherForecastControllerPost : IClassFixture<WebApplicationFactory<WebMarker>>
{
private const string CONTROLLER_POST_ROUTE = "/weatherforecast/create";
private const string ENDPOINT_POST_ROUTE = "/forecast/new";
private readonly HttpClient _client;

public WeatherForecastControllerPost(WebApplicationFactory<Startup> factory)
public WeatherForecastControllerPost(WebApplicationFactory<WebMarker> factory)
{
_client = factory.CreateClient();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Ardalis.ApiEndpoints" Version="4.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.11" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion sample/Ardalis.Result.SampleWeb/Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</p>
<p>WeatherForecast:</p>
<ul>
<li>PostalCode 55555 should work (200 OK)</li>
<li>PostalCode 55555 should work (201 Created)</li>
<li>PostalCode "" should fail (400 Bad Request with error list (required))</li>
<li>PostalCode "NotFound" should return (404 Not Found)</li>
<li>PostalCode "This is too long." should return (400 Bad Request with error list)</li>
Expand Down
77 changes: 64 additions & 13 deletions sample/Ardalis.Result.SampleWeb/Program.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,70 @@
using Ardalis.Result;
using Ardalis.Result.AspNetCore;
using Ardalis.Result.Sample.Core.Services;
using Ardalis.Result.SampleWeb.MediatrApi;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Globalization;
using System.Net;

namespace Ardalis.Result.SampleWeb;
var builder = WebApplication.CreateBuilder(args);

public class Program
var webAssembly = typeof(Program).Assembly;
builder.Services.AddMediatR(webAssembly);
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));

builder.Services.AddControllers(mvcOptions => mvcOptions
.AddResultConvention(resultStatusMap => resultStatusMap
.AddDefaultMap()
.For(ResultStatus.Ok, HttpStatusCode.OK, resultStatusOptions => resultStatusOptions
.For("POST", HttpStatusCode.Created)
.For("DELETE", HttpStatusCode.NoContent))
.Remove(ResultStatus.Forbidden)
.Remove(ResultStatus.Unauthorized)
));

builder.Services.AddRazorPages();
builder.Services.AddLocalization(opt => { opt.ResourcesPath = "Resources"; });
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("de-DE"),
};
options.DefaultRequestCulture = new RequestCulture("en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});

builder.Services.AddSwaggerGen();
builder.Services.AddTransient<PersonService>();
builder.Services.AddTransient<WeatherService>();
builder.Services.AddTransient<WeatherServiceWithExceptions>();

var app = builder.Build();

if (builder.Environment.IsDevelopment())
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseRouting();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"));

var options = app.Services.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);

app.MapControllers();
app.MapRazorPages();

app.Run();
Loading