133 lines
5.0 KiB
C#
133 lines
5.0 KiB
C#
namespace Kit.Helpers.Routes
|
|
{
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System;
|
|
using System.Reflection;
|
|
|
|
public class ControllerMethod
|
|
{
|
|
public string Name { get; }
|
|
public string Controller { get; }
|
|
public string RouteTemplate { get; }
|
|
public string Method => _route.GetMethod();
|
|
public MethodInfo MethodInfo { get; }
|
|
public RouteValueDictionary RouteDataTokens
|
|
{
|
|
get
|
|
{
|
|
var result = new RouteValueDictionary();
|
|
_route.Route.DataTokens?.ForEach(x => result.Add(x.Key, x.Value));
|
|
return result;
|
|
}
|
|
}
|
|
private RouteFluent _route { get; }
|
|
public ControllerMethod(string name, MethodInfo methodInfo, RouteFluent route)
|
|
{
|
|
MethodInfo = methodInfo;
|
|
_route = route;
|
|
|
|
Name = name;
|
|
Controller = _route.Route?.Defaults["controller"]?.ToString() ?? string.Empty;
|
|
RouteTemplate = _route.Route?.RouteTemplate ?? string.Empty;
|
|
}
|
|
}
|
|
|
|
public static class RouteHelper_Extensions
|
|
{
|
|
public static List<ControllerMethod> ControllerMethods = new List<ControllerMethod>();
|
|
|
|
private static IInlineConstraintResolver CreateInlineConstraintResolver(IServiceProvider serviceProvider)
|
|
{
|
|
var inlineConstraintResolver = serviceProvider
|
|
.GetRequiredService<IInlineConstraintResolver>();
|
|
|
|
var parameterPolicyFactory = serviceProvider
|
|
.GetRequiredService<ParameterPolicyFactory>();
|
|
|
|
// This inline constraint resolver will return a null constraint for non-IRouteConstraint
|
|
// parameter policies so Route does not error
|
|
return new BackCompatInlineConstraintResolver(inlineConstraintResolver, parameterPolicyFactory);
|
|
}
|
|
|
|
internal class NullRouteConstraint : IRouteConstraint
|
|
{
|
|
public static readonly NullRouteConstraint Instance = new NullRouteConstraint();
|
|
|
|
private NullRouteConstraint()
|
|
{
|
|
}
|
|
|
|
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
private class BackCompatInlineConstraintResolver : IInlineConstraintResolver
|
|
{
|
|
private readonly IInlineConstraintResolver _inner;
|
|
private readonly ParameterPolicyFactory _parameterPolicyFactory;
|
|
|
|
public BackCompatInlineConstraintResolver(IInlineConstraintResolver inner, ParameterPolicyFactory parameterPolicyFactory)
|
|
{
|
|
_inner = inner;
|
|
_parameterPolicyFactory = parameterPolicyFactory;
|
|
}
|
|
|
|
public IRouteConstraint ResolveConstraint(string inlineConstraint)
|
|
{
|
|
var routeConstraint = _inner.ResolveConstraint(inlineConstraint);
|
|
if (routeConstraint != null)
|
|
{
|
|
return routeConstraint;
|
|
}
|
|
|
|
var parameterPolicy = _parameterPolicyFactory.Create(null, inlineConstraint);
|
|
if (parameterPolicy != null)
|
|
{
|
|
// Logic inside Route will skip adding NullRouteConstraint
|
|
return NullRouteConstraint.Instance;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
public static RouteFluent AddRoute(this IRouteBuilder routeBuilder, string name, string url, string controller, string action, MethodInfo methodInfo)
|
|
{
|
|
var inline = CreateInlineConstraintResolver(routeBuilder.ServiceProvider);
|
|
var route = new Route(routeBuilder.DefaultHandler, name, url, new RouteValueDictionary(new { controller = controller, action = action }), null, null, inline);
|
|
routeBuilder.Routes.Add(route);
|
|
var result = new RouteFluent { Route = route };
|
|
ControllerMethods.Add(new ControllerMethod(name, methodInfo, result));
|
|
return result;
|
|
}
|
|
|
|
public static ControllerBaseRouteFluent<TController> AddControllerBase<TController>(this IRouteBuilder routeTable)
|
|
where TController : ControllerBase
|
|
{
|
|
return new ControllerBaseRouteFluent<TController>(routeTable);
|
|
}
|
|
|
|
public static ControllerRouteFluent<TController> AddController<TController>(this IRouteBuilder routeTable)
|
|
where TController : Controller
|
|
{
|
|
return new ControllerRouteFluent<TController>(routeTable);
|
|
}
|
|
|
|
public static RouteBase GetBaseRoute(this ControllerContext context)
|
|
{
|
|
return context.GetBaseRoute();
|
|
}
|
|
|
|
public static bool GetForbidForReadonly(this RouteData route)
|
|
{
|
|
return (route.DataTokens["forbidForReadonly"] as bool?) ?? false;
|
|
}
|
|
}
|
|
} |