Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Add PreserveMethod to RedirectPageResult
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanbrandenburg committed Apr 17, 2017
1 parent 6ac7fcc commit 6ac7681
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{
Expand Down Expand Up @@ -44,7 +46,17 @@ public void Execute(ActionContext context, RedirectToPageResult result)
}

_logger.RedirectToPageResultExecuting(result.PageName);
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);

if (result.PreserveMethod)
{
context.HttpContext.Response.StatusCode = result.Permanent ?
StatusCodes.Status308PermanentRedirect : StatusCodes.Status307TemporaryRedirect;
context.HttpContext.Response.Headers[HeaderNames.Location] = destinationUrl;
}
else
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}
}
}
}
44 changes: 44 additions & 0 deletions src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,50 @@ protected RedirectToPageResult RedirectToPagePermanent(string pageName, string f
protected RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, permanent: true, fragment: fragment);

/// <summary>
/// Redirects (<see cref="StatusCodes.Status307TemporaryRedirect"/>) to the specified page with
/// <see cref="RedirectToRouteResult.Permanent"/> set to false and <see cref="RedirectToRouteResult.PreserveMethod"/>
/// set to true, using the specified <paramref name="pageName"/>, <paramref name="routeValues"/>, and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The created <see cref="RedirectToRouteResult"/> for the response.</returns>
public virtual RedirectToPageResult RedirectToPagePreserveMethod(
string pageName = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
routeValues: routeValues,
permanent: false,
preserveMethod: true,
fragment: fragment);
}

/// <summary>
/// Redirects (<see cref="StatusCodes.Status308PermanentRedirect"/>) to the specified route with
/// <see cref="RedirectToRouteResult.Permanent"/> set to true and <see cref="RedirectToRouteResult.PreserveMethod"/>
/// set to true, using the specified <paramref name="pageName"/>, <paramref name="routeValues"/>, and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The created <see cref="RedirectToRouteResult"/> for the response.</returns>
public virtual RedirectToPageResult RedirectToPagePermanentPreserveMethod(
string pageName = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
routeValues: routeValues,
permanent: true,
preserveMethod: true,
fragment: fragment);
}

/// <summary>
/// Creates a <see cref="SignInResult"/> with the specified authentication scheme.
/// </summary>
Expand Down
53 changes: 52 additions & 1 deletion src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,14 @@ public virtual PhysicalFileResult PhysicalFile(string physicalPath, string conte
/// <param name="url">The URL to redirect to.</param>
/// <returns>The created <see cref="RedirectResult"/> for the response.</returns>
protected internal RedirectResult Redirect(string url)
=> new RedirectResult(url);
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(url));
}

return new RedirectResult(url);
}

/// <summary>
/// Creates a <see cref="RedirectResult"/> object with <see cref="RedirectResult.Permanent"/> set to true
Expand Down Expand Up @@ -1046,6 +1053,50 @@ protected internal RedirectToPageResult RedirectToPagePermanent(string pageName,
protected internal RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, permanent: true, fragment: fragment);

/// <summary>
/// Redirects (<see cref="StatusCodes.Status307TemporaryRedirect"/>) to the specified page with
/// <see cref="RedirectToRouteResult.Permanent"/> set to false and <see cref="RedirectToRouteResult.PreserveMethod"/>
/// set to true, using the specified <paramref name="pageName"/>, <paramref name="routeValues"/>, and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The created <see cref="RedirectToRouteResult"/> for the response.</returns>
public virtual RedirectToPageResult RedirectToPagePreserveMethod(
string pageName = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
routeValues: routeValues,
permanent: false,
preserveMethod: true,
fragment: fragment);
}

/// <summary>
/// Redirects (<see cref="StatusCodes.Status308PermanentRedirect"/>) to the specified route with
/// <see cref="RedirectToRouteResult.Permanent"/> set to true and <see cref="RedirectToRouteResult.PreserveMethod"/>
/// set to true, using the specified <paramref name="pageName"/>, <paramref name="routeValues"/>, and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The created <see cref="RedirectToRouteResult"/> for the response.</returns>
public virtual RedirectToPageResult RedirectToPagePermanentPreserveMethod(
string pageName = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
routeValues: routeValues,
permanent: true,
preserveMethod: true,
fragment: fragment);
}

/// <summary>
/// Creates a <see cref="SignInResult"/> with the specified authentication scheme.
/// </summary>
Expand Down
54 changes: 49 additions & 5 deletions src/Microsoft.AspNetCore.Mvc.RazorPages/RedirectToPageResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public RedirectToPageResult(string pageName, object routeValues)
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The name of the route.</param>
/// <param name="routeValues">The parameters for the route.</param>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for the page.</param>
/// <param name="permanent">If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).</param>
public RedirectToPageResult(
string pageName,
Expand All @@ -52,11 +52,27 @@ public RedirectToPageResult(string pageName, object routeValues)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for the page.</param>
/// <param name="permanent">If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).</param>
/// <param name="preserveMethod">If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the intial request method.</param>
public RedirectToPageResult(
string pageName,
object routeValues,
bool permanent,
bool preserveMethod)
: this(pageName, routeValues, permanent, preserveMethod, fragment: null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The name of the route.</param>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for the route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
public RedirectToPageResult(
Expand All @@ -71,8 +87,8 @@ public RedirectToPageResult(string pageName, object routeValues)
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The name of the route.</param>
/// <param name="routeValues">The parameters for the route.</param>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for the page.</param>
/// <param name="permanent">If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).</param>
/// <param name="fragment">The fragment to add to the URL.</param>
public RedirectToPageResult(
Expand All @@ -87,6 +103,29 @@ public RedirectToPageResult(string pageName, object routeValues)
Fragment = fragment;
}

/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for the page.</param>
/// <param name="permanent">If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).</param>
/// <param name="preserveMethod">If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the intial request method.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
public RedirectToPageResult(
string pageName,
object routeValues,
bool permanent,
bool preserveMethod,
string fragment)
{
PageName = pageName;
RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues);
PreserveMethod = preserveMethod;
Permanent = permanent;
Fragment = fragment;
}

/// <summary>
/// Gets or sets the <see cref="IUrlHelper" /> used to generate URLs.
/// </summary>
Expand All @@ -107,6 +146,11 @@ public RedirectToPageResult(string pageName, object routeValues)
/// </summary>
public bool Permanent { get; set; }

/// <summary>
/// Gets or sets an indication that the redirect preserves the initial request method.
/// </summary>
public bool PreserveMethod { get; set; }

/// <summary>
/// Gets or sets the fragment to add to the URL.
/// </summary>
Expand Down
60 changes: 60 additions & 0 deletions test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,65 @@ public static IEnumerable<object[]> RedirectTestData
}
}

[Fact]
public void RedirectToPagePreserveMethod_WithParameterUrl_SetsRedirectResultPreserveMethod()
{
// Arrange
var pageModel = new TestPageModel();
var url = "/test/url";

// Act
var result = pageModel.RedirectToPagePreserveMethod(url);

// Assert
Assert.IsType<RedirectToPageResult>(result);
Assert.True(result.PreserveMethod);
Assert.False(result.Permanent);
Assert.Same(url, result.PageName);
}

[Theory]
[MemberData(nameof(RedirectTestData))]
public void RedirectToPagePreserveMethod_SetsResultProperties(
object routeValues,
IEnumerable<KeyValuePair<string, object>> expected)
{
// Arrange
var pageModel = new TestPageModel();
var pageName = "CustomRouteName";

// Act
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues);

// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
Assert.True(resultPermanent.PreserveMethod);
Assert.False(resultPermanent.Permanent);
Assert.Same(pageName, resultPermanent.PageName);
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Theory]
[MemberData(nameof(RedirectTestData))]
public void RedirectToPagePermanentPreserveMethod_SetsResultProperties(
object routeValues,
IEnumerable<KeyValuePair<string, object>> expected)
{
// Arrange
var pageModel = new TestPageModel();
var routeName = "CustomRouteName";

// Act
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues);

// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
Assert.True(resultPermanent.PreserveMethod);
Assert.True(resultPermanent.Permanent);
Assert.Same(routeName, resultPermanent.PageName);
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Theory]
[MemberData(nameof(RedirectTestData))]
public void RedirectToRoute_WithParameterRouteNameAndRouteValues_SetsResultSameRouteNameAndRouteValues(
Expand Down Expand Up @@ -1020,6 +1079,7 @@ public static IEnumerable<object[]> RedirectTestData
Assert.Same(routeName, resultPermanent.RouteName);
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Fact]
public void File_WithContents()
{
Expand Down
59 changes: 59 additions & 0 deletions test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,65 @@ public void RedirectToRoutePermanentPreserveMethod_WithParameterRouteName_SetsRe
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Fact]
public void RedirectToPagePreserveMethod_WithParameterUrl_SetsRedirectResultPreserveMethod()
{
// Arrange
var pageModel = new TestPage();
var url = "/test/url";

// Act
var result = pageModel.RedirectToPagePreserveMethod(url);

// Assert
Assert.IsType<RedirectToPageResult>(result);
Assert.True(result.PreserveMethod);
Assert.False(result.Permanent);
Assert.Same(url, result.PageName);
}

[Theory]
[MemberData(nameof(RedirectTestData))]
public void RedirectToPagePreserveMethod_SetsResultProperties(
object routeValues,
IEnumerable<KeyValuePair<string, object>> expected)
{
// Arrange
var pageModel = new TestPage();
var pageName = "CustomRouteName";

// Act
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues);

// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
Assert.True(resultPermanent.PreserveMethod);
Assert.False(resultPermanent.Permanent);
Assert.Same(pageName, resultPermanent.PageName);
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Theory]
[MemberData(nameof(RedirectTestData))]
public void RedirectToPagePermanentPreserveMethod_SetsResultProperties(
object routeValues,
IEnumerable<KeyValuePair<string, object>> expected)
{
// Arrange
var pageModel = new TestPage();
var routeName = "CustomRouteName";

// Act
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues);

// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
Assert.True(resultPermanent.PreserveMethod);
Assert.True(resultPermanent.Permanent);
Assert.Same(routeName, resultPermanent.PageName);
Assert.Equal(expected, resultPermanent.RouteValues);
}

[Fact]
public void File_WithContents()
{
Expand Down

0 comments on commit 6ac7681

Please sign in to comment.