У меня есть следующий сценарий:
Я хочу создать пользовательский фильтр результатов, который позволяет мне добавлять заголовок разбиения на страницы в ответ, используя дочерний класс ResultFilterAttribute .Чтобы создать метаданные пагинации, используемые в заголовке, я создал вспомогательный сервис пагинации, который вводится в класс контроллера и нуждается в объекте PagingModel для генерации метаданных.
Чтобы добавить метаданные разбиения на страницы к ответу в фильтре, мне понадобится доступ как к pagingMetadata, так и к фактическому значению (entity, dto или whataver), которое я хочу вернуть из контроллера.Чтобы можно было передать оба объекта в фильтр результатов, я использовал кортеж.
Дело в том, что я хочу сделать этот фильтр своего рода универсальным, и я пытаюсь привести фактическое значение (сущность,dto ...) поступающий от контроллера к объекту , и это вызывает у меня исключение , говорящее, что приведение невозможно,
Как я мог выполнить приведение?или, может быть, я должен использовать другой подход?
Я пытался использовать paginationHelperService непосредственно в фильтре результатов вместо того, чтобы использовать его в контроллере, но невозможно передать экземпляр службы из контроллера, так какклассы атрибутов не позволяют это.
Я также пытался использовать дженерики, думаю, это был бы самый простой способ добиться кастинга.Если бы я мог просто сделать атрибут универсальным, я мог бы привести объект к его фактическому типу, но, к сожалению, это невозможно, поскольку это класс атрибута.
// Controller
[HttpGet]
[AddPaginationHeader]
public async Task<IActionResult> Get([FromQuery]PagingModel pagingModel,
[FromHeader(Name = "Accept")]string mediaType) {
var pagedCollection = repository.GetPage(pagingModel);
PaginationMetadata paginationMetadata = paginationHelperService.GetPagingMetadata(pagingModel);
if (mediaType == "mycustommediatype") {
var shapedCollection = ShapeCollectionOfData(pagedCollection);
return Ok((shapedCollection, pagingModel));
} else {
return Ok((pagedCollection, pagingModel));
}
}
// Custom Result Filter
public override void OnResultExecuting(ResultExecutingContext context) {
var result = context.Result as ObjectResult;
if (result?.Value != null && result?.StatusCode >= 200 &&
result?.StatusCode < 300) {
(object value, PaginationMetadata paginationMetadata) = ((object, PaginationMetadata))result.Value; // Casting
string paginationMetadataString = (context.HttpContext.Request.Headers["Accept"] == "mycustommediatype")
? JsonConvert.SerializeObject(paginationMetadata.FullMetadata)
: JsonConvert.SerializeObject(pagingMetadata.GenericMetadata);
context.HttpContext.Response.Headers.Add("X-Pagination", paging);
context.Result.Value = value;
}
}