12

The subject is selfexplanatory. I've developer and production environments. Developer env. is my localhost machine. I've action methods in contolers that sets response status code to 500 when something wents wrong (error occured, or logical inconsistance) and returns Json-answer. My common method looks like that:

[HttpPost]
public ActionResult DoSomething(int id)
{
    try
    {
         // some useful code
    }
    catch(Exception ex)
    {
         Response.StatusCode = 500;
         Json(new { message = "error" }, JsonBehaviour.AllowGet)
    }
}

On the client side in production env. when such an error occured ajax.response looks like an HTML-code, instead of expected JSON.

Consider this:

<div class="content-container">
 <fieldset>
   <h2>500 - Internal server error.</h2>
   <h3>There is a problem with the resource you are looking for, and it cannot be displayed.</h3>
</fieldset>
</div>

Filter context is not an option. I think it is some sort of IIS or web.config issue.

SOLUTION: We decided to add TrySkipIisCustomErrors in BeginRequest in Global.asax and it is solved problems in each method in our application.

2
  • 1
    Do you have return before the Json function call? Commented May 16, 2013 at 8:20
  • @Zoka, yes of corse return still there. Thank you. Commented May 16, 2013 at 9:49

3 Answers 3

13

I guess that IIS is serving some friendly error page. You could try skipping this page by setting the TrySkipIisCustomErrors property on the response:

catch(Exception ex)
{
     Response.StatusCode = 500;
     Response.TrySkipIisCustomErrors = true;
     return Json(new { message = "error" }, JsonBehaviour.AllowGet)
}
Sign up to request clarification or add additional context in comments.

3 Comments

@Khanh To, trying to skip iis errors seems to be some sort of hack.
No, not at all. It is not a hack. The friendly error page is a functionality built in ASP.NET. If you don't like them don't use them. But if you decided to use them you should be aware of the consequences (you cannot be setting error status codes with custom responses) without telling IIS explicitly that.
I think it is a good solution but still seems to be an IIS issue. We decided to add TrySkipIisCustomErrors in BeginRequest in Global.asax and it is solved problems in each method in our application. Thank you.
0

Is your IIS configured to treat application/json as a valid mime-type? You may check that in properties for the server in IIS Manager and click MIME Types. If json is not there then click "New", enter "JSON" for the extension, and "application/json" for the MIME type.

1 Comment

nope :( This type actually was not registered on my iis. I added it but nothing changed.
0

I solved this by writing a custom json result, which uses json.net as the serializer. This is overkill for just the IIS fix but it means it's reusable.

public class JsonNetResult : JsonResult
{
    //public Encoding ContentEncoding { get; set; }
    //public string ContentType { get; set; }
    public object Response { get; set; }
    public HttpStatusCode HttpStatusCode { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult(HttpStatusCode httpStatusCode = HttpStatusCode.OK)
    {
        Formatting = Formatting.Indented;
        SerializerSettings = new JsonSerializerSettings { };
        SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        HttpStatusCode = httpStatusCode;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        HttpResponseBase response = context.HttpContext.Response;

        response.TrySkipIisCustomErrors = true;

        response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        response.StatusCode = (int) HttpStatusCode;

        if (Response != null)
        {
            JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

            JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Response);

            writer.Flush();
        }
    }
}

Use:

            try
            {
                return new JsonNetResult()
                {
                    Response = "response data here"
                };
            }
            catch (Exception ex)
            {
                return new JsonNetResult(HttpStatusCode.InternalServerError)
                {
                    Response = new JsonResponseModel
                    {
                        Messages = new List<string> { ex.Message },
                        Success = false,
                    }
                };
            }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.