Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routing enhancements #5489

Closed
SteveSandersonMS opened this issue Mar 19, 2018 · 31 comments
Closed

Routing enhancements #5489

SteveSandersonMS opened this issue Mar 19, 2018 · 31 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one

Comments

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Mar 19, 2018

This issue is to track routing features we're likely to want to add in the future:

  • Review exactly which parameter constraints we really want to support. For example maybe add regex; maybe remove bool or limit the set of datetime formats more precisely. See Basic route constraints (:int, etc.) blazor#295 for more discussion.
  • Catch-all segments (e.g., /products/{*categoryAndName})
  • 404 handler (it's probably not enough just to have a component that matches /{*anythingElse}, because for SSR you'd want to know it's really not a match so you could actually return a 404) - Done!
  • Simple method for accessing querystring/hash values (e.g., via new properties on IUriHelper)
  • Multiple nested routers
  • Outbound URL generation (e.g., <a page=@About>About us</a>, or perhaps just by codegenning methods like <a href=@Products.Url(53)>Duck boots</a> for each @page declaration)
  • In the @page directive, allow the use of compile-time constant expressions, not just literal strings (e.g., https://github.com/aspnet/blazor/issues/1363).
  • Optional route parameters

Also the items from dotnet/blazor#636 that were not yet finalised:

  • Discover [Route] attributes on types in referenced assemblies that themselves reference Microsoft.AspNetCore.Blazor transitively
  • Discover [Route] attributes on component base classes (i.e., inherit=true)
  • In the Router component, make it simple to subclass and override a virtual method to change the logic for locating the IComponent for a given URL. Currently there's no virtual method for this.
  • Make RouteTable's Routes property get-only
  • Cache route tables per assembly
@kristapsstrals
Copy link

@SteveSandersonMS Thanks for raising this!

@grahamehorner
Copy link
Contributor

is a routine regex constraint on the road map?

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Mar 20, 2018

Regex constraints: definitely maybe :) We're not in a rush to put in all possible constraints because in practice it's rare that you really need them, so they end up just being friction for developers. It's often only server-side API endpoints that need to be strict about that. It's a matter of seeing what scenarios evolve and what kinds of feature requests we're getting from a wide range of people.

@dlr1
Copy link

dlr1 commented Mar 24, 2018

Would it be possible to define all the routes and destinations in a single place like in other JS frameworks?

@conficient
Copy link
Contributor

@dlr1 I believe the routing engine is pluggable so you can replace with any other system you desire.

@Nathan-Ryan
Copy link

@dlr1 with the ability to nest routes too, perhaps similar to the way angular works with the router-outlet component.

@TheAifam5
Copy link

Also saving states for every route would be nice feature to have ;)

@bastienJS
Copy link

Please replace 'Multiple nested routers' with 'Unlimited nested routers' else we get the same dilemma they found out later in angular 2 that the router`s nesting skills were limited to sth. like 3 child routers :P

@dlr1
Copy link

dlr1 commented May 29, 2018

It would be nice to have some virtual methods that are called at appropriate time to either allow navigation to a page or to dis-allow navigation from a page

@DNF-SaS
Copy link

DNF-SaS commented Jun 8, 2018

@SteveSandersonMS
Is it possible to restrict the routing from a certain slug onwards?
(e.g. everything below http://myserver/blazor will be processed, but e.g. http://myserver/otherdata won't?)

@danroth27
Copy link
Member

@DNF-SaS I believe your looking for support for catch-all segments, which hasn't been implemented yet.

@conficient
Copy link
Contributor

Is there anything tracking how routes behave if a user is unauthenticated vs authenticated? In MVC we can use filters on controllers to create secure routes and insecure routes.

@danroth27
Copy link
Member

@conficient Not currently.

@rpedretti
Copy link

rpedretti commented Aug 20, 2018

I'm building a Bing Maps component and it generates lots of anchor tags with href="#". As of version 0.5.1 whenever I click any of those links i get redirected to /. Is there a way to proper handle this?

@RyoukoKonpaku
Copy link
Contributor

@rpedretti for now you don't have a choice but to use JS interop since stopping the click even to propagate isn't possible yet and is tracked here #1073. If I remember you'd need the event that called the click and prevent it propagating via event.stopPropagation() method.

@rpedretti
Copy link

Thanki you @RyoukoKonpaku! Worked like a charm!

@TheFanatr
Copy link

Is there any way to manually implement 404 handling at the moment? Is this just a case of changing some logic in the routing system or would it require some more profound changes? It would be very useful for a project that I am working on.

@TheFanatr
Copy link

After combing through some of Blazor's codebase, I think I have a reasonable idea of what needs to be done; would a pull request for something like this be considered, or is it too small? It needs to be made either way for my purposes, but I'd love to submit it to the project if I actually get it working.

@TheFanatr
Copy link

I got this to work.

<Router AppAssembly=typeof(Program).Assembly FallbackRoute="/404"/>

Basically, if the router detects that a certain route doesn't exist, it will try to render the route described by FallbackRoute and if FallbackRoute is null or nonexistent, the regular behaviour will be observed, with the only difference being that the exception text will say that it cannot find any component with the fallback route '/<fallback>'.

Also, I specifically made it so that URI displayed by the browser is still what was navigated to originally so that some interop can be done to have behaviour specific to a certain nonexistent URI, such as redirecting if a page moved.

I will make a pull request and post the link here.

@marinasundstrom
Copy link

Will there be some way of configuring the router in Startup?

For instance, I want to be able to add handlers that hook into the router and determine whether a component actually should render, like in the case of authentication.

@SteveSandersonMS
Copy link
Member Author

Yes, the idea is that you'll be able to subclass Router and override a method to put in whatever logic you want to control the URL->component mapping.

@ThaDaVos
Copy link

Any ETA when you'll be able to add sort of router hooks for authentication?
Currently checking per page and redirecting when needed...

@shawty
Copy link

shawty commented Nov 1, 2018

The ability t attach a user defined object to each route, the same way it can be done in Aurelia would be nice :-)

EG:

Routes[]{name: "index",display: "Index Page",ID: "ID123", showInNav: true,....., userdata: { something, something, something } }

In Aurelia for example, I often use this approach to add roles to a specific route. I then intercept the before navigation event, and compare the roles on the route, to those loaded from the users session, and use that to decide if pages are accessible or not.

There are many other use cases too, such as route language, and dynamic routes.

@marinasundstrom
Copy link

@shawty But then, it is possible that the community will come up with alternative routing libraries, that suit different styles, needs and purposes. It is not a given that Microsoft will handle all the cases. It is a modular and extendable framework.

I'm thinking about building my own routing system that is service-based and configurable from, for instance, Startup.

@shawty
Copy link

shawty commented Nov 1, 2018

@RobertSundstrom This is true, and I get that :-) I was actually toying with the idea myself.

I do however need to dig into the routing system and take a good look before I do anything else, and (cough, cough blazor devs...) some in depth tech docs on the router on "blazor.net" would be usefull :-)

There are a million ways this could be done, but having just this small feature would be imensly helpfull even to those that are building custom routing systems I think.

@danroth27
Copy link
Member

@javiercn

@aspnet-hello aspnet-hello transferred this issue from dotnet/blazor Dec 17, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018
@aspnet-hello aspnet-hello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one labels Dec 17, 2018
@iron9light
Copy link

@SteveSandersonMS Support subfix with catch-all routing.
Something like this: "{controller}/{**path}/{action}"

@LukeTOBrien
Copy link

LukeTOBrien commented May 9, 2019

Just to add my 2 cent to this.
With ref to what @Nathan-Ryan said

similar to the way angular works with the router-outlet component.

I use router-outlet in my Angular apps.
In my apps I have the main outlet and a dialog outlet, this dialog outlet is then navigated to/populated in code and then I have CSS that presents the dialog as a modal.

I don't know what method anyone else would do for modal dialogs in Blazor or Angular, but this is how I do them and it works well.

So in my app.html I have:

<router-outlet></router-outlet>
<router-outlet name="dialog"></router-outlet>

And then to open a modal dialog (such as the new dialog in this case):

this.router.navigate([{
  outlets: { dialog: 'new-dialog' }
}]);

In fact I have a class called Dialog which all the dialogs (new, open, save...) inherit from:
(I use Bulma and jQuery encase anyone was wondering)

export class Dialog {
    @ViewChild('modal') modalRef: ElementRef
    modal: any;

    constructor(public router: Router) {

    }

    initModal() {
        this.modal = $(this.modalRef.nativeElement);
        this.modal.addClass('is-active');
        this.modal.find('.delete').on('click', () => {
          this.closeModal();
        });
    }

    closeModal() {
        this.modal.removeClass('is-active');
        return this.router.navigate([{
          outlets: { dialog: null }
        }]);
      }
}

I don't know if this helps or is off topic, but I thought it might help to see how others are working.
So yeah I think something similar to router-outlets will be beneficial.

@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@CornedBee
Copy link

Router should be more flexible in determining what components it looks at. Currently it simply takes a single assembly and searches that and its dependencies. I think it would be nice if the line var types = ComponentResolver.ResolveComponents(AppAssembly); would be turned into an overridable function. Then I could, for example, determine the set of types to look at based on configuration files or similar.

@mkArtakMSFT
Copy link
Member

@SteveSandersonMS given the many aspects being touched in this issue I'm going to close it now. Please file separate issues for things which are still valid and important.

@mrpmorris
Copy link

Allowing custom coded constraints would be nice!

@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Projects
None yet
Development

No branches or pull requests