ToActionResult(this) does not respect the custom result conventions
- 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
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