Найти класс компонентов Blazor, соответствующий заданному пути - PullRequest
0 голосов
/ 11 февраля 2020

В приложении сервера Blazor, как я могу найти класс (возвращаемый как Type) компонента бритвы, который соответствует заданному пути (в string, скажем "/controller/action")? Я не хочу переходить на реальную страницу; Я только wi sh, чтобы найти соответствующий класс и выполнить некоторые вещи типа отражения с ним. Мне кажется, что способ, которым Blazor обрабатывает маршрут, сильно отличается от способа MVC, и я не мог найти какую-либо документацию, которая может помочь.

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Вы можете использовать отражение, чтобы найти все компоненты с атрибутом RouteAttribute. Директива @page преобразуется в RouteAttribute.

var pageTypeList = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttribute(typeof(Microsoft.AspNetCore.Components.RouteAttribute)) != null);
0 голосов
/ 11 февраля 2020

После тщательного изучения исходного кода, предоставленного agua от mars, я пришел к следующему решению. Первый шаг - получить объект Router, созданный средой Blazor, и я делаю это, используя CascadingValue в моем App.razor:

<Router AppAssembly="@typeof(Program).Assembly" @ref="router">
    <Found Context="routeData">
        <CascadingValue Value="@router">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                ...
            </RouteView>
        </CascadingValue>
    </Found>
    <NotFound>
         ...
    </NotFound>
</Router>

@code {
    private Router router;
}

Так что теперь на любой странице моего приложения я могу получить объект Router, используя CascadingParameterAttribute. Далее следует рефлексия (поскольку многие вещи, которые здесь задействованы, определены как internal):

public Type Find(Router router, string path) {
    var assm = typeof(Router).Assembly;
    var routes = typeof(Router).GetProperty("Routes", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(router);
    var type = assm.GetTypes().FirstOrDefault(t => t.Name == "RouteContext");
    var context = Activator.CreateInstance(type, new[] { path });
    routes.GetType().GetMethod("Route", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(routes, new[] { context });
    return type.GetProperty("Handler").GetValue(context) as Type;
}

И эта функция достигает именно того, что мне нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...