Search code examples
.net-coremiddlewareasp.net-core-2.0

Response on created context keeps giving me NullStream


I'm trying to write a middleware for batch requests i .net core 2.0. So far the I have splitted the request, pipe each request on to the controllers. The controllers return value, but for some reason the response on the created context that I parse to the controllers keeps giving me a NullStream in the body, so I think that there is something that I miss in my setup.

The code looks like this:

var json = await streamHelper.StreamToJson(context.Request.Body);

var requests = JsonConvert.DeserializeObject<IEnumerable<RequestModel>>(json);

var responseBody = new List<ResponseModel>();

foreach (var request in requests)
{
    var newRequest = new HttpRequestFeature
    {
        Body = request.Body != null ? new MemoryStream(Encoding.ASCII.GetBytes(request.Body)) : null,
        Headers = context.Request.Headers,
        Method = request.Method,
        Path = request.RelativeUrl,
        PathBase = string.Empty,
        Protocol = context.Request.Protocol,
        Scheme = context.Request.Scheme,
        QueryString = context.Request.QueryString.Value
    };

    var newRespone = new HttpResponseFeature();
    var requestLifetimeFeature = new HttpRequestLifetimeFeature();

    var features = CreateDefaultFeatures(context.Features);
    features.Set<IHttpRequestFeature>(newRequest);
    features.Set<IHttpResponseFeature>(newRespone);
    features.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);

    var innerContext = _factory.Create(features);
    await _next(innerContext);

    var responseJson = await streamHelper.StreamToJson(innerContext.Response.Body);

I'm not sure what it is I'm missing in the setup, since innerContext.Response.Body isn't set.

One of the endpoints that I use for testing and that gets hit looks like this

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

Solution

  • I found the error, or two errors for it to work.

    First I had to change my newResponse to

    var newRespone = new HttpResponseFeature{ Body = new MemoryStream() };
    

    Since HttpResponseFeature sets Body to Stream.Null in the constructor.

    When that was done, then Body kept giving an empty string when trying to read it. That was fixed by setting the Position to Zero like

    innerContext.Response.Body.Position = 0;