Add an extension method to generate an absolute URL for a page.
This commit is contained in:
parent
4b8d9666f4
commit
1bc056a7f6
|
|
@ -582,5 +582,57 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
|
||||
return Action(helper, action, controller, values, protocol, host, fragment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an absolute URL for a page, which contains the specified
|
||||
/// <paramref name="pageName"/>, <paramref name="pageHandler"/>, route <paramref name="values"/>,
|
||||
/// <paramref name="protocol"/> to use, <paramref name="host"/> name, and <paramref name="fragment"/>.
|
||||
/// Generates an absolute URL if the <paramref name="protocol"/> and <paramref name="host"/> are
|
||||
/// non-<c>null</c>. See the remarks section for important security information.
|
||||
/// </summary>
|
||||
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
|
||||
/// <param name="pageName">The page name to generate the url for. When <see langword="null"/>, defaults to the current executing page.</param>
|
||||
/// <param name="pageHandler">The handler to generate the url for. When <see langword="null"/>, defaults to the current executing handler.</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 generated URL.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The value of <paramref name="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 <c>Host</c> header has been validated.
|
||||
/// See the deployment documentation for instructions on how to properly validate the <c>Host</c> header in
|
||||
/// your deployment environment.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static string PageLink(
|
||||
this IUrlHelper urlHelper,
|
||||
string pageName = null,
|
||||
string pageHandler = null,
|
||||
object values = null,
|
||||
string protocol = null,
|
||||
string host = null,
|
||||
string fragment = null)
|
||||
{
|
||||
if (urlHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(urlHelper));
|
||||
}
|
||||
|
||||
var httpContext = urlHelper.ActionContext.HttpContext;
|
||||
|
||||
if (protocol == null)
|
||||
{
|
||||
protocol = httpContext.Request.Protocol;
|
||||
}
|
||||
|
||||
if (host == null)
|
||||
{
|
||||
host = httpContext.Request.Host.ToUriComponent();
|
||||
}
|
||||
|
||||
return Page(urlHelper, pageName, pageHandler, values, protocol, host, fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -708,6 +708,151 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test.Routing
|
|||
Assert.Equal(expectedHost, actual.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PageLink_WithPageName_Works()
|
||||
{
|
||||
// Arrange
|
||||
var expectedPage = "/TestPage";
|
||||
var expectedProtocol = "testprotocol://";
|
||||
var expectedHost = "www.example.com";
|
||||
UrlRouteContext actual = null;
|
||||
|
||||
var actionContext = new ActionContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
Request =
|
||||
{
|
||||
Protocol = expectedProtocol,
|
||||
Host = new HostString(expectedHost),
|
||||
}
|
||||
},
|
||||
RouteData = new RouteData
|
||||
{
|
||||
Values =
|
||||
{
|
||||
{ "page", "ambient-page" },
|
||||
}
|
||||
},
|
||||
};
|
||||
var urlHelper = CreateMockUrlHelper(actionContext);
|
||||
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
|
||||
.Callback((UrlRouteContext context) => actual = context);
|
||||
|
||||
// Act
|
||||
urlHelper.Object.PageLink(expectedPage);
|
||||
|
||||
// Assert
|
||||
urlHelper.Verify();
|
||||
Assert.NotNull(actual);
|
||||
Assert.Collection(Assert.IsType<RouteValueDictionary>(actual.Values),
|
||||
value =>
|
||||
{
|
||||
Assert.Equal("page", value.Key);
|
||||
Assert.Equal(expectedPage, value.Value);
|
||||
});
|
||||
Assert.Null(actual.RouteName);
|
||||
|
||||
Assert.Equal(expectedProtocol, actual.Protocol);
|
||||
Assert.Equal(expectedHost, actual.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PageLink_UsesSpecifiedProtocol()
|
||||
{
|
||||
// Arrange
|
||||
var expectedProtocol = "testprotocol://";
|
||||
var expectedHost = "www.example.com";
|
||||
UrlRouteContext actual = null;
|
||||
|
||||
var actionContext = new ActionContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
Request =
|
||||
{
|
||||
Protocol = "http://",
|
||||
Host = new HostString(expectedHost),
|
||||
}
|
||||
},
|
||||
RouteData = new RouteData
|
||||
{
|
||||
Values =
|
||||
{
|
||||
{ "page", "ambient-page" },
|
||||
}
|
||||
},
|
||||
};
|
||||
var urlHelper = CreateMockUrlHelper(actionContext);
|
||||
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
|
||||
.Callback((UrlRouteContext context) => actual = context);
|
||||
|
||||
// Act
|
||||
urlHelper.Object.PageLink(protocol: expectedProtocol);
|
||||
|
||||
// Assert
|
||||
urlHelper.Verify();
|
||||
Assert.NotNull(actual);
|
||||
Assert.Collection(Assert.IsType<RouteValueDictionary>(actual.Values),
|
||||
value =>
|
||||
{
|
||||
Assert.Equal("page", value.Key);
|
||||
Assert.Equal("ambient-page", value.Value);
|
||||
});
|
||||
Assert.Null(actual.RouteName);
|
||||
|
||||
Assert.Equal(expectedProtocol, actual.Protocol);
|
||||
Assert.Equal(expectedHost, actual.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PageLink_UsesSpecifiedHost()
|
||||
{
|
||||
// Arrange
|
||||
var expectedProtocol = "testprotocol://";
|
||||
var expectedHost = "www.example.com";
|
||||
UrlRouteContext actual = null;
|
||||
|
||||
var actionContext = new ActionContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
Request =
|
||||
{
|
||||
Protocol = expectedProtocol,
|
||||
Host = new HostString("www.asp.net"),
|
||||
}
|
||||
},
|
||||
RouteData = new RouteData
|
||||
{
|
||||
Values =
|
||||
{
|
||||
{ "page", "ambient-page" },
|
||||
}
|
||||
},
|
||||
};
|
||||
var urlHelper = CreateMockUrlHelper(actionContext);
|
||||
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
|
||||
.Callback((UrlRouteContext context) => actual = context);
|
||||
|
||||
// Act
|
||||
urlHelper.Object.PageLink(host: expectedHost);
|
||||
|
||||
// Assert
|
||||
urlHelper.Verify();
|
||||
Assert.NotNull(actual);
|
||||
Assert.Collection(Assert.IsType<RouteValueDictionary>(actual.Values),
|
||||
value =>
|
||||
{
|
||||
Assert.Equal("page", value.Key);
|
||||
Assert.Equal("ambient-page", value.Value);
|
||||
});
|
||||
Assert.Null(actual.RouteName);
|
||||
|
||||
Assert.Equal(expectedProtocol, actual.Protocol);
|
||||
Assert.Equal(expectedHost, actual.Host);
|
||||
}
|
||||
|
||||
private static Mock<IUrlHelper> CreateMockUrlHelper(ActionContext context = null)
|
||||
{
|
||||
if (context == null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue