これまで、次のような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
プロパティ)の代わりに応答カスタムヘッダーとして応答本文。
ApiControllerからResponse
にアクセスできません。フィルターまたは属性について考えましたが、メタデータ値を取得するにはどうすればよいですか?
この情報をすべて応答に保持してから、クライアントに送信する前に応答を逆シリアル化し、ヘッダーを使用して新しい応答を作成するフィルターを使用できますが、これは面倒で悪いようです。
ApiController
にこのメソッドからカスタムヘッダーを直接追加する方法はありますか?
私はコメントを入力しました、ここに私の完全な答えがあります。
カスタムフィルターを作成し、それをコントローラーに適用する必要があります。
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";
}
}
次のようにメソッドにカスタムヘッダーを明示的に追加できます。
[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/
簡単な解決策は次のとおりです。
HttpContext.Current.Response.Headers.Add("MaxRecords", "1000");
必要なのは:
public async Task<IHttpActionResult> Get()
{
var response = Request.CreateResponse();
response.Headers.Add("Lorem", "ipsum");
return base.ResponseMessage(response);
}
これがあなたの質問に答えることを願っています。
カスタムヘッダーを送信し、HttpContextにアクセスできるようにするカスタムActionFilterを使用できます。
public class AddCustomHeaderFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response.Content.Headers.Add("name", "value");
}
}
または、すべての応答で実行する必要がある場合は、DelegatingHandlerを活用することをお勧めします。コントローラー/アクションレベルではなく、リクエスト/レスポンスパイプラインで動作するためです。私の場合、すべての応答にヘッダーを追加する必要があるため、説明したとおりにしました。以下のコードスニペットを参照してください
public class Interceptor : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,PUT,OPTIONS");
response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token, content-type");
return response;
}
}
そして、このハンドラーをWebApiConfigに追加する必要があります。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new Interceptor());
}
}