ardalis / ardalis/Result

ToActionResult(this) does not respect the custom result conventions

Open
#239 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
1k
Forks
127
PR merge metrics
No merged PRs in 30d

Description

I have the following custom conventions configuration in my ASP.NET WebAPI project `Program.cs` file

```csharp
builder.Services
.AddControllers(mvcOptions => mvcOptions
.AddResultConvention(resultStatusMap => resultStatusMap
.AddDefaultMap()
.For(ResultStatus.Invalid,
HttpStatusCode.BadRequest,
resultStatusOptions => resultStatusOptions
.With((_, result) => ExtendedProblemDetailsResponse.FromResult(result))))).AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
opts.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
opts.JsonSerializerOptions.Converters.Add(new DateTimeOffsetConverter());
});
```

I have the following endpoint

```csharp
[HttpPut("{salesAgentId}")]
public async Task CreateProspect([FromRoute] Guid salesAgentId,
[FromBody] CreateProspectRequest request,
CancellationToken cancellationToken = default)
{
var result = await handler.CreateAsync(request.ToCommand(salesAgentId,
timeProvider.GetUtcNow()),
cancellationToken);

return result.ToActionResult(this);
}
```

My custom conventions return a special type of problem/details object called `ExtendedProblemDetailsResponse` when the result is invalid.

When I use the above endpoint, the custom conventions are not invoked.

When I change the endpoint to this

```csharp
[HttpPut("{salesAgentId}")]
[TranslateResultToActionResult]
public async Task CreateProspect([FromRoute] Guid salesAgentId,
[FromBody] CreateProspectRequest request,
CancellationToken cancellationToken = default)
{
var result = await handler.CreateAsync(request.ToCommand(salesAgentId,
timeProvider.GetUtcNow()),
cancellationToken);

return result;
}
```

The result custom conventions start working and I get the customized `ExtendedProblemDetailsResponse`. Notice that in this version I do not return `ActionResult` I return `Ardalis.Result` and I do not call the `ToActionResult(this)`.

There are 2 questions I have

1. Is this intended behavior?
2. If it is intended behavior, how can I customize what action result to return when I use the explicit `ToActionResult(this)` extension method instead of relying on the automatic conversion using the `TranslateResultToActionResult`.

Further, (this is probably a separate issue). When we use the automatic version where instead of returning `ActionResult` we return the `Ardalis.Result` certain filters and middleware stop working which rely on the fact that the controller returns `ActionResult`. So, I really would prefer using the manual version and be able to customize the returned action result. And if the library does not support that, I can roll my own version of the mapper will do what I need.

Contributor guide

Open the contributing guide

Research direction

Start with the ToActionResult(this) extension and compare its mapping path with the TranslateResultToActionResult attribute used by the automatic conversion. Trace how AddResultConvention and the custom ExtendedProblemDetailsResponse are applied in the Program.cs configuration, then verify whether explicit conversion can honor those conventions while still returning ActionResult. Done means the manual endpoint produces the customized response and the reported filters and middleware continue to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.