namespace Kit.Helpers.Routes { using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Constraints; public class BodyConstraint : IRouteConstraint, IParameterPolicy { private readonly bool _required; public BodyConstraint(bool required) { _required = required; } public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { bool hasBody = string.IsNullOrWhiteSpace(httpContext?.Request.ContentType) == false; return _required == hasBody; } } public class RouteFluent : IEndPointFluent { public Route Route { get; set; } public RouteFluent NeedHttpGet(bool required = true) { this.Route.Constraints.SetByKey("httpMethod", new HttpMethodRouteConstraint("GET")); return this; } public string GetMethod() { if (IsMethodPost()) return "POST"; if (IsMethodPut()) return "PUT"; if (IsMethodDelete()) return "DELETE"; return "GET"; } public bool IsMethodNotSpecified() { return this.Route.Constraints.ContainsKey("httpMethod") == false; } public bool IsMethodGet() { if (this.Route.Constraints.ContainsKey("httpMethod") == false) return false; return (this.Route.Constraints.GetByKey("httpMethod") as HttpMethodRouteConstraint)!.AllowedMethods.Contains("GET"); } public RouteFluent NeedHttpPost(bool required = true) { this.Route.Constraints.SetByKey("httpMethod", new HttpMethodRouteConstraint("POST")); return this; } public bool IsMethodPost() { if (this.Route.Constraints.ContainsKey("httpMethod") == false) return false; return (this.Route.Constraints.GetByKey("httpMethod") as HttpMethodRouteConstraint)!.AllowedMethods.Contains("POST"); } public RouteFluent NeedHttpPut(bool required = true) { this.Route.Constraints.SetByKey("httpMethod", new HttpMethodRouteConstraint("PUT")); return this; } public bool IsMethodPut() { if (this.Route.Constraints.ContainsKey("httpMethod") == false) return false; return (this.Route.Constraints.GetByKey("httpMethod") as HttpMethodRouteConstraint)!.AllowedMethods.Contains("PUT"); } public RouteFluent NeedHttpDelete(bool required = true) { this.Route.Constraints.SetByKey("httpMethod", new HttpMethodRouteConstraint("DELETE")); return this; } public bool IsMethodDelete() { if (this.Route.Constraints.ContainsKey("httpMethod") == false) return false; return (this.Route.Constraints.GetByKey("httpMethod") as HttpMethodRouteConstraint)!.AllowedMethods.Contains("DELETE"); } public RouteFluent NeedSecurityKey(string securityKeyName) { this.Route.DataTokens["APP_SecurityKeyName"] = securityKeyName; return this; } public RouteFluent WithBody(bool required = true) { this.Route.Constraints.SetByKey("withBody", new BodyConstraint(required)); return this; } public RouteFluent ForbidForReadonly(bool value = true) { this.Route.DataTokens["forbidForReadonly"] = value; return this; } public RouteFluent WithDefaults(object defaults) { if (defaults == null) return this; foreach (var pair in new RouteValueDictionary(defaults)) { this.Route.Defaults.Add(pair.Key, pair.Value); } return this; } public RouteFluent WithConstraints(object constraints) { if (constraints == null) return this; foreach (var pair in new RouteValueDictionary(constraints)) { this.Route.Constraints.SetByKey(pair.Key, (IRouteConstraint)pair.Value); } return this; } public RouteFluent WithNamespaces(string[] namespaces) { if (namespaces == null) return this; this.Route.DataTokens["Namespaces"] = namespaces; return this; } public RouteFluent WithDataTokens(object dataTokens) { if (dataTokens == null) return this; foreach (var pair in new RouteValueDictionary(dataTokens)) { this.Route.DataTokens[pair.Key] = pair.Value; } return this; } } }