Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a page only once in asp.net mvc

Tags:

asp.net-mvc

In my app, I am checking if some config file is available or not, if it's not then I want to redirect to install page.

To me the best place to accomplish this is application_start. Because it's happening for only one time. If I do the checking in application_start and write Response.Redirect I will get Response is not available in this context.

I tried other answers in stack overflow to redirect in application_start like HttpContext.Current.Response.Redirect; none worked for me.

I don't want to do it in a base controller or a filter because the checking logic will happen for every single request.

My goal is to check it only once and it's best to be when the app start.

Update 1

I added response.redirect to the application_start but got error like this:

application start:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        Response.RedirectToRoute(
            new RouteValueDictionary {
            { "Controller", "Home" },
            { "Action", "about" }
        });
    }

but i am receiving an error like this:

Response is not available in this context.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Response is not available in this context.

like image 340
Mohammad Hossein Amri Avatar asked Aug 08 '16 13:08

Mohammad Hossein Amri


1 Answers

If you really want to avoid having a filter run for every request after setup then you can do something like this:

RedirectAttribute.cs (generic example)

public class RedirectAttribute : ActionFilterAttribute
{
    private readonly string _controller;
    private readonly string _action;

    public RedirectAttribute(string controller, string action)
    {
        _controller = controller;
        _action = action;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionDescriptor.ActionName != _action ||
            filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != _controller)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary(new {controller = _controller, action = _action})
                );
        }
    }
}

In Global.asax.cs above "FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);"

if (/*Insert logic to check if the config file does NOT exist*/)
{
    //Replace "Setup" and "Index" with your setup controller and action below
    GlobalFilters.Filters.Add(new RedirectAttribute("Setup", "Index"));
}

Now, after your user has fully completed setup, you can unload the app domain:

HttpRuntime.UnloadAppDomain();

Please note: you will need to make sure that your app has permission to unload the AppDomain. If it does not, you can try File.SetLastWriteTimeUtc(...) on the configuration file (AppDomain.CurrentDomain.SetupInformation.ConfigurationFile.) This will also unload the AppDomain.

Unloading the AppDomain will "restart" the web app and call Application_Start() again. The filter will not be added to your requests since your if statement will determine that the app has already been configured.

like image 80
agriffin Avatar answered Oct 16 '22 02:10

agriffin