Quantcast
Channel: ASPNETWebStack Issue Tracker Rss Feed
Viewing all articles
Browse latest Browse all 7215

Commented Issue: HttpControllerHandler.EndProcessRequest fails when the MS_HttpContext is modified and other Message Handler terminates the request [408]

$
0
0
If I were to have two message handlers registered and one of them modifies the MS_HttpContext and the other terminates the request, System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest throws "Object reference not set to an instance of an object" NullReferenceException. Repro steps:

First message handler which modified MS_HttpContext:

public class RemoveServerHeaderHandler : DelegatingHandler {

protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken) {

return base.SendAsync(request, cancellationToken).ContinueWith(task => {

var response = task.Result;

var httpContext = response.RequestMessage.Properties["MS_HttpContext"] as HttpContextWrapper;
if (httpContext != null)
httpContext.Response.Headers.Remove("Server");

return response;
});
}
}

Second message handler which terminates the request:

public class TerminatingMessageHandler : DelegatingHandler {

protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken) {

var response = new HttpResponseMessage(HttpStatusCode.OK);
return Task.FromResult(response);
}
}

Registering them:

protected void Application_Start(object sender, EventArgs e) {

var config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute(
"DefaultApiRoute",
"api/{controller}/{id}",
new { id = RouteParameter.Optional }
);

config.MessageHandlers.Add(new RemoveServerHeaderHandler());
config.MessageHandlers.Add(new TerminatingMessageHandler());
}

When we run the application and get into the Web API pipeline, message handlers are invoked and following error message is thrown:

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result) +112
System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +10
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

I also attached the sample project. Just send a request to /api/cars.
Comments: I think I found out what is causing this. The below one also fails on his own, no need for another handler: public class TerminatingMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var response = new HttpResponseMessage(HttpStatusCode.OK); return Task.FromResult(response).ContinueWith(task => { var responseMsg = task.Result; var httpContext = responseMsg.RequestMessage.Properties["MS_HttpContext"] as HttpContextWrapper; if (httpContext != null) httpContext.Response.Headers.Remove("Server"); return responseMsg; }); } } The problem is that as we create the response from scratch, it doesn't carry the RequestMessage. So, it fails. The blow code, which sets the RequestMessage property of the HttpResponseMessage, solves the problem but I believe this should be done by the framework: public class TerminatingMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var response = new HttpResponseMessage(HttpStatusCode.OK); response.RequestMessage = request; return Task.FromResult(response).ContinueWith(task => { var responseMsg = task.Result; var httpContext = responseMsg.RequestMessage.Properties["MS_HttpContext"] as HttpContextWrapper; if (httpContext != null) httpContext.Response.Headers.Remove("Server"); return responseMsg; }); } }

Viewing all articles
Browse latest Browse all 7215

Trending Articles