Добавление настраиваемого заголовка ответа в ApiController

До сих пор у меня был метод GET, который выглядел следующим образом:

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()
     });
}

Это работало как шарм, и это было хорошо. Тем не менее, мне недавно было сказано отправить ответ метаданные (то есть Total, Count и Last свойства) как ответные пользовательские заголовки вместо тела ответа.

Мне не удается получить доступ к Response из ApiController. Я думал о фильтре или атрибуте, но как бы получить значения метаданных?

Я могу сохранить всю эту информацию в ответ, а затем фильтр, который будет десериализовать ответ перед отправкой клиенту и создать новый с заголовками, но это кажется неприятным и плохим.

Есть ли способ добавить пользовательские заголовки непосредственно из этого метода на ApiController?

Ответ 1

Я ввел комментарии, вот мой полный ответ.

Вам нужно будет создать собственный фильтр и применить его к контроллеру.

public class CustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       var count = actionExecutedContext.Request.Properties["Count"];
       actionExecutedContext.Response.Content.Headers.Add("totalHeader", count);
    }
}

В вашем контроллере

  public class AddressController : ApiController
        {
            public async Task<Address> Get()
            {
               Request.Properties["Count"] = "123";
            }
    }

Ответ 2

Вы можете явно добавлять пользовательские заголовки в метод, подобный этому:

[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;
}

Для получения дополнительной информации прочитайте эту статью: http://www.jerriepelser.com/blog/paging-in-aspnet-webapi-http-headers/

Ответ 3

Что вам нужно:

public async Task<IHttpActionResult> Get() 
{ 
    var response = Request.CreateResponse();
    response.Headers.Add("Lorem", "ipsum");

    return base.ResponseMessage(response); 
}

Надеюсь, это ответит на ваш вопрос.

Ответ 4

Простое решение состоит в том, чтобы просто:

HttpContext.Current.Response.Headers.Add("MaxRecords", "1000");

Ответ 5

Вы можете использовать пользовательский ActionFilter, который позволит отправлять пользовательские заголовки и обращаться к HttpContext:

public class AddCustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       actionExecutedContext.Response.Content.Headers.Add("name", "value");
    }
}