added Link method to IUrlHelper

This commit is contained in:
Ajay Bhargav Baaskaran 2015-02-12 17:04:24 -08:00
parent 48a1cbb0e5
commit 3d30fd653e
6 changed files with 119 additions and 3 deletions

View File

@ -60,10 +60,9 @@ namespace Microsoft.AspNet.Mvc
/// <inheritdoc /> /// <inheritdoc />
protected override void OnFormatting([NotNull] ActionContext context) protected override void OnFormatting([NotNull] ActionContext context)
{ {
var request = context.HttpContext.Request;
var urlHelper = UrlHelper ?? context.HttpContext.RequestServices.GetRequiredService<IUrlHelper>(); var urlHelper = UrlHelper ?? context.HttpContext.RequestServices.GetRequiredService<IUrlHelper>();
var url = urlHelper.RouteUrl(RouteName, RouteValues, request.Scheme, request.Host.ToUriComponent()); var url = urlHelper.Link(RouteName, RouteValues);
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {

View File

@ -55,5 +55,16 @@ namespace Microsoft.AspNet.Mvc
/// <param name="routeContext">The context object for the generated URLs for a route.</param> /// <param name="routeContext">The context object for the generated URLs for a route.</param>
/// <returns>The fully qualified or absolute URL.</returns> /// <returns>The fully qualified or absolute URL.</returns>
string RouteUrl([NotNull] UrlRouteContext routeContext); string RouteUrl([NotNull] UrlRouteContext routeContext);
/// <summary>
/// Generates an absolute URL using the specified route name and values.
/// </summary>
/// <param name="routeName">The name of the route that is used to generate the URL.</param>
/// <param name="values">An object that contains the route values.</param>
/// <returns>The generated absolute URL.</returns>
/// <remarks>
/// The protocol and host is obtained from the current request.
/// </remarks>
string Link(string routeName, object values);
} }
} }

View File

@ -127,6 +127,18 @@ namespace Microsoft.AspNet.Mvc
return GenerateClientUrl(_httpContext.Request.PathBase, contentPath); return GenerateClientUrl(_httpContext.Request.PathBase, contentPath);
} }
/// <inheritdoc />
public virtual string Link(string routeName, object values)
{
return RouteUrl(new UrlRouteContext()
{
RouteName = routeName,
Values = values,
Protocol = _httpContext.Request.Scheme,
Host = _httpContext.Request.Host.ToUriComponent()
});
}
private static string GenerateClientUrl([NotNull] PathString applicationPath, private static string GenerateClientUrl([NotNull] PathString applicationPath,
[NotNull] string path) [NotNull] string path)
{ {

View File

@ -115,7 +115,7 @@ namespace Microsoft.AspNet.Mvc
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<UrlRouteContext>())).Returns(returnValue); urlHelper.Setup(o => o.Link(It.IsAny<string>(), It.IsAny<object>())).Returns(returnValue);
return urlHelper.Object; return urlHelper.Object;
} }

View File

@ -613,6 +613,11 @@ namespace Microsoft.AspNet.Mvc
throw new NotImplementedException(); throw new NotImplementedException();
} }
public string Link(string routeName, object values)
{
throw new NotImplementedException();
}
public string RouteUrl(UrlRouteContext routeContext) public string RouteUrl(UrlRouteContext routeContext)
{ {
Assert.Equal(_routeName, routeContext.RouteName); Assert.Equal(_routeName, routeContext.RouteName);

View File

@ -728,6 +728,82 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("https://remotelyhost/app/home3/contact#somefragment", url); Assert.Equal("https://remotelyhost/app/home3/contact#somefragment", url);
} }
[Fact]
public void LinkWithAllParameters_ReturnsExpectedResult()
{
// Arrange
var services = GetServices();
var urlHelper = CreateUrlHelperWithRouteCollection(services, "/app");
// Act
var url = urlHelper.Link("namedroute",
new
{
Action = "newaction",
Controller = "home",
id = "someid"
});
// Assert
Assert.Equal("http://localhost/app/named/home/newaction/someid", url);
}
[Fact]
public void LinkWithNullRouteName_ReturnsExpectedResult()
{
// Arrange
var services = GetServices();
var urlHelper = CreateUrlHelperWithRouteCollection(services, "/app");
// Act
var url = urlHelper.Link(null,
new
{
Action = "newaction",
Controller = "home",
id = "someid"
});
// Assert
Assert.Equal("http://localhost/app/home/newaction/someid", url);
}
[Fact]
public void LinkWithDefaultsAndNullRouteValues_ReturnsExpectedResult()
{
// Arrange
var services = GetServices();
var routeCollection = GetRouter(services, "MyRouteName", "any/url");
var urlHelper = CreateUrlHelper("/app", routeCollection);
// Act
var url = urlHelper.Link("MyRouteName", null);
// Assert
Assert.Equal("http://localhost/app/any/url", url);
}
[Fact]
public void LinkWithCustomHostAndProtocol_ReturnsExpectedResult()
{
// Arrange
var services = GetServices();
var routeCollection = GetRouter(services, "MyRouteName", "any/url");
var urlHelper = CreateUrlHelper("myhost", "https", routeCollection);
// Act
var url = urlHelper.Link("namedroute",
new
{
Action = "newaction",
Controller = "home",
id = "someid"
});
// Assert
Assert.Equal("https://myhost/named/home/newaction/someid", url);
}
private static HttpContext CreateHttpContext( private static HttpContext CreateHttpContext(
IServiceProvider services, IServiceProvider services,
string appRoot) string appRoot)
@ -782,6 +858,19 @@ namespace Microsoft.AspNet.Mvc
return new UrlHelper(actionContext, actionSelector.Object); return new UrlHelper(actionContext, actionSelector.Object);
} }
private static UrlHelper CreateUrlHelper(string host, string protocol, IRouter router)
{
var services = GetServices();
var context = CreateHttpContext(services, string.Empty);
context.Request.Host = new HostString(host);
context.Request.Scheme = protocol;
var actionContext = CreateActionContext(context, router);
var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict);
return new UrlHelper(actionContext, actionSelector.Object);
}
private static UrlHelper CreateUrlHelper(IScopedInstance<ActionContext> contextAccessor) private static UrlHelper CreateUrlHelper(IScopedInstance<ActionContext> contextAccessor)
{ {
var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict); var actionSelector = new Mock<IActionSelector>(MockBehavior.Strict);