简体   繁体   中英

Redirect user from startup.cs asp.net core

I have a requirement where I want to check if database is connected(I have the class for that). if this class's method returns false then I want to redirect to database page/view where setup will take place. I have Asp.Net core identity. I want to check this condition before EF core tries to connect to DB. I tried to use the following but returns "too many redirects in browser". Note: Every method in home controller has [Authorize] except DatabaseCheck. Once the user is redirect here I would take values and update Appsettings.json, and application would run normally. Thanks for insights.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(Configuration);          

        services.AddDbContext<MyContext>(options =>
        options.UseSqlServer(SqlSettingsProvider.GetSqlConnection()));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<MyContext>()
            .AddDefaultTokenProviders();
        services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
        services.AddMvc()
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.Formatting = Formatting.Indented;
            }).AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

            });


    }
      public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }



        if (!DatabaseInstalledMiddleware.IsDatabaseInstalled(Configuration))
            app.UseMiddleware<DatabaseInstalledMiddleware>();



        app.UseStatusCodePagesWithReExecute("/StatusCodes/{0}");
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
                routes.MapRoute(
                    name: "defaultApi",
                    template: "api/v2/{controller}/{id?}");
            });     




    }

在此处输入图像描述

My suggestion is to use a Middleware solution that can handle just what you are looking for.

What is middleware

Middleware is software that is assembled into an application pipeline to handle requests and responses.

Each component:

Chooses whether to pass the request to the next component in the pipeline. Can perform work before and after the next component in the pipeline is invoked.

Here is a simple implemetation of how the middleware would work.

Now as we can assume that only at startup of the application we need to check if the database is installed and not every request to the application we can add the middleware only if it is needed. Therefore on restarts the middleware is only included if the database is not installed. So we will only register the Middleware extension when the database is not installed at startup.

The follow code assumes you have reviewed the linked MSDN page above.

Here is a simple example of the middleware (I called it DatabaseInstalledMiddleware )

public class DatabaseInstalledMiddleware
{
    public DatabaseInstalledMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    readonly RequestDelegate _next;

    public async Task Invoke(HttpContext context, IConfiguration configuration)
    {
        if (!IsDatabaseInstalled(configuration))
        {
            var url = "/databasechecker";
            //check if the current url contains the path of the installation url
            if (context.Request.Path.Value.IndexOf(url, StringComparison.CurrentCultureIgnoreCase) == -1)
            {
                //redirect to another location if not ready
                context.Response.Redirect(url);
                return;
            }
        }
        //or call the next middleware in the request pipeline
        await _next(context);
    }

    public static bool IsDatabaseInstalled(IConfiguration configuration)
    {
        var key = configuration["SQLConnectionSettings:SqlServerIp"];
        return !string.IsNullOrEmpty(key);
    }
}

The code is pretty basic, however we see that Invoke method accepts the current HttpContext and injects the IConfiguration instance. Next we run a simple method to check if the database is installed IsDataBaseInstalled .

If this method returns false we check to see if the user is currently requesting the databasechecker url. You can change this pattern or add urls as required if there are multiple install urls. If they are not requesting an install URL then we redirect them to the /databasechecker url. Otherwise the Middleware executes as expected with the line await _next(context) .

Now to use this in your request pipleline simply add the middleware before the MVC middleware such as.

This is in the startup.cs file. (Below is the basic startup file)

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    if (!DatabaseInstalledMiddleware.IsDatabaseInstalled(Configuration))
        app.UseMiddleware<DatabaseInstalledMiddleware>();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

It work for me. Startup.cs

app.Use(async (context, next) =>
{
    await next();
    if (context.Response.StatusCode == 404)
    {
        context.Response.Redirect("/Home/Error404");
        return;
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM