diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/RedirectToPageResultExecutor.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/RedirectToPageResultExecutor.cs
index 8a7494cdb9..8ff19456af 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/RedirectToPageResultExecutor.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/RedirectToPageResultExecutor.cs
@@ -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
{
@@ -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);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
index 23d90aa12d..3ad708a7b1 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
@@ -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);
+ ///
+ /// Redirects () to the specified page with
+ /// set to false and
+ /// set to true, using the specified , , and .
+ ///
+ /// The name of the page.
+ /// The route data to use for generating the URL.
+ /// The fragment to add to the URL.
+ /// The created for the response.
+ 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);
+ }
+
+ ///
+ /// Redirects () to the specified route with
+ /// set to true and
+ /// set to true, using the specified , , and .
+ ///
+ /// The name of the page.
+ /// The route data to use for generating the URL.
+ /// The fragment to add to the URL.
+ /// The created for the response.
+ 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);
+ }
+
///
/// Creates a with the specified authentication scheme.
///
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs
index afbc007b9e..dc8ab8b044 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs
@@ -513,7 +513,14 @@ public virtual PhysicalFileResult PhysicalFile(string physicalPath, string conte
/// The URL to redirect to.
/// The created for the response.
protected internal RedirectResult Redirect(string url)
- => new RedirectResult(url);
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(url));
+ }
+
+ return new RedirectResult(url);
+ }
///
/// Creates a object with set to true
@@ -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);
+ ///
+ /// Redirects () to the specified page with
+ /// set to false and
+ /// set to true, using the specified , , and .
+ ///
+ /// The name of the page.
+ /// The route data to use for generating the URL.
+ /// The fragment to add to the URL.
+ /// The created for the response.
+ 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);
+ }
+
+ ///
+ /// Redirects () to the specified route with
+ /// set to true and
+ /// set to true, using the specified , , and .
+ ///
+ /// The name of the page.
+ /// The route data to use for generating the URL.
+ /// The fragment to add to the URL.
+ /// The created for the response.
+ 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);
+ }
+
///
/// Creates a with the specified authentication scheme.
///
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/RedirectToPageResult.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/RedirectToPageResult.cs
index d808d1f44b..fcb29e81b5 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/RedirectToPageResult.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/RedirectToPageResult.cs
@@ -41,8 +41,8 @@ public RedirectToPageResult(string pageName, object routeValues)
/// Initializes a new instance of the with the values
/// provided.
///
- /// The name of the route.
- /// The parameters for the route.
+ /// The name of the page.
+ /// The parameters for the page.
/// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).
public RedirectToPageResult(
string pageName,
@@ -52,11 +52,27 @@ public RedirectToPageResult(string pageName, object routeValues)
{
}
+ ///
+ /// Initializes a new instance of the with the values provided.
+ ///
+ /// The name of the page.
+ /// The parameters for the page.
+ /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).
+ /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the intial request method.
+ public RedirectToPageResult(
+ string pageName,
+ object routeValues,
+ bool permanent,
+ bool preserveMethod)
+ : this(pageName, routeValues, permanent, preserveMethod, fragment: null)
+ {
+ }
+
///
/// Initializes a new instance of the with the values
/// provided.
///
- /// The name of the route.
+ /// The name of the page.
/// The parameters for the route.
/// The fragment to add to the URL.
public RedirectToPageResult(
@@ -71,8 +87,8 @@ public RedirectToPageResult(string pageName, object routeValues)
/// Initializes a new instance of the with the values
/// provided.
///
- /// The name of the route.
- /// The parameters for the route.
+ /// The name of the page.
+ /// The parameters for the page.
/// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).
/// The fragment to add to the URL.
public RedirectToPageResult(
@@ -87,6 +103,29 @@ public RedirectToPageResult(string pageName, object routeValues)
Fragment = fragment;
}
+ ///
+ /// Initializes a new instance of the with the values
+ /// provided.
+ ///
+ /// The name of the page.
+ /// The parameters for the page.
+ /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302).
+ /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the intial request method.
+ /// The fragment to add to the URL.
+ 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;
+ }
+
///
/// Gets or sets the used to generate URLs.
///
@@ -107,6 +146,11 @@ public RedirectToPageResult(string pageName, object routeValues)
///
public bool Permanent { get; set; }
+ ///
+ /// Gets or sets an indication that the redirect preserves the initial request method.
+ ///
+ public bool PreserveMethod { get; set; }
+
///
/// Gets or sets the fragment to add to the URL.
///
diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs
index 87509ff87c..e5019878b8 100644
--- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs
@@ -937,6 +937,65 @@ public static IEnumerable