Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IIS Overwriting HTTP Response Text When HTTP Response Status set as 400

I am building an MVC 3 application with an IIS 7.5 backend. On my controller, I have action methods that allow the user to add/edit domain objects. The Action handles HTTP Post, has a return value of string which contains any validation error messages encountered during the save process. Here is an example of one Action Method:

    [HttpPost]
    public string CustomerEdit(CustomerModel customerModel)
    {
        var errorMessages = new StringBuilder();
        var serverErrors = new List<string>();

        //Map to a customer domain object
        Mapper.CreateMap<CustomerModel, Customer>();
        var customer = Mapper.Map<CustomerModel, Customer>(customerModel);

        if (customerModel.Oper == "del")
        {
            var customerIds = new List<Guid>();
            customerIds.Add(customer.Id);

            if (!_serverService.DeleteCustomers(customerIds))
            {
                errorMessages.Append("The item could not be deleted");
                Response.StatusCode = Constants.STATUS_SERVER_ERROR;
            }
        }
        else
        {
            //Validate
            if (!_serverService.ValidateCustomer(customer, out serverErrors))
            {
                foreach (var error in serverErrors)
                {
                    ModelState.AddModelError("Validation", error);
                }
            }

            //Save
            if (ModelState.IsValid)
            {
                var saveStatus = _serverService.SaveCustomer(ref customer, _id);

                if (!saveStatus)
                {
                    errorMessages.Append("The server encountered and error during Save");
                    Response.StatusCode = Constants.STATUS_SERVER_ERROR;
                }
            }
            else
            {
                errorMessages.Append(GetValidationErrors(ModelState));
                Response.StatusCode = Constants.STATUS_SERVER_ERROR;
            }
        }
        return errorMessages.ToString();
    }

In the case of an error, I need to set the Response.StatusCode property to a value of either 400/500, and return a concatenated string of detailed error messages. Unfortunately, IIS always strips my error string out of the response test, and (in the case of 400 errors) adds replaces it with the string 'Bad Request'

Is there a way to configure IIS to return a custom, Action-specific, string when the status code is set to 400?

like image 928
TheoryOfLight Avatar asked Jan 17 '12 18:01

TheoryOfLight


2 Answers

After talking to a friend of mine who is a wiz at configuring IIS, I found that in IIS 7+ you can add the following to web.config:

<system.webServer>
  <httpErrors errorMode="Detailed"/>
</system.webServer>

If this setting in web.config is used, AND you set the body of the response, then the response body will reach the client. If you do NOT set the response body, then IIS will serve up a detailed error page with detailed error information (see http://learn.iis.net/page.aspx/267/how-to-use-http-detailed-errors-in-iis/). Many folks consider this a security risk, so use with caution.

like image 59
TheoryOfLight Avatar answered Oct 22 '22 23:10

TheoryOfLight


In MVC it is also possible to do this on a Action by Action basis. See TrySkipisCustomErrors.

Use:

Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return this.Json(SomeJsonObject);  // could output string too
like image 27
jsturtevant Avatar answered Oct 22 '22 21:10

jsturtevant