Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Response object is null when using FeatureCollection on the DefaultHttpContext

I am testing some .net Core middleware and would like to run the middleware with the whole asp.net Core http pipeline instead of mocking it.

The problem is that somehow the Response object is not being set in the httpRequest when I use the Feature Collection and it is read only on the Request itself.

This code throws an exception when it tries to write to the Response Stream.

var fc = new FeatureCollection();
fc.Set<IHttpRequestFeature>(new HttpRequestFeature {
    Headers = new HeaderDictionary { { "RandomHeaderName", "123" } }
});
var httpContext = new DefaultHttpContext(fc);

var middleware = new RequestValidationMiddleware(
    next: async (innerHttpContext) =>
    {
        await innerHttpContext.Response.WriteAsync("test writing");
    });

middleware.InvokeAsync(httpContext).GetAwaiter().GetResult();
like image 512
Archlight Avatar asked Nov 22 '25 02:11

Archlight


1 Answers

By using a custom feature collection, you are excluding features that would have been added by the default constructor of the DefaultHttpContext

public DefaultHttpContext()
    : this(new FeatureCollection())
{
    Features.Set<IHttpRequestFeature>(new HttpRequestFeature());
    Features.Set<IHttpResponseFeature>(new HttpResponseFeature());
    Features.Set<IHttpResponseBodyFeature>(new StreamResponseBodyFeature(Stream.Null));
}

public DefaultHttpContext(IFeatureCollection features)
{
    _features.Initalize(features);
    _request = new DefaultHttpRequest(this);
    _response = new DefaultHttpResponse(this);
}

try recreating what was done in the default constructor by also adding the required features needed to exercise your test

var fc = new FeatureCollection();
fc.Set<IHttpRequestFeature>(new HttpRequestFeature {
    Headers = new HeaderDictionary { { "RandomHeaderName", "123" } }
});
//Add response features
fc.Set<IHttpResponseFeature>(new HttpResponseFeature());
var responseBodyStream = new MemoryStream();
fc.Set<IHttpResponseBodyFeature>(new StreamResponseBodyFeature(responseBodyStream ));

var httpContext = new DefaultHttpContext(fc);
like image 101
Nkosi Avatar answered Nov 24 '25 16:11

Nkosi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!