Reload routes on runtime in dotnetcore

眉间皱痕 提交于 2019-12-24 03:53:26

问题


I have a custom route that reads URLs from a no-SQL database (MongoDB) and add them to the route pipeline at moment that the application starts, which is "pretty standard"

something like this (in my startup.cs file):

app.UseMvc(routes =>
{
    routes.MapRoute(
        "default",
        "{controller=Home}/{action=Index}/{id?}");
    routes.Routes.Add(
        new LandingPageRouter(routes, webrequest, memoryCache, Configuration)); 
    // this custom routes adds URLs from database
}

the issue is that if I add another route to the database after the application has started I basically get a 404 since the routing system isn't aware of this new route, I think that what I need is add the missing routes at runtime or (less convenient) restart the application pool from another web application (which has been developed on framework 4.5 and obviously it runs on a different pool)

Any other thoughts on this? thanks.


回答1:


The first question is what does database mean when you say: I add another route to the database and wether you can keep your routes in a JSON, XML or INI file.

If you can, for example, keep the routes in a JSON file, then there is possible for the routes to be dynamically available on runtime (as you can read in the ASP.NET Core Documentation)

You can find a full blog post about this here.

Assuming that routes.json is a JSON file with structure similar to the following, and is in the same folder as Startup:

{
    "route": "This is a route",
    "another-route": "This is another route",
    "default": "This is default!"
}

You can configure the Startup class in the following way:

Note that this example does not use MVC but the separate routing package, although I assume you can transpose it to work with MVC.

public class Startup
{
    public IConfiguration Configuration {get;set;}
    public Startup(IHostingEnvironment env)
    {
        var configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("routes.json", optional: false, reloadOnChange: true);

        Configuration = configurationBuilder.Build();
    }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRouting();
    }
    public void Configure(IApplicationBuilder app)
    {
        var routeBuilder = new RouteBuilder(app);

        routeBuilder.MapGet("{route}", context => 
        {
            var routeMessage = Configuration.AsEnumerable()
                .FirstOrDefault(r => r.Key == context.GetRouteValue("route")
                .ToString())
                .Value;

            var defaultMessage = Configuration.AsEnumerable()
                .FirstOrDefault(r => r.Key == "default")
                .Value;

            var response = (routeMessage != null) ? routeMessage : defaultMessage;

            return context.Response.WriteAsync(response);
        });

        app.UseRouter(routeBuilder.Build());
    }
}

At this point, while the application is running, you can modify the JSON file, save it, then because of the reloadOnChange: true parameter, the framework will reinject the new configuration into the Configuration property.

The implementation of the reload is based on a file watcher, so if you want to use a database for this - a SQL Server, then I think you have to implement this yourself.

A (not pretty at all and reminded here just for completeness) solution could be to create a console application that adds database changes in a file, then use that file in the application configuration.

Best regards!



来源:https://stackoverflow.com/questions/39460585/reload-routes-on-runtime-in-dotnetcore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!