Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="System.Runtime" Version="4.3.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="System.Text.Json" Version="8.0.6" />
<PackageVersion Include="xunit" Version="2.4.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
</ItemGroup>
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,44 @@ public ActionResult<WeatherForecastSummaryDto> CreateSummaryForecast([FromBody]
}
```

### Chaining Result Operations with Bind and BindAsync

You can chain together multiple operations that return `Result<T>` using the `Bind` and `BindAsync` methods. This allows you to perform a sequence of operations where each operation can fail, and if any operation fails, the subsequent operations will not be executed. This can be useful for eliminating checking for success after each Result operation with a more readable and maintainable chain of operations.

```csharp
[HttpPost("Summary")]
public async Task<ActionResult<WeatherForecastSummaryDto>> CreateSummaryForecast([FromBody] ForecastRequestDto model)
{
var result1 = await _weatherService.GetSingleForecast(model);

if (!result1.IsSuccess)
{
return result1.ToActionResult(this);
}

var result2 = await _weatherService.GetForecastDetailsAsync(result1.Value.Id);

return result2
.Map(details => new WeatherForecastSummaryDto(details.Date, details.Summary))
.ToActionResult(this);
}
```

With the `Bind` and `BindAsync` methods, you can simplify this code by chaining the operations together. The following example demonstrates how to use `BindAsync` to achieve the same result in a more concise manner:

```csharp
[HttpPost("BindedForecast")]
public async Task<ActionResult<WeatherForecastSummaryDto>> CreateSummaryForecastWithBind([FromBody] ForecastRequestDto model)
{
return await _weatherService.GetSingleForecast(model)
.BindAsync(wf => _weatherService.GetForecastDetailsAsync(wf.Id))
.Map(details => new WeatherForecastSummaryDto(details.Date, details.Summary))
.ToActionResult(this);
}
```

In this example, if `GetSingleForecast` returns a failure result, `GetForecastDetailsAsync` will not be called, and the failure will propagate through the chain. If all operations succeed, the final result will be mapped to a `WeatherForecastSummaryDto` and returned as an `ActionResult`.

## 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`:
Expand Down
Loading