Add convenience methods for redirecting from a Razor Page back to itself

Fuxes #5953
This commit is contained in:
Pranav K 2017-04-04 15:41:40 -07:00
parent 4032de064e
commit 1e7972bd8f
7 changed files with 114 additions and 7 deletions

View File

@ -138,6 +138,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
return new RedirectResult(url);
}
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the current page.
/// </summary>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected RedirectToPageResult RedirectToPage()
=> RedirectToPage(pageName: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the current page with the specified <paramref name="routeValues"/>.
/// </summary>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected RedirectToPageResult RedirectToPage(object routeValues)
=> RedirectToPage(pageName: null, routeValues: routeValues);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>.
/// </summary>

View File

@ -176,6 +176,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
return new RedirectResult(url);
}
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the current page.
/// </summary>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected RedirectToPageResult RedirectToPage()
=> RedirectToPage(pageName: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the current page with the specified <paramref name="routeValues"/>.
/// </summary>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected RedirectToPageResult RedirectToPage(object routeValues)
=> RedirectToPage(pageName: null, routeValues: routeValues);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>.
/// </summary>

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <summary>
/// Razor page specific extensions for <see cref="IUrlHelper"/>.
/// </summary>
public static class PageNameUrlHelperExtensions
public static class PageUrlHelperExtensions
{
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.

View File

@ -130,12 +130,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
throw new ArgumentNullException(nameof(context));
}
if (string.IsNullOrEmpty(PageName))
{
throw new InvalidOperationException(
Resources.FormatPropertyOfTypeCannotBeNull(nameof(PageName), nameof(RedirectToPageResult)));
}
var executor = context.HttpContext.RequestServices.GetRequiredService<RedirectToPageResultExecutor>();
executor.Execute(context, this);
}

View File

@ -677,6 +677,29 @@ Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore._InjectedP
Assert.Equal(expected, response.Headers.Location.ToString());
}
[Fact]
public async Task RedirectToSelfWorks()
{
// Arrange
var expected = "/Pages/Redirects/RedirectToSelf?user=37";
var request = new HttpRequestMessage(HttpMethod.Post, "/Pages/Redirects/RedirectToSelf")
{
Content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("value", "37"),
}),
};
// Act
await AddAntiforgeryHeaders(request);
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Equal(expected, response.Headers.Location.ToString());
}
private async Task AddAntiforgeryHeaders(HttpRequestMessage request)
{
var getResponse = await Client.GetAsync(request.RequestUri);

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
@ -123,6 +124,56 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
Assert.Equal("test-fragment", context.Fragment);
}
[Fact]
public async Task RedirectToPage_WithNullPage_UsesAmbientValue()
{
// Arrange
var expected = "path/to/this-page";
var httpContext = new Mock<HttpContext>();
var httpResponse = new Mock<HttpResponse>();
httpContext.SetupGet(c => c.Response)
.Returns(httpResponse.Object);
httpContext.SetupGet(c => c.RequestServices)
.Returns(CreateServices());
var routeData = new RouteData
{
Values =
{
["page"] = expected,
}
};
var actionContext = new ActionContext(
httpContext.Object,
routeData,
new ActionDescriptor());
UrlRouteContext context = null;
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
.Callback((UrlRouteContext c) => context = c)
.Returns("some-value");
urlHelper.SetupGet(h => h.ActionContext)
.Returns(actionContext);
var pageName = (string)null;
var result = new RedirectToPageResult(pageName)
{
UrlHelper = urlHelper.Object,
};
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
Assert.NotNull(context);
Assert.Collection(Assert.IsType<RouteValueDictionary>(context.Values),
value =>
{
Assert.Equal("page", value.Key);
Assert.Equal(expected, value.Value);
});
}
private static IServiceProvider CreateServices(IUrlHelperFactory factory = null)
{
var services = new ServiceCollection();

View File

@ -0,0 +1,9 @@
@page
@functions
{
public IActionResult OnPost(int value) => RedirectToPage(new { user = value });
}
<form action="">
@Html.AntiForgeryToken()
</form>