Open khandelwal-arpit opened 3 years ago
Good question; will need to review.
Hello Steve,
I am facing the same issue. Any news about the development of this feature ?
Aurélien
This may not be the most elegant solution but given you have a StoryDto, could you create a PagedStoryDto (or whatever name) and use the Map
method to combine StoryDto + PagedInfo into a single object that would get returned. Something like this:
return Result<IEnumerable<StoryDto>>.Success(pagedStoryDtos)
.ToPagedResult(pagedInfo)
.Map(r => new PagedStoryDto
{
StoryProperty = r.StoryProperty,
PageNumber = r.PagedInfo.PageNumber,
... // other properties
};
We might be able to add an overload of Map
for paged results that does this out of the box in a future update. đŸ¤”
I did something a little bit more complex : I have overriden the TranslateResultToActionResultAttribute
to deal with the paged results.
public class AdvancedTranslateResultToActionResultAttribute : TranslateResultToActionResultAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
if ((context.Result as ObjectResult)?.Value is not IResult result) return;
if (context.Controller is not ControllerBase controller) return;
base.OnActionExecuted(context);
if (result.Status is not ResultStatus.Ok) return;
var type = result.GetType();
var ardalisPagedResultType = typeof(PagedResult<>);
if (type.Namespace != ardalisPagedResultType.Namespace
|| type.Name != ardalisPagedResultType.Name)
{
return;
}
if (!result.ValueType.IsAssignableTo(typeof(IEnumerable<object>))) return;
var pagedInfoProperty = type.GetProperty(nameof(PagedInfo));
if (pagedInfoProperty?.GetValue(result) is not PagedInfo pagedInfoValue) return;
var pagedResultType = typeof(Contracts.Core.PagedResult<>);
var itemType = result.ValueType.GetGenericArguments()[0];
var constructed = pagedResultType.MakeGenericType(itemType);
var pagedInfo = Contracts.Core.PagedInfo.FromArdalisPagedInfo(pagedInfoValue);
context.Result = controller.StatusCode(
context.HttpContext.Response.StatusCode,
Activator.CreateInstance(constructed, pagedInfo, result.GetValue()));
}
}
As you can see, I use reflection to Map Ardalis PagedResult and PagedInfo to my own equivalent classes Contracts.Core.Paged*
With this approach, I obtain a generic solution for all my controllers and paged models.
While using TranslateResultToActionResult to return responses in the form of ActionResults, there is no way for the caller to know the details of the pagination.
The reason is because the ToActionResult method in the ResultExtensions class just cares about the "result.GetValue()" and ignores the Pagination details which were fed by the upstream services as shown below:
return Result<IEnumerable<StoryDto>>.Success(pagedStoryDtos).ToPagedResult(pagedInfo);
Is there a way we can modify this behavior so that the caller can see the pagination details too?