Introducing UrlActionContext and UrlRouteContext, and updating IUrlHelper accordingly

This commit is contained in:
Youngjune Hong 2015-02-02 13:49:28 -08:00
parent ac6a1a6a80
commit c7d09d7ad7
17 changed files with 429 additions and 119 deletions

View File

@ -9,17 +9,12 @@ namespace Microsoft.AspNet.Mvc
public interface IUrlHelper
{
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// controller name, route values, protocol to use, host name and fragment.
/// Generates a fully qualified or absolute URL specified by <see cref="Mvc.UrlActionContext"/> for an action
/// method, which contains action name, controller name, route values, protocol to use, host name, and fragment.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <param name="values">An object that contains the parameters for a route.</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>
/// <param name="actionContext">The context object for the generated URLs for an action method.</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
string Action(string action, string controller, object values, string protocol, string host, string fragment);
string Action([NotNull] UrlActionContext actionContext);
/// <summary>
/// Converts a virtual (relative) path to an application absolute path.
@ -54,15 +49,11 @@ namespace Microsoft.AspNet.Mvc
bool IsLocalUrl(string url);
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values by
/// using the specified route name, protocol to use, host name and fragment.
/// Generates a fully qualified or absolute URL specified by <see cref="Mvc.UrlRouteContext"/>, which
/// contains the route name, the route values, protocol to use, host name and fragment.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <param name="values">An object that contains the parameters for a route.</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>
/// <param name="routeContext">The context object for the generated URLs for a route.</param>
/// <returns>The fully qualified or absolute URL.</returns>
string RouteUrl(string routeName, object values, string protocol, string host, string fragment);
string RouteUrl([NotNull] UrlRouteContext routeContext);
}
}

View File

@ -193,7 +193,12 @@ namespace Microsoft.AspNet.Mvc
protected virtual string GetUrl([NotNull] ClientModelValidationContext context)
{
var urlHelper = context.RequestServices.GetRequiredService<IUrlHelper>();
var url = urlHelper.RouteUrl(RouteName, values: RouteData, protocol: null, host: null, fragment: null);
var url = urlHelper.RouteUrl(new UrlRouteContext()
{
RouteName = this.RouteName,
Values = RouteData,
});
if (url == null)
{
throw new InvalidOperationException(Resources.RemoteAttribute_NoUrlFound);

View File

@ -0,0 +1,67 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Context object to be used for the URLs that <see cref="Mvc.IUrlHelper.Action(UrlActionContext)"/> generates.
/// </summary>
public class UrlActionContext
{
/// <summary>
/// The name of the action method that <see cref="Mvc.UrlHelper.Action(UrlActionContext)" uses to generate URLs.
/// </summary>
public string Action
{
get;
set;
}
/// <summary>
/// The name of the controller that <see cref="Mvc.UrlHelper.Action(UrlActionContext)" uses to generate URLs.
/// </summary>
public string Controller
{
get;
set;
}
/// <summary>
/// The object that contains the route parameters that <see cref="Mvc.IUrlHelper.Action(UrlActionContext)"/>
/// uses to generate URLs.
/// </summary>
public object Values
{
get;
set;
}
/// <summary>
/// The protocol for the URLs that <see cref="Mvc.UrlHelper.Action(UrlActionContext)" generates
/// such as "http" or "https"
/// </summary>
public string Protocol
{
get;
set;
}
/// <summary>
/// The host name for the URLs that <see cref="Mvc.UrlHelper.Action(UrlActionContext)" generates.
/// </summary>
public string Host
{
get;
set;
}
/// <summary>
/// The fragment for the URLs that <see cref="Mvc.UrlHelper.Action(UrlActionContext)" generates.
/// </summary>
public string Fragment
{
get;
set;
}
}
}

View File

@ -40,24 +40,18 @@ namespace Microsoft.AspNet.Mvc
}
/// <inheritdoc />
public virtual string Action(
string action,
string controller,
object values,
string protocol,
string host,
string fragment)
public virtual string Action(UrlActionContext actionContext)
{
var valuesDictionary = TypeHelper.ObjectToDictionary(values);
var valuesDictionary = TypeHelper.ObjectToDictionary(actionContext.Values);
if (action != null)
if (actionContext.Action != null)
{
valuesDictionary["action"] = action;
valuesDictionary["action"] = actionContext.Action;
}
if (controller != null)
if (actionContext.Controller != null)
{
valuesDictionary["controller"] = controller;
valuesDictionary["controller"] = actionContext.Controller;
}
var path = GeneratePathFromRoute(valuesDictionary);
@ -66,7 +60,7 @@ namespace Microsoft.AspNet.Mvc
return null;
}
return GenerateUrl(protocol, host, path, fragment);
return GenerateUrl(actionContext.Protocol, actionContext.Host, path, actionContext.Fragment);
}
/// <inheritdoc />
@ -76,17 +70,17 @@ namespace Microsoft.AspNet.Mvc
}
/// <inheritdoc />
public virtual string RouteUrl(string routeName, object values, string protocol, string host, string fragment)
public virtual string RouteUrl(UrlRouteContext routeContext)
{
var valuesDictionary = TypeHelper.ObjectToDictionary(values);
var valuesDictionary = TypeHelper.ObjectToDictionary(routeContext.Values);
var path = GeneratePathFromRoute(routeName, valuesDictionary);
var path = GeneratePathFromRoute(routeContext.RouteName, valuesDictionary);
if (path == null)
{
return null;
}
return GenerateUrl(protocol, host, path, fragment);
return GenerateUrl(routeContext.Protocol, routeContext.Host, path, routeContext.Fragment);
}
private string GeneratePathFromRoute(IDictionary<string, object> values)

View File

@ -5,6 +5,10 @@ namespace Microsoft.AspNet.Mvc
{
public static class UrlHelperExtensions
{
/// <summary>
/// Generates a fully qualified or absolute URL for an action method.
/// </summary>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action([NotNull] this IUrlHelper helper)
{
return helper.Action(
@ -16,26 +20,62 @@ namespace Microsoft.AspNet.Mvc
fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action([NotNull] this IUrlHelper helper, string action)
{
return helper.Action(action, controller: null, values: null, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// and route values.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="values">An object that contains route values.</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action([NotNull] this IUrlHelper helper, string action, object values)
{
return helper.Action(action, controller: null, values: values, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// and controller name.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action([NotNull] this IUrlHelper helper, string action, string controller)
{
return helper.Action(action, controller, values: null, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// controller name, and route values.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <param name="values">An object that contains route values.</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action([NotNull] this IUrlHelper helper, string action, string controller, object values)
{
return helper.Action(action, controller, values, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// controller name, route values, and protocol to use.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <param name="values">An object that contains route values.</param>
/// <param name="protocol">The protocol for the URL, such as "http" or "https".</param>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action(
[NotNull] this IUrlHelper helper,
string action,
@ -46,6 +86,16 @@ namespace Microsoft.AspNet.Mvc
return helper.Action(action, controller, values, protocol, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// controller name, route values, protocol to use, and host name.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <param name="values">An object that contains route values.</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>
/// <returns>The fully qualified or absolute URL to an action method.</returns>
public static string Action(
[NotNull] this IUrlHelper helper,
string action,
@ -57,21 +107,77 @@ namespace Microsoft.AspNet.Mvc
return helper.Action(action, controller, values, protocol, host, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for an action method by using the specified action name,
/// controller name, route values, protocol to use, host name and fragment.
/// </summary>
/// <param name="action">The name of the action method.</param>
/// <param name="controller">The name of the controller.</param>
/// <param name="values">An object that contains route values.</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 fully qualified or absolute URL to an action method.</returns>
public static string Action(
[NotNull] this IUrlHelper helper,
string action,
string controller,
object values,
string protocol,
string host,
string fragment)
{
return helper.Action(new UrlActionContext()
{
Action = action,
Controller = controller,
Host = host,
Values = values,
Protocol = protocol,
Fragment = fragment
});
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values.
/// </summary>
/// <param name="values">An object that contains route values.</param>
/// <returns>The fully qualified or absolute URL.</returns>
public static string RouteUrl([NotNull] this IUrlHelper helper, object values)
{
return helper.RouteUrl(routeName: null, values: values, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route name.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <returns>The fully qualified or absolute URL.</returns>
public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName)
{
return helper.RouteUrl(routeName, values: null, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values by
/// using the specified route name.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <param name="values">An object that contains route values.</param>
/// <returns>The fully qualified or absolute URL.</returns>
public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName, object values)
{
return helper.RouteUrl(routeName, values, protocol: null, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values by
/// using the specified route name, and protocol to use.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <param name="values">An object that contains route values.</param>
/// <param name="protocol">The protocol for the URL, such as "http" or "https".</param>
/// <returns>The fully qualified or absolute URL.</returns>
public static string RouteUrl(
[NotNull] this IUrlHelper helper,
string routeName,
@ -81,6 +187,15 @@ namespace Microsoft.AspNet.Mvc
return helper.RouteUrl(routeName, values, protocol, host: null, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values by
/// using the specified route name, protocol to use, and host name.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <param name="values">An object that contains route values.</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>
/// <returns>The fully qualified or absolute URL.</returns>
public static string RouteUrl(
[NotNull] this IUrlHelper helper,
string routeName,
@ -90,5 +205,33 @@ namespace Microsoft.AspNet.Mvc
{
return helper.RouteUrl(routeName, values, protocol, host, fragment: null);
}
/// <summary>
/// Generates a fully qualified or absolute URL for the specified route values by
/// using the specified route name, protocol to use, host name and fragment.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate URL.</param>
/// <param name="values">An object that contains route values.</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 fully qualified or absolute URL.</returns>
public static string RouteUrl(
[NotNull] this IUrlHelper helper,
string routeName,
object values,
string protocol,
string host,
string fragment)
{
return helper.RouteUrl(new UrlRouteContext()
{
RouteName = routeName,
Values = values,
Protocol = protocol,
Host = host,
Fragment = fragment
});
}
}
}

View File

@ -0,0 +1,57 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Context object to be used for the URLs that <see cref="Mvc.IUrlHelper.RouteUrl(UrlRouteContext)"/> generates.
/// </summary>
public class UrlRouteContext
{
/// <summary>
/// The name of the route that <see cref="Mvc.IUrlHelper.RouteUrl(UrlRouteContext)" uses to generate URLs.
/// </summary>
public string RouteName
{
get;
set;
}
/// <summary>
/// The object that contains the route values for the generated URLs.
/// </summary>
public object Values
{
get;
set;
}
/// <summary>
/// The protocol for the URLs that <see cref="Mvc.IUrlHelper.RouteUrl(UrlRouteContext)" generates
/// such as "http" or "https"
/// </summary>
public string Protocol
{
get;
set;
}
/// <summary>
/// The host name for the URLs that <see cref="Mvc.IUrlHelper.RouteUrl(UrlRouteContext)" generates.
/// </summary>
public string Host
{
get;
set;
}
/// <summary>
/// The fragment for the URLs that <see cref="Mvc.IUrlHelper.RouteUrl(UrlRouteContext)" generates.
/// </summary>
public string Fragment
{
get;
set;
}
}
}

View File

@ -106,8 +106,7 @@ namespace Microsoft.AspNet.Mvc
private static IUrlHelper GetMockUrlHelper(string returnValue)
{
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(o => o.Action(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(),
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue);
urlHelper.Setup(o => o.Action(It.IsAny<UrlActionContext>())).Returns(returnValue);
return urlHelper.Object;
}

View File

@ -115,8 +115,7 @@ namespace Microsoft.AspNet.Mvc
private static IUrlHelper GetMockUrlHelper(string returnValue)
{
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(o => o.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue);
urlHelper.Setup(o => o.RouteUrl(It.IsAny<UrlRouteContext>())).Returns(returnValue);
return urlHelper.Object;
}

View File

@ -69,8 +69,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
private static IUrlHelper GetMockUrlHelper(string returnValue)
{
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(o => o.Action(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(),
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue);
urlHelper.Setup(o => o.Action(It.IsAny<UrlActionContext>())).Returns(returnValue);
return urlHelper.Object;
}

View File

@ -89,8 +89,7 @@ namespace Microsoft.AspNet.Mvc.Core
private static IUrlHelper GetMockUrlHelper(string returnValue)
{
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(o => o.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>())).Returns(returnValue);
urlHelper.Setup(o => o.RouteUrl(It.IsAny<UrlRouteContext>())).Returns(returnValue);
return urlHelper.Object;
}
}

View File

@ -596,13 +596,7 @@ namespace Microsoft.AspNet.Mvc
public object RouteValues { get; private set; }
public string Action(
string action,
string controller,
object values,
string protocol,
string host,
string fragment)
public string Action(UrlActionContext actionContext)
{
throw new NotImplementedException();
}
@ -617,14 +611,14 @@ namespace Microsoft.AspNet.Mvc
throw new NotImplementedException();
}
public string RouteUrl(string routeName, object values, string protocol, string host, string fragment)
public string RouteUrl(UrlRouteContext routeContext)
{
Assert.Equal(_routeName, routeName);
Assert.Null(protocol);
Assert.Null(host);
Assert.Null(fragment);
Assert.Equal(_routeName, routeContext.RouteName);
Assert.Null(routeContext.Protocol);
Assert.Null(routeContext.Host);
Assert.Null(routeContext.Fragment);
RouteValues = values;
RouteValues = routeContext.Values;
return _url;
}

View File

@ -177,13 +177,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
var urlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
urlHelper
.Setup(realHelper => realHelper.Action(
actionName,
controllerName,
routeValues,
null, // protocol
null, // host
null)) // fragment
.Setup(realHelper => realHelper.Action(It.Is<UrlActionContext>((context) =>
string.Equals(context.Action, actionName) &&
string.Equals(context.Controller, controllerName) &&
context.Values == routeValues
)))
.Returns(expectedAction)
.Verifiable();
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(urlHelper.Object);
@ -221,12 +219,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
var urlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
urlHelper
.Setup(realHelper => realHelper.RouteUrl(
routeName,
routeValues,
null, // protocol
null, // host
null)) // fragment
.Setup(realHelper => realHelper.RouteUrl(It.Is<UrlRouteContext>(context =>
string.Equals(context.RouteName, routeName) &&
context.Values == routeValues &&
context.Protocol == null &&
context.Host == null &&
context.Fragment == null)))
.Returns(expectedAction)
.Verifiable();
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(urlHelper.Object);

View File

@ -55,23 +55,15 @@ namespace Microsoft.AspNet.Mvc.Rendering
GetHtmlAttributesAsString(htmlAttributes));
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(
h => h.Action(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns<string, string, object, string, string, string>(
(actn, cntrlr, rvalues, prtcl, hname, frgmt) =>
string.Format("{0}{1}{2}{3}{4}{5}",
prtcl,
hname,
cntrlr,
actn,
GetRouteValuesAsString(rvalues),
frgmt));
urlHelper.Setup(h => h.Action(It.IsAny<UrlActionContext>()))
.Returns<UrlActionContext>((actionContext) =>
string.Format("{0}{1}{2}{3}{4}{5}",
actionContext.Protocol,
actionContext.Host,
actionContext.Controller,
actionContext.Action,
GetRouteValuesAsString(actionContext.Values),
actionContext.Fragment));
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(urlHelper.Object);
@ -129,19 +121,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
var urlHelper = new Mock<IUrlHelper>();
urlHelper
.Setup(
h => h.RouteUrl(
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns<string, object, string, string, string>(
(rname, rvalues, prtcl, hname, frgmt) =>
h => h.RouteUrl(It.IsAny<UrlRouteContext>())).Returns<UrlRouteContext>((context) =>
string.Format("{0}{1}{2}{3}",
prtcl,
hname,
GetRouteValuesAsString(rvalues),
frgmt));
context.Protocol,
context.Host,
GetRouteValuesAsString(context.Values),
context.Fragment));
var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(urlHelper.Object);

View File

@ -59,8 +59,8 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(expectedPath, path);
}
// UrlHelper.IsLocalUrl depends on the UrlUtility.IsLocalUrl method.
// To avoid duplicate tests, all the tests exercising IsLocalUrl verify
// UrlHelper.IsLocalUrl depends on the UrlUtility.IsLocalUrl method.
// To avoid duplicate tests, all the tests exercising IsLocalUrl verify
// both of UrlHelper.IsLocalUrl and UrlUtility.IsLocalUrl
[Theory]
[InlineData(null)]
@ -543,6 +543,56 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("/app/named/home2/newaction/someid", url);
}
[Fact]
public void RouteUrlWithUrlRouteContext_ReturnsExpectedResult()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
var routeContext = new UrlRouteContext()
{
RouteName = "namedroute",
Values = new
{
Action = "newaction",
Controller = "home2",
id = "someid"
},
Fragment = "somefragment",
Host = "remotetown",
Protocol = "ftp"
};
// Act
var url = urlHelper.RouteUrl(routeContext);
// Assert
Assert.Equal("ftp://remotetown/app/named/home2/newaction/someid#somefragment", url);
}
[Fact]
public void RouteUrlWithAllParameters_ReturnsExpectedResult()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.RouteUrl(
routeName: "namedroute",
values: new
{
Action = "newaction",
Controller = "home2",
id = "someid"
},
fragment: "somefragment",
host: "remotetown",
protocol: "https");
// Assert
Assert.Equal("https://remotetown/app/named/home2/newaction/someid#somefragment", url);
}
[Fact]
public void UrlAction_RouteValuesAsDictionary_CaseSensitive()
{
@ -616,6 +666,49 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("/app/named/home/contact/suppliedid", url);
}
[Fact]
public void UrlActionWithUrlActionContext_ReturnsExpectedResult()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
var actionContext = new UrlActionContext()
{
Action = "contact",
Controller = "home3",
Values = new { id = "idone" },
Protocol = "ftp",
Host = "remotelyhost",
Fragment = "somefragment"
};
// Act
var url = urlHelper.Action(actionContext);
// Assert
Assert.Equal("ftp://remotelyhost/app/home3/contact/idone#somefragment", url);
}
[Fact]
public void UrlActionWithAllParameters_ReturnsExpectedResult()
{
// Arrange
var urlHelper = CreateUrlHelperWithRouteCollection("/app");
// Act
var url = urlHelper.Action(
controller: "home3",
action: "contact",
values: null,
protocol: "https",
host: "remotelyhost",
fragment: "somefragment"
);
// Assert
Assert.Equal("https://remotelyhost/app/home3/contact#somefragment", url);
}
private static HttpContext CreateHttpContext(string appRoot, ILoggerFactory factory = null)
{
if (factory == null)

View File

@ -47,14 +47,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var urlHelper = new Mock<IUrlHelper>();
urlHelper
.Setup(mock => mock.Action(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns("home/index");
.Setup(mock => mock.Action(It.IsAny<UrlActionContext>())).Returns("home/index");
var htmlGenerator = new TestableHtmlGenerator(metadataProvider, urlHelper.Object);
var viewContext = TestableHtmlGenerator.GetViewContext(model: null,

View File

@ -47,13 +47,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
};
var urlHelper = new Mock<IUrlHelper>();
urlHelper
.Setup(mock => mock.Action(It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns("home/index");
.Setup(mock => mock.Action(It.IsAny<UrlActionContext>())).Returns("home/index");
var htmlGenerator = new TestableHtmlGenerator(metadataProvider, urlHelper.Object);
var viewContext = TestableHtmlGenerator.GetViewContext(model: null,

View File

@ -46,14 +46,14 @@ namespace UrlHelperWebSite
return ConvertToLowercaseUrl(base.Content(contentPath));
}
public override string RouteUrl(string routeName, object values, string protocol, string host, string fragment)
public override string RouteUrl(UrlRouteContext routeContext)
{
return ConvertToLowercaseUrl(base.RouteUrl(routeName, values, protocol, host, fragment));
return ConvertToLowercaseUrl(base.RouteUrl(routeContext));
}
public override string Action(string action, string controller, object values, string protocol, string host, string fragment)
public override string Action(UrlActionContext actionContext)
{
return ConvertToLowercaseUrl(base.Action(action, controller, values, protocol, host, fragment));
return ConvertToLowercaseUrl(base.Action(actionContext));
}
private string ConvertToLowercaseUrl(string url)