Hi,
It would appear that there is a bug in the way the WebApi batch handlers work. The content of any batched request is null/blank when attempting to access it from a filter.
This is problematic for us as we use filters to check the Content-MD5 header, and therefore require access to the content to perform the check.
Note: The content does become accessible to filters if it is read further upstream, e.g. in a message handler, or a custom batch handler.
I have attached a small project that demonstrates the fault.
Cheers
Ben
Comments: This is due to the fact that action filters run after model binding. Because the content has already been read by the model binders, the content stream position has moved to the end and need to be rewinded before reading. Or you can load the content into buffer so that it can be read multiple times. Here is a recommended workaround using custom batch handler: Step 1. Create a custom batch handler (by deriving from DefaultHttpBatchHandler) and load the content into buffer. This will allow the content to be read multiple times after model binding without rewinding the steam. ``` public class MyHttpBatchHandler : DefaultHttpBatchHandler { public MyHttpBatchHandler(HttpServer httpServer) : base(httpServer) { } public override async Task<IList<HttpRequestMessage>> ParseBatchRequestsAsync(HttpRequestMessage request, CancellationToken cancellationToken) { IList<HttpRequestMessage> reqs = await base.ParseBatchRequestsAsync(request, cancellationToken); foreach (var item in reqs) { await item.Content.LoadIntoBufferAsync(); } return reqs; } } ``` 2. Wire up the custom batch handler instead of the DefaultHttpBatchHandler. ``` config.Routes.MapHttpBatchRoute("batch", "api/batch", new MyHttpBatchHandler(server)); ```
It would appear that there is a bug in the way the WebApi batch handlers work. The content of any batched request is null/blank when attempting to access it from a filter.
This is problematic for us as we use filters to check the Content-MD5 header, and therefore require access to the content to perform the check.
Note: The content does become accessible to filters if it is read further upstream, e.g. in a message handler, or a custom batch handler.
I have attached a small project that demonstrates the fault.
Cheers
Ben
Comments: This is due to the fact that action filters run after model binding. Because the content has already been read by the model binders, the content stream position has moved to the end and need to be rewinded before reading. Or you can load the content into buffer so that it can be read multiple times. Here is a recommended workaround using custom batch handler: Step 1. Create a custom batch handler (by deriving from DefaultHttpBatchHandler) and load the content into buffer. This will allow the content to be read multiple times after model binding without rewinding the steam. ``` public class MyHttpBatchHandler : DefaultHttpBatchHandler { public MyHttpBatchHandler(HttpServer httpServer) : base(httpServer) { } public override async Task<IList<HttpRequestMessage>> ParseBatchRequestsAsync(HttpRequestMessage request, CancellationToken cancellationToken) { IList<HttpRequestMessage> reqs = await base.ParseBatchRequestsAsync(request, cancellationToken); foreach (var item in reqs) { await item.Content.LoadIntoBufferAsync(); } return reqs; } } ``` 2. Wire up the custom batch handler instead of the DefaultHttpBatchHandler. ``` config.Routes.MapHttpBatchRoute("batch", "api/batch", new MyHttpBatchHandler(server)); ```