Hello. There seems to be a bug in either MVC 1.0 or IIS 7 that causes server errors to render improperly when the response is returned to the browser. Basically, when a server error occurs, I should get the standard error page from asp.net, telling me the
file and line of code where the error occurred. But instead I get a bunch of weird, binary-like data.
As a test scenario, I have created a default asp.net mvc application, and have applied my compression actionfilter attribute to the Home controller.
Then, I added some code under the About action to manually throw a generic exception.
When running under the local VS development server, the server error renders correctly in the browser. When I publish the application to our local staging IIS7 server, the page returns the aforementioned junk data.
The response code returns 500 as it should, though.
Here is the CompressionFilter code:
public class CompressFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("GZIP"))
{
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
response.AppendHeader("Content-encoding", "gzip");
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
response.AppendHeader("Content-encoding", "deflate");
}
}
}
It almost seems like the output in the response is being compressed, but the Content-encoding header is cleared when an exception occurs.
Debugging locally, I can see the same thing happening. When the page finishes loading, the Content-encoding header is not there:
Server
ASP.NET Development Server/9.0.0.0
Date
Thu, 23 Apr 2009 15:25:25 GMT
X-AspNet-Version
2.0.50727
Cache-Control
private
Content-Type
text/html; charset=utf-8
Content-Length
9793
Connection
Close
In disabling the compression filter, I found the content-length to be the same under the dev server. So its like the compression filter and header are ignored/cleared within the asp.net dev server. But in IIS7, compression is applied, but with no header.
I know I can use Dynamic compression within IIS7 and disable the filter in code altogether, but I would still like to know what is going here.
Also, as a workaround to solve the problem, I have found adding code within the Application_Error event handler to dispose of the response filter stream fixes the issue (response.filter.dispose()).
Thanks
asp.net mvc IIS7 gzip compression filter server error 500 binary characters
rfrancis48
0 Points
1 Post
Problem with MVC 1.0 compression actionfilter and IIS 7
Apr 23, 2009 03:42 PM|LINK
Hello. There seems to be a bug in either MVC 1.0 or IIS 7 that causes server errors to render improperly when the response is returned to the browser. Basically, when a server error occurs, I should get the standard error page from asp.net, telling me the file and line of code where the error occurred. But instead I get a bunch of weird, binary-like data.
As a test scenario, I have created a default asp.net mvc application, and have applied my compression actionfilter attribute to the Home controller.
Then, I added some code under the About action to manually throw a generic exception.
When running under the local VS development server, the server error renders correctly in the browser. When I publish the application to our local staging IIS7 server, the page returns the aforementioned junk data.
The response code returns 500 as it should, though.
Here is the CompressionFilter code:
public class CompressFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { HttpRequestBase request = filterContext.HttpContext.Request; string acceptEncoding = request.Headers["Accept-Encoding"]; if (string.IsNullOrEmpty(acceptEncoding)) return; acceptEncoding = acceptEncoding.ToUpperInvariant(); HttpResponseBase response = filterContext.HttpContext.Response; if (acceptEncoding.Contains("GZIP")) { response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); response.AppendHeader("Content-encoding", "gzip"); } else if (acceptEncoding.Contains("DEFLATE")) { response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); response.AppendHeader("Content-encoding", "deflate"); } } }It almost seems like the output in the response is being compressed, but the Content-encoding header is cleared when an exception occurs.
Debugging locally, I can see the same thing happening. When the page finishes loading, the Content-encoding header is not there:
In disabling the compression filter, I found the content-length to be the same under the dev server. So its like the compression filter and header are ignored/cleared within the asp.net dev server. But in IIS7, compression is applied, but with no header.
I know I can use Dynamic compression within IIS7 and disable the filter in code altogether, but I would still like to know what is going here.
Also, as a workaround to solve the problem, I have found adding code within the Application_Error event handler to dispose of the response filter stream fixes the issue (response.filter.dispose()).
Thanks
asp.net mvc IIS7 gzip compression filter server error 500 binary characters