Skip to content

Commit

Permalink
Add extension methods on IRouteValues to simplify MVC/Razor Pages ind…
Browse files Browse the repository at this point in the history
…ependent code
  • Loading branch information
daviddotcs committed Jul 31, 2022
1 parent afb31f2 commit fcfecd9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
46 changes: 46 additions & 0 deletions src/SafeRouting.Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ public static RedirectToPageResult Redirect(this IPageRouteValues route, PageMod
public static RedirectToActionResult Redirect(this IControllerRouteValues route, PageModel page)
=> page.RedirectToAction(route.ActionName, route.ControllerName, route.RouteValues);

/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="route"/>.
/// </summary>
/// <param name="route">The <see cref="IRouteValues"/> to redirect to.</param>
/// <param name="page">The <see cref="PageModel"/>.</param>
/// <returns>The <see cref="ActionResult"/>.</returns>
public static ActionResult Redirect(this IRouteValues route, PageModel page)
=> route switch
{
IControllerRouteValues controllerRoute => Redirect(controllerRoute, page),
IPageRouteValues pageRoute => Redirect(pageRoute, page),
_ => page.RedirectToRoute(route.RouteValues)
};

/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="route"/>.
/// </summary>
Expand All @@ -45,6 +59,20 @@ public static RedirectToPageResult Redirect(this IPageRouteValues route, Control
public static RedirectToActionResult Redirect(this IControllerRouteValues route, ControllerBase controller)
=> controller.RedirectToAction(route.ActionName, route.ControllerName, route.RouteValues);

/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="route"/>.
/// </summary>
/// <param name="route">The <see cref="IRouteValues"/> to redirect to.</param>
/// <param name="controller">The <see cref="ControllerBase"/>.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public static ActionResult Redirect(this IRouteValues route, ControllerBase controller)
=> route switch
{
IControllerRouteValues controllerRoute => Redirect(controllerRoute, controller),
IPageRouteValues pageRoute => Redirect(pageRoute, controller),
_ => controller.RedirectToRoute(route.RouteValues)
};

/// <summary>
/// Generates a URL with a relative path for the specified <paramref name="route"/>.
/// </summary>
Expand All @@ -70,4 +98,22 @@ public static RedirectToActionResult Redirect(this IControllerRouteValues route,
/// <remarks>The value of host should be a trusted value. Relying on the value of the current request can allow untrusted input to influence the resulting URI unless the Host header has been validated. See the deployment documentation for instructions on how to properly validate the Host header in your deployment environment.</remarks>
public static string? Url(this IControllerRouteValues route, IUrlHelper url, string? protocol = null, string? host = null, string? fragment = null)
=> url.Action(route.ActionName, route.ControllerName, route.RouteValues, protocol, host, fragment);

/// <summary>
/// Generates a URL with a relative path for the specified <paramref name="route"/>.
/// </summary>
/// <param name="route">The <see cref="IRouteValues"/> to generate the url for.</param>
/// <param name="url">The <see cref="IUrlHelper"/>.</param>
/// <param name="protocol">The protocol for the URL, such as "http" or "https".</param>
/// <param name="host">The host name for the URL.</param>
/// <param name="fragment">The fragment for the URL.</param>
/// <returns>The generated URL.</returns>
/// <remarks>The value of host should be a trusted value. Relying on the value of the current request can allow untrusted input to influence the resulting URI unless the Host header has been validated. See the deployment documentation for instructions on how to properly validate the Host header in your deployment environment.</remarks>
public static string? Url(this IRouteValues route, IUrlHelper url, string? protocol = null, string? host = null, string? fragment = null)
=> route switch
{
IControllerRouteValues controllerRoute => Url(controllerRoute, url, protocol, host, fragment),
IPageRouteValues pageRoute => Url(pageRoute, url, protocol, host, fragment),
_ => url.RouteUrl(routeName: null, route.RouteValues, protocol, host, fragment)
};
}
17 changes: 5 additions & 12 deletions src/SafeRouting.Common/TagHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using SafeRouting.Extensions;

namespace SafeRouting.TagHelpers;

Expand Down Expand Up @@ -47,22 +48,14 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
_ => null
};

if (urlAttributeName is null)
if (urlAttributeName is null
|| ForRoute is null
|| ForRoute.Url(Url) is not string url)
{
return;
}

var url = ForRoute switch
{
IControllerRouteValues controllerRoute => Extensions.RouteValueExtensions.Url(controllerRoute, Url),
IPageRouteValues pageRoute => Extensions.RouteValueExtensions.Url(pageRoute, Url),
_ => null
};

if (url is not null)
{
output.Attributes.SetAttribute(urlAttributeName, url);
}
output.Attributes.SetAttribute(urlAttributeName, url);
}

private IUrlHelper Url => urlHelperFactory.GetUrlHelper(ViewContext);
Expand Down

0 comments on commit fcfecd9

Please sign in to comment.