2

I have two ASP.NET MVC web apps running on the same server. One of them is a web service that returns an error message in plain text if an exception occurs. However, right now, some clients that call the web service don't receive the error message; instead, they simply receive "Bad Request" in HTML.

The second web app (on the same server as the first) can call a URL handled by the first one and, right now, correctly receives the error message in plain text. However, I have tried calling that URL other ways, and all of them have resulted in receiving "Bad Request":

  • Pasting the URL into Chrome on my computer
  • Pasting the URL into IE on the server
  • Calling the URL from a web app on a different computer from the server

This error does not occur locally. When I run the 2 web apps on my computer, I receive the error message in plain text from both the second web app and from calling the local URL from Chrome.

I have narrowed down the offending line of code to the first line of the following ActionResult snippet:

Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Content(errorMessage, ContentTypes.PlainText);

Removing the first line appears to fix the problem; however, that also eliminates the ability for me to use a descriptive status code. It appears to me that after the ActionResult is returned the response is being intercepted if either (a) the client is on a different computer or (b) the client is a web browser. So I guess I have a 2-part question:

  1. Is there a reason why .NET or IIS would intercept and change a response depending on the client type or location?
  2. Is there an easy way to view the response at any point between this code and when it's dispatched to the client?

Thanks!


Update: I changed the web app to use HttpResponseException. Now I am getting the following YSOD exception:

Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.

Using MVC version 5, Visual Studio 2013. The code for the ActionResult looks like this:

MyImage image = new MyImage(parameters);

if (image.Errors.Any())
{
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(image.Error) });
}

return File(image.AsJpeg(), ContentTypes.Jpeg);

Anyone have an idea how to bypass this unhelpful response?


Update 2: The issue turned out to be that the error message was being suppressed because of the Web.config setting system.webServer > httpErrors > errorMode which has a default value of "DetailedLocalOnly" and seems to be invoked in some cases for a reason I don't know (although this question may start to shed some light). Once I changed it to this, it worked as I expected:

<httpErrors errorMode="Detailed" />

I understand why they suppress error messages by default on remote machines, but this was a lot harder to track down than I would have thought. Anyway, I hope this is helpful to someone in the future.

Community
  • 1
  • 1
Andy
  • 856
  • 9
  • 26
  • Put some sort of logging and then test with different client browsers. See what response you get. – Azhar Khorasany Dec 22 '14 at 22:53
  • Can you please share the specific error responses that your receive from other types. – Thanigainathan Dec 22 '14 at 22:56
  • @Thanigainathan: each of the 3 cases in that list results in just the words "Bad Request" with response type HTML. – Andy Dec 22 '14 at 23:03
  • @Andy please use the fiddler tool to see the request headers that's sent when you open the link. Does the code block you are mentioning is the error handling block ? If so you have to check why its coming to the error block – Thanigainathan Dec 22 '14 at 23:12
  • @Thanigainathan: the issue isn't WHY it's going to the error block. The issues is what it's DOING in the error block. I expect it to return an error message in plain text. Instead it's returning the words "Bad request" in HTML. I have ascertained via debugging that it does call that code correctly. The issue happens sometime between when I set Reponse.StatusCode and when my browser receives the response. – Andy Dec 22 '14 at 23:31
  • Hi Andy, please let us know the version of the MVC, .net framework ?Are you getting this exception from the Web API service method ? If possible can you paste the code block of the method – Thanigainathan Dec 23 '14 at 17:51
  • @Thanigainathan: I updated the question with the current code. Thanks! – Andy Dec 23 '14 at 18:07
  • Any possibility that it's the browser itself trying to display a "friendly" error? – rossisdead Dec 23 '14 at 21:08
  • No, it's definitely a yellow screen of death. The second one, anyway. – Andy Dec 23 '14 at 21:09
  • @Andy Are you not getting the error "Cannot implicitly convert type "System.Web.Http.HttpResponseException' to 'System.Web.Mvc.ActionResult" ? – Thanigainathan Dec 24 '14 at 03:45
  • @Thanigainathan: No, I haven't gotten that error - yet. – Andy Dec 24 '14 at 07:22
  • @Andy I am wondering you are returning an exception fo rthe ActionResult. Is that right ? – Thanigainathan Dec 24 '14 at 17:25
  • @Thanigainathan: at the moment, I am throwing an exception, so it never gets to the return statement. – Andy Dec 27 '14 at 06:47
  • @Andy looks like there is an environment based issues for the image processing. Please confirm if this is correct. If so you have to fix that to fix this error reponse – Thanigainathan Dec 29 '14 at 15:59
  • @Thanigainathan: I don't believe so. If the parameters are correct, the image works fine. The only unexpected behavior is when an error occurs. Thanks for your help. – Andy Dec 29 '14 at 18:05
  • @Andy Please use an ErrorController to show a user friendly error message instead of sending an BadRequest response. So Check for any errors and redirect to the custom error page. – Thanigainathan Dec 29 '14 at 20:48
  • @Thanigainathan: I cannot redirect the user to an error page. This is a web service, and the response must be either an image (jpg) or a plain-text error message. Thank you for your suggestion, though. – Andy Jan 01 '15 at 04:54
  • @Andy it seems you are expecting plain text response for error scenario. So it's working as expected, there is an error in local host for image processing and its returning bad request text. – Thanigainathan Jan 01 '15 at 05:07
  • @Thanigainathan: there's not an error in localhost. The issue is that I'm throwing an exception, but .NET is intercepting it and replacing it with a "friendly" YSOD. – Andy Jan 01 '15 at 10:09
  • @Andy I would advise you to use the answer given by alwayslearning. Its the correct way to return exception from web api service. Dont use responseexception because it gives YSOD – Thanigainathan Jan 01 '15 at 21:33
  • @Thanigainathan: I tried that, and it suppressed the error message I supplied. I submitted a different question about it: http://stackoverflow.com/questions/27785444/httpresponsemessage-stringcontent-replacing-message-content – Andy Jan 05 '15 at 22:47
  • @Thanigainathan: I discovered a solution to my original issue. I've updated above. Thanks again for your help. – Andy Jan 06 '15 at 23:20
  • 1
    @Andy it was a good finding. Thanks for letting me know that – Thanigainathan Jan 06 '15 at 23:25

1 Answers1

1

I can't think of any reason why IIS would care what client was calling a service. My guess is that the client is sending a different request to the server than what you think it is sending. You can verify this by using a program called "Fiddler".

Also, I'd recommend following a pattern that returns a HttpResponseMessage like this when sending back information from a Web API call:

return new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            ReasonPhrase = message,
            Content = new StringContent(string.Format("{0}", exception))
        };
Always Learning
  • 2,623
  • 3
  • 20
  • 39
  • It looks like .NET cares where the client was (remote vs. local), but you're right, IIS doesn't. Setting httpErrors errorMode to Detailed (default is DetailedLocalOnly) did the trick. Thanks for your help. – Andy Jan 06 '15 at 23:23
  • On second thought, it might actually be related to IIS (at http://stackoverflow.com/a/18404091/361460 it suggests this may be IIS's way of suppressing it after .NET is done) – Andy Jan 06 '15 at 23:31