响应重定向在MVC中使用
本文关键字:MVC 重定向 响应 | 更新日期: 2023-09-27 18:03:20
我想创建全局之间的连接。Asax和控制器。我们在网站上使用数据库。我们有一个代码来检查数据库是否存在。如果它不存在,我们希望显示"数据库初始化"等消息。
数据库检查GLOBAL。ASAX:
public class MvcApplication : System.Web.HttpApplication
{
public static bool flag;
protected void Application_Start()
{
Database.SetInitializer<PhoneDexContext>(null);
var connString = ConfigurationManager.ConnectionStrings["DatabaseConnection"].ConnectionString;
using (PhoneDexContext db = new PhoneDexContext())
{
if (!db.Database.Exists())
{
flag = true;
db.Database.CreateIfNotExists();
}
}
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_BeginRequest()
{
if (flag)
{
Response.Redirect("Loading/LoadingScreen");
}
}
}
但是我们在使用响应重定向时有一个问题。它返回
{"响应在此上下文中不可用。"}.
我们有一个控制器LoadingController它有这样的代码;
public class LoadingController : Controller
{
// GET: Loading
public ActionResult LoadingScreen()
{
return View();
}
}
但是我们不能跳到这部分。我怎样才能连接??由于
首先,Application_Start
不处理任何用户请求。它只是执行一些启动初始化。它只在应用程序启动时调用一次。要根据用户的操作进行一些检查并正确响应,您需要将这些检查移到Application_BeginRequest
方法中。
第二,您还需要检查用户是否已经请求/Loading/LoadScreen
之前响应重定向到该页。否则,您将获得无限重定向,直到数据库创建。
public class MvcApplication : HttpApplication
{
private static bool dbInitialized;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// We can do it asynchronously to not block other initialization code.
Task.Run((Action)CreateDataBase);
}
private static void CreateDataBase()
{
Database.SetInitializer<PhoneDexContext>(null);
using (PhoneDexContext db = new PhoneDexContext())
{
if (!db.Database.Exists())
db.Database.CreateIfNotExists();
}
dbInitialized = true;
}
protected void Application_BeginRequest()
{
if (!dbInitialized && !this.Request.Url.LocalPath.StartsWith("/Loading/LoadingScreen", StringComparison.OrdinalIgnoreCase))
{
this.Response.Redirect("/Loading/LoadingScreen");
}
}
}
您可以进一步将检查移到ActionFilter
中,因为您将能够使用RouteData
并检查action
和controller
参数而不是url。与nameof
相结合,将减少路由更改,重命名,重构等的错误倾向。
我认为这个答案会给你你想要的:在一个控制器中返回不同的视图
在您的情况下,而不是响应。重定向使用返回视图("/Loading/LoadScreen");…或者类似的
try this
HttpContext.Current.Response.Redirect("/Loading/LoadScreen");
因为Response对象在global.asax的application_start方法中不可用。你必须使用HttpContext。
你也可以使用"自动启动功能"(如何预热ASP. js)。. NET MVC应用程序在IIS 7.5?:(亲爱的回答)。这将执行一次,在网站准备好服务请求之前。缺点是你不能向用户显示"请等待"窗口。就我个人而言,我不会在每个请求时检查数据库是否存在。只要执行它;我猜数据库更新应该不会花很长时间吧?
Application_Start
发生在ASP之前。Net开始处理请求。
您可以设置一个全局静态标志来指示错误条件,然后处理Application_BeginRequest
并检查标志和重定向。
static bool _isDbLoaded;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start(){
Database.SetInitializer<PhoneDexContext>(null);
var connString = ConfigurationManager.ConnectionStrings["DatabaseConnection"].ConnectionString;
using (PhoneDexContext db = new PhoneDexContext())
{
if (!db.Database.Exists())
{
_isDbLoaded = false;
db.Database.CreateIfNotExists();
}
}
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
protected void Application_BeginRequest(){
if(!_isDbLoaded){
Response.Redirect("Loading/LoadingPage");
}
}
由于Request
和Response
在Application_Start
事件中不可用,您可能会考虑将此代码放在MVC请求-响应管道中的某个地方。动作过滤器是一个好地方。
public class VerifySetupIsGood : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var dbSetDate = context.HttpContext.Application["DbSetDate"] as string;
if (String.IsNullOrEmpty(dbSetDate))
{
//to do : Execute your custom code to check db existence here
var values = new Dictionary<string, string> { { "action", "LoadScreen" },
{ "controller", "Loading" } };
var r = new RouteValueDictionary(values);
//redirect the request to MissingDatabase action method.
context.Result = new RedirectToRouteResult(r);
}
base.OnActionExecuting(context);
}
}
在这里,我们首先检查应用程序变量是否有"DbSetDate"键的有效条目。默认情况下,它将不在那里。然后必须执行自定义代码来检查数据库是否存在。如果没有,重定向到LoadScreen动作。
全局注册此过滤器,以便它将在任何进入您的应用程序的请求中执行。
GlobalFilters.Filters.Add(new VerifySetupIsGood());
现在,当您完成数据库设置后,更新这个应用程序变量,使其具有一个有效值。
HttpContext.Application["DbSetDate"] = DateTime.Now.ToString();
记住,应用程序变量状态也会被重置。所以不要只依赖于这个。您应该运行自定义代码来检查数据库是否存在于if条件中。