Jusqu'à présent, j'avais une méthode GET
qui ressemblait à ceci:
protected override async Task<IHttpActionResult> GetAll(QueryData query)
{
// ... Some operations
//LINQ Expression based on the query parameters
Expression<Func<Entity, bool>> queryExpression = BuildQueryExpression(query);
//Begin to count all the entities in the repository
Task<int> countingEntities = repo.CountAsync(queryExpression);
//Reads an entity that will be the page start
Entity start = await repo.ReadAsync(query.Start);
//Reads all the entities starting from the start entity
IEnumerable<Entity> found = await repo.BrowseAllAsync(start, queryExpression);
//Truncates to page size
found = found.Take(query.Size);
//Number of entities returned in response
int count = found.Count();
//Number of total entities (without pagination)
int total = await countingEntities;
return Ok(new {
Total = total,
Count = count,
Last = count > 0 ? GetEntityKey(found.Last()) : default(Key),
Data = found.Select(e => IsResourceOwner(e) ? MapToOwnerDTO(e) : MapToDTO(e)).ToList()
});
}
Cela a fonctionné comme un charme et c'était bon. Cependant, on m'a récemment demandé d'envoyer la réponse métadonnées (c'est-à-dire, les propriétés Total
, Count
et Last
) en tant qu'en-têtes personnalisés à la place du corps de la réponse.
Je n'arrive pas à accéder à la Response
à partir d'ApiController. J'ai pensé à un filtre ou à un attribut, mais comment pourrais-je obtenir les valeurs de métadonnées?
Je peux conserver toutes ces informations dans la réponse, puis disposer d'un filtre qui désérialisera la réponse avant de l'envoyer au client et en créer un nouveau avec les en-têtes, mais cela semble gênant et mauvais.
Existe-t-il un moyen d’ajouter des en-têtes personnalisés directement à partir de cette méthode sur une ApiController
?
J'ai entré des commentaires, voici ma réponse complète.
Vous devrez créer un filtre personnalisé et l'appliquer à votre contrôleur.
public class CustomHeaderFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var count = actionExecutedContext.Request.Properties["Count"];
actionExecutedContext.Response.Content.Headers.Add("totalHeader", count);
}
}
Dans votre contrôleur
public class AddressController : ApiController
{
public async Task<Address> Get()
{
Request.Properties["Count"] = "123";
}
}
Vous pouvez explicitement ajouter des en-têtes personnalisés dans une méthode comme ceci:
[HttpGet]
[Route("home/students")]
public HttpResponseMessage GetStudents()
{
// Get students from Database
// Create the response
var response = Request.CreateResponse(HttpStatusCode.OK, studends);
// Set headers for paging
response.Headers.Add("X-Students-Total-Count", studends.Count());
return response;
}
Pour plus d'informations, lisez cet article: http://www.jerriepelser.com/blog/paging-in-aspnet-webapi-http-headers/
Ce dont vous avez besoin c'est:
public async Task<IHttpActionResult> Get()
{
var response = Request.CreateResponse();
response.Headers.Add("Lorem", "ipsum");
return base.ResponseMessage(response);
}
J'espère que cela répond à votre question.
La solution simple est de faire juste:
HttpContext.Current.Response.Headers.Add("MaxRecords", "1000");
Dans API Controller.
Vous pouvez utiliser un ActionFilter personnalisé qui vous permettra d'envoyer des en-têtes personnalisés et d'accéder au HttpContext:
public class AddCustomHeaderFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response.Content.Headers.Add("name", "value");
}
}