HTTP Failure response overwrites response body for non-local clients
I'm creating a locking mechanism for some public pages that should only allow one user to edit them at the same time. The client makes GET API calls to the server requesting a lock, which returns an MVC ActionResult object. For some reason, when I'm running the program locally and I return a new HttpConflictResult("Cannot acquire lock", message);
(indicating that acquiring the lock failed), it works fine. The error message is sent and received properly and can be displayed in an alert or whatever is needed. However, when I'm accessing the site remotely, the message is overwritten with "The page was not displayed because there was a conflict." Am I doing something wrong or is this a 'Feature' of IIS or something? If it is, is there a way around it so that I can still get the message that I want to the client?
Thanks in advance for any help!
EDIT: Sorry, forgot that HttpConflictResult was an inherited class. Here's some info on it:
public class HttpConflictResult : HttpErrorResult
{
public HttpConflictResult() : this(string.Empty) { }
public HttpConflictResult(string errorMessageResource) : this("Conflict", errorMessageResource, true) { }
public HttpConflictResult(string statusMessage, string errorMessage) :
base(409, statusMessage, errorMessage) { }
}
public class HttpErrorResult : ActionResult
{
protected int _statusCode;
protected string _statusMessage;
protected string _errorMessage;
public HttpErrorResult(int statusCode, string statusMessage, string errorMessageResource)
{
_statusCode = statusCode;
_statusMessage = statusMessage;
_errorMessage = errorMessage;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = _statusCode;
context.HttpContext.Response.StatusDescription =开发者_如何转开发 _statusMessage;
if(_errorMessage != null)
{
context.HttpContext.Response.ContentType = "application/json; charset=utf-8";
context.HttpContext.Response.Clear();
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
context.HttpContext.Response.Write(ser.Serialize(new { message = _errorMessage }));
}
}
}
Let me know if I left anything else out. Thanks again!
If you're setting error codes (i.e. http status codes in the 4xx or 5xx ranges), and you're running under IIS 7, then you need to ensure you've told IIS not to use the standard error messages.
You do this with the TrySkipIisCustomErrors
parameter on the Response
object. Try modifying your HttpErrorResult as follows:
public override void ExecuteResult(ControllerContext context)
{
// Set TrySkipIisCustomErrors to ensure ASP.NET sends your error content to the
// user instead of the default ASP.NET content under IIS 7.
context.HttpContext.Response.TrySkipIisCustomErrors = true;
context.HttpContext.Response.StatusCode = _statusCode;
context.HttpContext.Response.StatusDescription = _statusMessage;
if(_errorMessage != null)
{
[...]
}
}
精彩评论