IIS のさまざまなバージョンでさまざまな応答を返すモデルを検証するために使用する MVC アクション フィルターがあります。アクション フィルターのコードは次のとおりです。
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var viewData = filterContext.Controller.ViewData;
var modelStateErrors = filterContext.Controller.ViewData.ModelState.Keys.SelectMany(key => filterContext.Controller.ViewData.ModelState[key].Errors);
string errorMessage;
if (modelStateErrors.Count() > 0)
{
ModelError error = modelStateErrors.FirstOrDefault();
if (error.ErrorMessage.IsNotNullOrEmpty())
{
errorMessage = error.ErrorMessage;
}
else if (error.Exception != null)
{
errorMessage = error.Exception.Message;
}
else
{
errorMessage = Messages.UNKNOWN_VALIDATION_ERROR;
}
}
else
{
errorMessage = Messages.UNKNOWN_VALIDATION_ERROR;
}
if (!viewData.ModelState.IsValid)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
filterContext.Result = new ContentResult { Content = errorMessage, ContentType = "text/plain" };
}
else
{
var controller = filterContext.Controller as WMSControllerBase;
if (controller != null)
{
controller.DisplayWarningMessage(errorMessage);
}
foreach (var param in filterContext.ActionParameters)
{
if (param.Key.ToLower() == "model" || param.Value is ViewModelBase)
{
viewData.Model = param.Value;
break;
}
}
if (viewData.Model is ViewModelBase)
{
(viewData.Model as ViewModelBase).RebuildModel();
}
filterContext.Result = new ViewResult
{
ViewData = viewData
};
}
}
base.OnActionExecuting(filterContext);
}
}
IIS 7.0 サーバーでは、アクション フィルターは意図したとおりに機能し、AJAX 呼び出しに対して次のような応答を生成します。
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/7.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 08 Oct 2013 21:40:36 GMT
Content-Length: 47
The error message I want the end user to see.
ただし、IIS 7.5 以降で実行すると、次のような応答が返されます。どうやら IIS または MVC は、応答本文を「Bad Request」に置き換えて、タイプを text/html に設定することを決定したようです。ここで何が起こっているのか疑問に思っていますが、なぜこのように応答を変更するのでしょうか?
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 08 Oct 2013 21:50:02 GMT
Content-Length: 11
Bad Request