Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use existingResponse="Auto" successfully?

So I am returning detailed 400 error responses from my MVC web app. Setting existingResponse="PassThrough" works, but that's not what I want. I don't want to expose all failures, I only want to expose them when I have custom responses.

Auto, is set by default, but I deliberately set it. However, the documentation says "SetStatus" flag must be set, but I have no idea how to do such a thing. I wrote the following four controller methods in order to test it, and only BadRequestD works. The others set the status code and the status just fine, but the body content is "Bad Request".

public ActionResult BadRequestA() {     Response.StatusCode = 400;     return Content("weeeeee"); }  public ActionResult BadRequestB() {     Response.Status = "400 U DUN MESSED UP";     return Content("weeeeee"); }  public ActionResult BadRequestC() {     Response.Status = "400 U DUN MESSED UP";     Response.StatusCode = 400;     return Content("weeeeee"); }  public ActionResult BadRequestD() {     Response.StatusCode = 400;     Response.TrySkipIisCustomErrors = true;     return Content("weeeeee"); } 
like image 923
BradLaney Avatar asked Aug 16 '13 15:08

BradLaney


2 Answers

However, the documentation says "SetStatus" flag must be set, but I have no idea how to do such a thing

It's actually talking about the fTrySkipCustomErrors flag/argument to the IHttpResponse::SetStatus method in the IIS C++ SDK (see note I added to bottom of documentation here). But in ASP.NET the flag is exposed as Response.TrySkipIisCustomErrors. So according to:

http://www.iis.net/configreference/system.webserver/httperrors

Auto = Leaves the response untouched only if the SetStatus flag is set

I would expect to see IIS replace the response with its own html error page content (you can configure what that content is) by default unless you set:

Response.TrySkipIisCustomErrors = true; 

Which is what you're seeing.


Additional related info, in MVC5 it seems to act as if that flag is true even if it's false for uncaught exceptions which I don't see in WebForms. As a workaround in Global.asax I'm:

protected void Application_Error() {     var error = Server.GetLastError();     Server.ClearError();     //code to log error here     var httpException = error as HttpException;     Response.StatusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError; } 
like image 60
Michael Avatar answered Oct 13 '22 18:10

Michael


If you need to have custom responses with 4xx http statuses and still want to use Custom Error Pages here's what you should do:

  • set existingResponse="Auto" in web.config;
  • set TrySkipIisCustomErrors = true in your action (one that returns 4xx status and a content);
  • clear server error in global.asax (in Application_Error() - Server.ClearError()) and re-set the status code (Reponse.StatusCode = ((HttpException)Server.GetLastError()).GetHttpCode())

It's weird that IIS team didn't implement existingResponse attribute for specific status codes, so it's impossible to use existingResponse="PassThrough" just for one (or few) codes.

like image 27
Łukasƨ Fronczyk Avatar answered Oct 13 '22 16:10

Łukasƨ Fronczyk