Adding Support for LinkGeneration for named Routes.

- Adding HtmlHelpers for route link generation.
- Controller Helpers
- UrlHelper and UrlHelperExtensions
This commit is contained in:
harshgMSFT 2014-04-28 18:56:17 -07:00
parent a1f3c72e08
commit 3765abdfca
12 changed files with 481 additions and 39 deletions

View File

@ -19,7 +19,7 @@ namespace MvcSample.Web
public string Get() public string Get()
{ {
// Creates a url like: http://localhost:58195/Home/Details#CoolBeans! // Creates a url like: http://localhost:58195/Home/Details#CoolBeans!
return Url.RouteUrl(new { controller = "Home", action = "Details" }, protocol: "http", host: null, fragment: "CoolBeans!"); return Url.RouteUrl("CoolBeansRoute", new { controller = "Home", action = "Details" }, protocol: "http", host: null, fragment: "CoolBeans!");
} }
public string Link1() public string Link1()

View File

@ -27,7 +27,7 @@ namespace MvcSample.Web
new { controller = "Home", action = "Index" }); new { controller = "Home", action = "Index" });
routes.MapRoute( routes.MapRoute(
"ControllerOnlyRoute", "controllerRoute",
"{controller}", "{controller}",
new { controller = "Home" }); new { controller = "Home" });
}); });

View File

@ -7,21 +7,34 @@ namespace Microsoft.AspNet.Mvc
{ {
public class RedirectToRouteResult : ActionResult public class RedirectToRouteResult : ActionResult
{ {
public RedirectToRouteResult([NotNull] IUrlHelper urlHelper, IDictionary<string, object> routeValues) public RedirectToRouteResult([NotNull] IUrlHelper urlHelper,
: this(urlHelper, routeValues, permanent: false) object routeValues)
: this(urlHelper, routeName: null, routeValues: routeValues)
{ {
} }
public RedirectToRouteResult([NotNull] IUrlHelper urlHelper, public RedirectToRouteResult([NotNull] IUrlHelper urlHelper,
IDictionary<string, object> routeValues, bool permanent) string routeName,
object routeValues)
: this(urlHelper, routeName, routeValues, permanent: false)
{
}
public RedirectToRouteResult([NotNull] IUrlHelper urlHelper,
string routeName,
object routeValues,
bool permanent)
{ {
UrlHelper = urlHelper; UrlHelper = urlHelper;
RouteValues = routeValues; RouteName = routeName;
RouteValues = TypeHelper.ObjectToDictionary(routeValues);
Permanent = permanent; Permanent = permanent;
} }
public IUrlHelper UrlHelper { get; private set; } public IUrlHelper UrlHelper { get; private set; }
public string RouteName { get; private set; }
public IDictionary<string, object> RouteValues { get; private set; } public IDictionary<string, object> RouteValues { get; private set; }
public bool Permanent { get; private set; } public bool Permanent { get; private set; }

View File

@ -164,14 +164,34 @@ namespace Microsoft.AspNet.Mvc
TypeHelper.ObjectToDictionary(routeValues), permanent: true); TypeHelper.ObjectToDictionary(routeValues), permanent: true);
} }
public RedirectToRouteResult RedirectToRoute(string routeName)
{
return RedirectToRoute(routeName, routeValues: null);
}
public RedirectToRouteResult RedirectToRoute(object routeValues) public RedirectToRouteResult RedirectToRoute(object routeValues)
{ {
return new RedirectToRouteResult(Url, TypeHelper.ObjectToDictionary(routeValues)); return RedirectToRoute(routeName: null, routeValues: routeValues);
}
public RedirectToRouteResult RedirectToRoute(string routeName, object routeValues)
{
return new RedirectToRouteResult(Url, routeName, routeValues);
}
public RedirectToRouteResult RedirectToRoutePermanent(string routeName)
{
return RedirectToRoutePermanent(routeName, routeValues: null);
} }
public RedirectToRouteResult RedirectToRoutePermanent(object routeValues) public RedirectToRouteResult RedirectToRoutePermanent(object routeValues)
{ {
return new RedirectToRouteResult(Url, TypeHelper.ObjectToDictionary(routeValues), permanent: true); return RedirectToRoutePermanent(routeName: null, routeValues: routeValues);
}
public RedirectToRouteResult RedirectToRoutePermanent(string routeName, object routeValues)
{
return new RedirectToRouteResult(Url, routeName, routeValues, permanent: true);
} }
} }
} }

View File

@ -8,6 +8,6 @@
bool IsLocalUrl(string url); bool IsLocalUrl(string url);
string RouteUrl(object values, string protocol, string host, string fragment); string RouteUrl(string routeName, object values, string protocol, string host, string fragment);
} }
} }

View File

@ -416,6 +416,20 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new HtmlString(value == null ? null : value.ToString()); return new HtmlString(value == null ? null : value.ToString());
} }
/// <inheritdoc />
public HtmlString RouteLink(
[NotNull] string linkText,
string routeName,
string protocol,
string hostName,
string fragment,
object routeValues,
object htmlAttributes)
{
var url = _urlHelper.RouteUrl(routeName, routeValues, protocol, hostName, fragment);
return GenerateLink(linkText, url, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
/// <inheritdoc /> /// <inheritdoc />
public HtmlString ValidationMessage(string expression, string message, object htmlAttributes) public HtmlString ValidationMessage(string expression, string message, object htmlAttributes)
{ {

View File

@ -107,5 +107,104 @@ namespace Microsoft.AspNet.Mvc.Rendering
routeValues: routeValues, routeValues: routeValues,
htmlAttributes: htmlAttributes); htmlAttributes: htmlAttributes);
} }
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
object routeValues)
{
return htmlHelper.RouteLink(
linkText,
routeName: null,
protocol: null,
hostName: null,
fragment: null,
routeValues: routeValues,
htmlAttributes: null);
}
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
string routeName)
{
return htmlHelper.RouteLink(
linkText,
routeName,
protocol: null,
hostName: null,
fragment: null,
routeValues: null,
htmlAttributes: null);
}
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
string routeName,
object routeValues)
{
return htmlHelper.RouteLink(
linkText,
routeName,
protocol: null,
hostName: null,
fragment: null,
routeValues: routeValues,
htmlAttributes: null);
}
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
object routeValues,
object htmlAttributes)
{
return htmlHelper.RouteLink(
linkText,
routeName: null,
protocol: null,
hostName: null,
fragment: null,
routeValues: routeValues,
htmlAttributes: htmlAttributes);
}
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
string routeName,
object routeValues,
object htmlAttributes)
{
return htmlHelper.RouteLink(
linkText,
routeName,
protocol: null,
hostName: null,
fragment: null,
routeValues: routeValues,
htmlAttributes: htmlAttributes);
}
public static HtmlString RouteLink(
[NotNull] this IHtmlHelper htmlHelper,
[NotNull] string linkText,
string routeName,
string protocol,
string hostName,
string fragment,
object routeValues,
object htmlAttributes)
{
return htmlHelper.RouteLink(
linkText,
routeName,
protocol,
hostName,
fragment,
routeValues,
htmlAttributes);
}
} }
} }

View File

@ -358,6 +358,35 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <returns>A task that represents when rendering has completed.</returns> /// <returns>A task that represents when rendering has completed.</returns>
Task RenderPartialAsync([NotNull] string partialViewName, object model, ViewDataDictionary viewData); Task RenderPartialAsync([NotNull] string partialViewName, object model, ViewDataDictionary viewData);
/// <summary>
/// Returns an anchor element (a element) that contains a URL path to the specified route.
/// </summary>
/// <param name="linkText">The inner text of the anchor element.</param>
/// <param name="routeName">The name of the route.</param>
/// <param name="protocol">The protocol for the URL, such as &quot;http&quot; or &quot;https&quot;.</param>
/// <param name="hostName">The host name for the URL.</param>
/// <param name="fragment">The URL fragment name (the anchor name).</param>
/// <param name="routeValues">
/// An object that contains the parameters for a route. The parameters are retrieved through reflection by
/// examining the properties of the object. This object is typically created using object initializer syntax.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the route parameters.
/// </param>
/// <param name="htmlAttributes">
/// An object that contains the HTML attributes to set for the element. Alternatively, an
/// <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>
/// An anchor element (a element).
/// </returns>
HtmlString RouteLink(
[NotNull] string linkText,
string routeName,
string protocol,
string hostName,
string fragment,
object routeValues,
object htmlAttributes);
/// <summary> /// <summary>
/// Render a textarea. /// Render a textarea.
/// </summary> /// </summary>
@ -375,7 +404,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// </param> /// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns> /// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString TextArea(string name, string value, int rows, int columns, object htmlAttributes); HtmlString TextArea(string name, string value, int rows, int columns, object htmlAttributes);
/// <summary> /// <summary>
/// Render an input element of type "text". /// Render an input element of type "text".
/// </summary> /// </summary>

View File

@ -1,12 +1,10 @@
using System; 
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNet.Abstractions; using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
@ -69,21 +67,20 @@ namespace Microsoft.AspNet.Mvc
public bool IsLocalUrl(string url) public bool IsLocalUrl(string url)
{ {
return return
!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(url) &&
// Allows "/" or "/foo" but not "//" or "/\". // Allows "/" or "/foo" but not "//" or "/\".
((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) || ((url[0] == '/' && (url.Length == 1 || (url[1] != '/' && url[1] != '\\'))) ||
// Allows "~/" or "~/foo". // Allows "~/" or "~/foo".
(url.Length > 1 && url[0] == '~' && url[1] == '/')); (url.Length > 1 && url[0] == '~' && url[1] == '/'));
} }
public string RouteUrl(object values, string protocol, string host, string fragment) public string RouteUrl(string routeName, object values, string protocol, string host, string fragment)
{ {
var valuesDictionary = TypeHelper.ObjectToDictionary(values); var valuesDictionary = TypeHelper.ObjectToDictionary(values);
var path = GeneratePathFromRoute(routeName, valuesDictionary);
var path = GeneratePathFromRoute(valuesDictionary);
if (path == null) if (path == null)
{ {
return null; return null;
@ -94,7 +91,12 @@ namespace Microsoft.AspNet.Mvc
private string GeneratePathFromRoute(IDictionary<string, object> values) private string GeneratePathFromRoute(IDictionary<string, object> values)
{ {
var context = new VirtualPathContext(_httpContext, _ambientValues, values); return GeneratePathFromRoute(routeName: null, values: values);
}
private string GeneratePathFromRoute(string routeName, IDictionary<string, object> values)
{
var context = new VirtualPathContext(_httpContext, _ambientValues, values, routeName);
var path = _router.GetVirtualPath(context); var path = _router.GetVirtualPath(context);
if (path == null) if (path == null)
{ {
@ -123,7 +125,7 @@ namespace Microsoft.AspNet.Mvc
return GenerateClientUrl(_httpContext.Request.PathBase, contentPath); return GenerateClientUrl(_httpContext.Request.PathBase, contentPath);
} }
private static string GenerateClientUrl([NotNull] PathString applicationPath, private static string GenerateClientUrl([NotNull] PathString applicationPath,
[NotNull] string path) [NotNull] string path)
{ {
if (path.StartsWith("~/", StringComparison.Ordinal)) if (path.StartsWith("~/", StringComparison.Ordinal))
@ -132,12 +134,11 @@ namespace Microsoft.AspNet.Mvc
return applicationPath.Add(segment).Value; return applicationPath.Add(segment).Value;
} }
return path; return path;
} }
private string GenerateUrl(string protocol, string host, string path, string fragment) private string GenerateUrl(string protocol, string host, string path, string fragment)
{ {
// We should have a robust and centrallized version of this code. See HttpAbstractions#28 // We should have a robust and centrallized version of this code. See HttpAbstractions#28
Contract.Assert(path != null); Contract.Assert(path != null);
var url = path; var url = path;
@ -167,4 +168,4 @@ namespace Microsoft.AspNet.Mvc
} }
} }
} }
} }

View File

@ -56,17 +56,31 @@
public static string RouteUrl([NotNull] this IUrlHelper helper, object values) public static string RouteUrl([NotNull] this IUrlHelper helper, object values)
{ {
return helper.RouteUrl(values, protocol: null, host: null, fragment: null); return helper.RouteUrl(routeName: null, values: values, protocol: null, host: null, fragment: null);
} }
public static string RouteUrl([NotNull] this IUrlHelper helper, object values, string protocol) public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName)
{ {
return helper.RouteUrl(values, protocol, host: null, fragment: null); return helper.RouteUrl(routeName, values: null, protocol: null, host: null, fragment: null);
} }
public static string RouteUrl([NotNull] this IUrlHelper helper, object values, string protocol, string host) public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName, object values)
{ {
return helper.RouteUrl(values, protocol, host, fragment: null); return helper.RouteUrl(routeName, values, protocol: null, host: null, fragment: null);
}
public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName, object values, string protocol)
{
return helper.RouteUrl(routeName, values, protocol, host: null, fragment: null);
}
public static string RouteUrl([NotNull] this IUrlHelper helper,
string routeName,
object values,
string protocol,
string host)
{
return helper.RouteUrl(routeName, values, protocol, host, fragment: null);
} }
} }
} }

View File

@ -26,7 +26,9 @@ namespace Microsoft.AspNet.Mvc.Core
new Dictionary<string, object>(), new Dictionary<string, object>(),
new ActionDescriptor()); new ActionDescriptor());
IUrlHelper urlHelper = GetMockUrlHelper(expectedUrl); IUrlHelper urlHelper = GetMockUrlHelper(expectedUrl);
RedirectToRouteResult result = new RedirectToRouteResult(urlHelper, TypeHelper.ObjectToDictionary(values)); RedirectToRouteResult result = new RedirectToRouteResult(urlHelper,
null,
TypeHelper.ObjectToDictionary(values));
// Act // Act
await result.ExecuteResultAsync(actionContext); await result.ExecuteResultAsync(actionContext);
@ -50,7 +52,9 @@ namespace Microsoft.AspNet.Mvc.Core
new ActionDescriptor()); new ActionDescriptor());
IUrlHelper urlHelper = GetMockUrlHelper(returnValue: null); IUrlHelper urlHelper = GetMockUrlHelper(returnValue: null);
RedirectToRouteResult result = new RedirectToRouteResult(urlHelper, new Dictionary<string, object>()); RedirectToRouteResult result = new RedirectToRouteResult(urlHelper,
null,
new Dictionary<string, object>());
// Act & Assert // Act & Assert
ExceptionAssert.ThrowsAsync<InvalidOperationException>( ExceptionAssert.ThrowsAsync<InvalidOperationException>(
@ -81,7 +85,7 @@ namespace Microsoft.AspNet.Mvc.Core
private static IUrlHelper GetMockUrlHelper(string returnValue) private static IUrlHelper GetMockUrlHelper(string returnValue)
{ {
var urlHelper = new Mock<IUrlHelper>(); var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(o => o.RouteUrl(It.IsAny<object>(), It.IsAny<string>(), urlHelper.Setup(o => o.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue); It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue);
return urlHelper.Object; return urlHelper.Object;
} }

View File

@ -12,8 +12,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
[Theory] [Theory]
[InlineData("", "/Home/About", "/Home/About")] [InlineData("", "/Home/About", "/Home/About")]
[InlineData("/myapproot", "/test", "/test")] [InlineData("/myapproot", "/test", "/test")]
public void Content_ReturnsContentPath_WhenItDoesNotStartWithToken(string appRoot, public void Content_ReturnsContentPath_WhenItDoesNotStartWithToken(string appRoot,
string contentPath, string contentPath,
string expectedPath) string expectedPath)
{ {
// Arrange // Arrange
@ -36,8 +36,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test
[InlineData("/myapproot", "~/", "/myapproot/")] [InlineData("/myapproot", "~/", "/myapproot/")]
[InlineData("", "~/Home/About", "/Home/About")] [InlineData("", "~/Home/About", "/Home/About")]
[InlineData("/myapproot", "~/", "/myapproot/")] [InlineData("/myapproot", "~/", "/myapproot/")]
public void Content_ReturnsAppRelativePath_WhenItStartsWithToken(string appRoot, public void Content_ReturnsAppRelativePath_WhenItStartsWithToken(string appRoot,
string contentPath, string contentPath,
string expectedPath) string expectedPath)
{ {
// Arrange // Arrange
@ -247,22 +247,223 @@ namespace Microsoft.AspNet.Mvc.Core.Test
Assert.False(result); Assert.False(result);
} }
[Fact]
public void RouteUrlWithDictionary()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}));
// Assert
Assert.Equal("/app/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithEmptyHostName()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}),
protocol: "http",
host: string.Empty);
// Assert
Assert.Equal("http://localhost/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithEmptyProtocol()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}),
protocol: string.Empty,
host: "foo.bar.com");
// Assert
Assert.Equal("http://foo.bar.com/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithNullProtocol()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}),
protocol: null,
host: "foo.bar.com");
// Assert
Assert.Equal("http://foo.bar.com/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithNullProtocolAndNullHostName()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}),
protocol: null,
host: null);
// Assert
Assert.Equal("/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithObjectProperties()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(new { Action = "newaction", Controller = "home2", id = "someid" });
// Assert
Assert.Equal("/app/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithProtocol()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new
{
Action = "newaction",
Controller = "home2",
id = "someid"
},
protocol: "https");
// Assert
Assert.Equal("https://localhost/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithRouteNameAndDefaults()
{
// Arrange
var routeCollection = GetRouteCollection("MyRouteName", "any/url");
var urlHelper = CreateUrlHelper("/app", routeCollection);
// Act
var url = urlHelper.RouteUrl("MyRouteName");
// Assert
Assert.Equal("/app/any/url", url);
}
[Fact]
public void RouteUrlWithRouteNameAndDictionary()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new RouteValueDictionary(
new
{
Action = "newaction",
Controller = "home2",
id = "someid"
}));
// Assert
Assert.Equal("/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithRouteNameAndObjectProperties()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(routeName: "namedroute",
values: new
{
Action = "newaction",
Controller = "home2",
id = "someid"
});
// Assert
Assert.Equal("/app/named/home2/newaction/someid", url);
}
private static HttpContext CreateHttpContext(string appRoot) private static HttpContext CreateHttpContext(string appRoot)
{ {
var appRootPath = new PathString(appRoot); var appRootPath = new PathString(appRoot);
var request = new Mock<HttpRequest>(); var request = new Mock<HttpRequest>();
request.SetupGet(r => r.PathBase) request.SetupGet(r => r.PathBase)
.Returns(appRootPath); .Returns(appRootPath);
request.SetupGet(r => r.Host)
.Returns(new HostString("localhost"));
var context = new Mock<HttpContext>(); var context = new Mock<HttpContext>();
context.SetupGet(c => c.Request) context.SetupGet(c => c.Request)
.Returns(request.Object); .Returns(request.Object);
return context.Object; return context.Object;
} }
private static IContextAccessor<ActionContext> CreateActionContext(HttpContext context) private static IContextAccessor<ActionContext> CreateActionContext(HttpContext context)
{
return CreateActionContext(context, (new Mock<IRouter>()).Object);
}
private static IContextAccessor<ActionContext> CreateActionContext(HttpContext context, IRouter router)
{ {
var actionContext = new ActionContext(context, var actionContext = new ActionContext(context,
Mock.Of<IRouter>(), router,
new Dictionary<string, object>(), new Dictionary<string, object>(),
new ActionDescriptor()); new ActionDescriptor());
var contextAccessor = new Mock<IContextAccessor<ActionContext>>(); var contextAccessor = new Mock<IContextAccessor<ActionContext>>();
@ -296,5 +497,52 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict); var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict);
return new UrlHelper(contextAccessor, actionSelector.Object); return new UrlHelper(contextAccessor, actionSelector.Object);
} }
private static UrlHelper CreateUrlHelper(string appBase, IRouter router)
{
var context = CreateHttpContext(appBase);
var actionContext = CreateActionContext(context, router);
var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict);
return new UrlHelper(actionContext, actionSelector.Object);
}
private static UrlHelper CreateUrlHelperWithRouteCollection(string appPrefix)
{
var routeCollection = GetRouteCollection();
return CreateUrlHelper("/app", routeCollection);
}
private static RouteCollection GetRouteCollection()
{
return GetRouteCollection("mockRoute", "/mockTemplate");
}
private static RouteCollection GetRouteCollection(string mockRouteName, string mockTemplateValue)
{
var rt = new RouteCollection();
var target = new Mock<IRouter>(MockBehavior.Strict);
target
.Setup(e => e.GetVirtualPath(It.IsAny<VirtualPathContext>()))
.Callback<VirtualPathContext>(c => c.IsBound = true)
.Returns<VirtualPathContext>(rc => null);
rt.DefaultHandler = target.Object;
rt.MapRoute(string.Empty,
"{controller}/{action}/{id}",
new RouteValueDictionary(new { id = "defaultid" }));
rt.MapRoute("namedroute",
"named/{controller}/{action}/{id}",
new RouteValueDictionary(new { id = "defaultid" }));
var mockHttpRoute = new Mock<IRouter>();
mockHttpRoute.Setup(mock =>
mock.GetVirtualPath(It.Is<VirtualPathContext>(c => string.Equals(c.RouteName,
mockRouteName)
)))
.Returns(mockTemplateValue);
rt.Add(mockHttpRoute.Object);
return rt;
}
} }
} }