Asp.net mvc 3 &引用;“停机维修”;Asp.net MVC web应用的页面
我有以下要求Asp.net mvc 3 &引用;“停机维修”;Asp.net MVC web应用的页面,asp.net-mvc-3,iis-7.5,httpmodule,action-filter,Asp.net Mvc 3,Iis 7.5,Httpmodule,Action Filter,我有以下要求 在web.config中设置一个值并启用维护模式 所有非ajax请求都应该显示一个自定义错误页面,http状态代码设置为503。应保留页面的url 所有ajax请求都应使用http状态代码503进行响应 我应该有机会对一个文件做一些基本的日志记录。如果他碰巧登录到应用程序,请记录url和用户身份 我正在使用ELMAH跟踪/记录所有未处理的异常。实现维护模式的机制不需要我不使用ELMAH 我已将“runAllManagedModulesForAllRequests”设置为true。
- 在web.config中设置一个值并启用维护模式
- 所有非ajax请求都应该显示一个自定义错误页面,http状态代码设置为503。应保留页面的url李>
- 所有ajax请求都应使用http状态代码503进行响应
- 我应该有机会对一个文件做一些基本的日志记录。如果他碰巧登录到应用程序,请记录url和用户身份
- 我正在使用ELMAH跟踪/记录所有未处理的异常。实现维护模式的机制不需要我不使用ELMAH
- 我已将“runAllManagedModulesForAllRequests”设置为true。这最初是用于RequestReduce的。我们不再使用它,但我不愿意将其值重置为false。我不确定是否有其他图书馆需要它李>
HttpModule
- MVC
ActionFilter
ActionFilter
,因为我不知道如何保证它在任何身份验证/授权过滤器之前运行。我有一个自定义的身份验证过滤器,它可以访问数据库。维护模式背后的想法是db可能处于脱机状态,但web应用程序不应该显示500个自定义错误页面,而应该显示503个自定义错误页面
我编写了以下httpmodule
,并将其添加到我的web.config中。它适用于ajax请求。它对非ajax请求有点有效。所有请求都被重定向到503错误页面。副作用是所有对静态内容的请求也会导致503。因此,我的错误页面显示为非样式:(
这种方法的问题
// the http module
public class MaintenanceModeModule : IHttpModule
{
private static bool _isUnderMaintenance;
static MaintenanceModeModule()
{
var valueStr = (ConfigurationManager.AppSettings["UnderMaintenance"] ?? (false).ToString());
bool underMaintenance;
bool.TryParse(valueStr, out underMaintenance);
_isUnderMaintenance = underMaintenance;
}
public void Init(HttpApplication application)
{
application.BeginRequest += OnBeginRequest;
}
private void OnBeginRequest(object sender, EventArgs e)
{
var application = (HttpApplication) sender;
var request = application.Request;
var response = application.Response;
if (_isUnderMaintenance == false)
{
return;
}
application.Context.Items["under_maintenance"] = true; // used later
if (request.Url.PathAndQuery == "/503") // the url of the action that renders the custom error page
{
return;
}
const int statusCode = (int) HttpStatusCode.ServiceUnavailable;
const string statusMessage = "Temporarily down for maintenance";
var requestWrapper = new HttpRequestWrapper(request);
if (requestWrapper.IsAjaxRequest())
{
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.StatusCode = statusCode;
response.TrySkipIisCustomErrors = true;
response.StatusDescription = statusMessage;
response.End();
return;
}
// doesn't work, shows the Yellow Screen of Death (YSoD)
// application.Context.Server.Transfer("~/503", preserveForm: true);
// doesn't work, shows the Yellow Screen of Death (YSoD)
// throw new HttpException(statusCode, statusMessage);
response.Redirect("~/503");
}
public void Dispose()
{
}
}
// web.config
// only the relevant portions of each section is shown
<appSettings>
<add key="UnderMaintenance" value="true" />
</appSettings>
<customErrors mode="On"> <!-- Custom errors are on, even then I was seeing YSoDs during my attempts -->
<error statusCode="404" redirect="404" />
<error statusCode="503" redirect="503" />
</customErrors>
<system.webServer>
<httpErrors existingResponse="PassThrough">
</httpErrors>
<modules runAllManagedModulesForAllRequests="true">
<add name="MaintenanceMode" type="WebApp.Code.MvcInfrastructure.MaintenanceModeModule" />
</modules>
</system.webServer>
// route config
routes.MapRoute("503Error", "503", new { controller = "Error", action = "UnderMaintenance" });
// error controller
// the authentication filter skips authentication if the allowanonymous attribute is present
[AllowAnonymous]
public class ErrorController : CustomBaseController
{
public ErrorController(AppConfig appConfig)
: base(appConfig)
{
}
public ActionResult UnderMaintenance()
{
// behind the scenes reads the value from HttpContext.Items.
// This was set during the execution of the httpmodule
if (AppConfig.UnderMaintenance == false)
{
return new RedirectResult("~/");
}
Response.StatusCode = (int) HttpStatusCode.ServiceUnavailable;
Response.TrySkipIisCustomErrors = true;
// the actual content of the view is not relevant now
return View("Error503");
}
}