The Wayback Machine - https://web.archive.org/web/20220124085637/https://github.com/dotnet/aspnetcore/issues/39719
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

Support for a standard router in the new one or extension of the current one with additional parameters. #39719

Open
Alerinos opened this issue Jan 24, 2022 · 0 comments

Comments

@Alerinos
Copy link

@Alerinos Alerinos commented Jan 24, 2022

Summary

I created my router to control subpages, it works only as I set it up. I need to add support for a standard router. The main assumption:
Before giving the route, it wants to search the database and then display the correct condition, if there is no record in the database, the standard router is started.

Motivation and goals

This solves seo problems, creates a nice link. Example:
domain.pl/games/counter-strike -> domain.pl/counter-strike
domain.pl/player/Alerin -> domain.pl/Alerin
Thanks to this, we have nice and short links.

Examples

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;


namespace Website;

public class ConventionRouter : IComponent, IHandleAfterRender, IDisposable
{
    RenderHandle _renderHandle;
    bool _navigationInterceptionEnabled;
    string _location;

    [Inject] private NavigationManager NavigationManager { get; set; }
    [Inject] private INavigationInterception NavigationInterception { get; set; }

    [Parameter] public RenderFragment NotFound { get; set; }
    [Parameter] public RenderFragment<RouteData> Found { get; set; }

    public void Attach(RenderHandle renderHandle)
    {
        _renderHandle = renderHandle;
        _location = NavigationManager.Uri;
        NavigationManager.LocationChanged += HandleLocationChanged;
    }

    public Task SetParametersAsync(ParameterView parameters)
    {
        parameters.SetParameterProperties(this);

        if (Found == null)
        {
            throw new InvalidOperationException($"The {nameof(ConventionRouter)} component requires a value for the parameter {nameof(Found)}.");
        }

        if (NotFound == null)
        {
            throw new InvalidOperationException($"The {nameof(ConventionRouter)} component requires a value for the parameter {nameof(NotFound)}.");
        }

        Refresh();

        return Task.CompletedTask;
    }

    public Task OnAfterRenderAsync()
    {
        if (!_navigationInterceptionEnabled)
        {
            _navigationInterceptionEnabled = true;
            return NavigationInterception.EnableNavigationInterceptionAsync();
        }

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        NavigationManager.LocationChanged -= HandleLocationChanged;
    }

    private void HandleLocationChanged(object sender, LocationChangedEventArgs args)
    {
        _location = args.Location;
        Refresh();
    }

    private void Refresh()
    {
        var relativeUri = NavigationManager.ToBaseRelativePath(_location);
        var parameters = ParseQueryString(relativeUri);

        if (relativeUri.IndexOf('?') > -1)
        {
            relativeUri = relativeUri.Substring(0, relativeUri.IndexOf('?'));
        }

        var segments = relativeUri.Trim().Split('/', StringSplitOptions.RemoveEmptyEntries);


        // domain.com/test
        if (segments.Contains("test") == true)
        {

            var pageComponentTypes = Assembly.GetExecutingAssembly()
                             .ExportedTypes;
                             //.Where(t => t.IsSubclassOf(typeof(ComponentBase))
                             //            && t.Namespace.Contains(".Pages"));

            var pageType = pageComponentTypes.SingleOrDefault(x => x.Name == "Contact");

            var routeData = new RouteData(pageType,
             parameters);


            // Return "contact" page
            _renderHandle.Render(Found(routeData));

            return;
        }
        else
        {
            // RUN standard router

            _renderHandle.Render(NotFound);
        }
    }

    private Dictionary<string, object> ParseQueryString(string uri)
    {
        var querystring = new Dictionary<string, object>();

        foreach (string kvp in uri.Substring(uri.IndexOf("?") + 1).Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
        {
            if (kvp != "" && kvp.Contains("="))
            {
                var pair = kvp.Split('=');
                querystring.Add(pair[0], pair[1]);
            }
        }

        return querystring;
    }
}

Can I ask for help how to add a standard router to this or how to get all @page attributes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant