dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.45k stars 10.03k forks source link

Custom router in Razor pages #18475

Closed marcuslindblom closed 4 years ago

marcuslindblom commented 4 years ago

In MVC I have a custom router where I look up what controller and action the request should end up in. Is it possible to use a custom router in Razor pages?

This is basically how I do it in MVC.

    public class DefaultRouter : IRouter
    {
        public DefaultRouter() {
        }
        public VirtualPathData GetVirtualPath(VirtualPathContext context)
        {
            throw new System.NotImplementedException();
        }

        public Task RouteAsync(RouteContext context)
        {
            context.RouteData.Values["Controller"] = "Hello";
            context.RouteData.Values["Action"] = "World";
            return Task.CompletedTask;
        }
    }

Is it possible to set some route value to send the request to a specific PageModel in Razor pages?

javiercn commented 4 years ago

@marcuslindblom thanks for contacting us.

@rynowak or @pranavkm can you help here?

It would help if you describe in more detail what you are trying to accomplish so that we might be able to provide an alternative option in case it is not possible.

marcuslindblom commented 4 years ago

@javiercn Basically I have a IDictionary<string, TrieNode> where the key is the a friendly url and the TrieNode has information about the controller and Id of the entity to load from the database. The urls are hierarchical and does not have the name of the controller because that information is in the TrieNode. A url is constructed by the h1 on the page and can look something like this. /always-interactive-lightning-fast-design. In my router I get the TrieNode that matches the path, sets the Controller and Action in the route data. Now, I would like to do the same thing for Razor pages and route the request to the correct Page based on the information in my dictionary.

javiercn commented 4 years ago

@marcuslindblom you could try setting the "page" in the RouteData.Values to the page path, like "/Index.cshtml"

I believe that should work, otherwise I'm not sure what other options exists, but @rynowak will know.

marcuslindblom commented 4 years ago

@javiercn @rynowak I tried something like this but it does not execute my router at all.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Test2
{
  public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting()
                .UseRouter(options => new DefaultRouter(options.DefaultHandler));

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
    public class DefaultRouter : IRouter
    {
        private readonly IRouter _next;
        public DefaultRouter(IRouter next) {
            _next = next;
        }
        public VirtualPathData GetVirtualPath(VirtualPathContext context)
        {
            throw new System.NotImplementedException();
        }

        public async Task RouteAsync(RouteContext context)
        {
            RouteData routeData = new RouteData();
            routeData.Values["page"] = "Index";
            context.RouteData = routeData;
            await _next.RouteAsync(context);
        }
    }
}
marcuslindblom commented 4 years ago

I forgot to say that I'm developing a CMS so perhaps you can understand more what I'm trying to achieve. I think it's basically a wildcard route where I look for my "page" in the database, route it correctly if it exists on the given path, or else I want to forward the request to the next registered router or endpoint.

javiercn commented 4 years ago

@mrpmorris this is not a Blazor question but an ASP.NET Core routing question. That advice doesn't apply here.

mrpmorris commented 4 years ago

@mrpmorris this is not a Blazor question but an ASP.NET Core routing question. That advice doesn't apply here.

@javiercn I thought I had the area-blazor filter on, sorry. Deleted :)

mkArtakMSFT commented 4 years ago

@rynowak can you please look into this one? Thanks!

ghost commented 4 years ago

Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!