Add support for page handler to URL generating APIs.

This commit is contained in:
Pranav K 2017-04-24 15:02:07 -07:00
parent ef0333ac6a
commit 649ee4d28d
25 changed files with 507 additions and 125 deletions

View File

@ -961,30 +961,54 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPage(string pageName, object routeValues)
=> RedirectToPage(pageName, routeValues, fragment: null);
=> RedirectToPage(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler)
=> RedirectToPage(pageName, pageHandler, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, object routeValues)
=> RedirectToPage(pageName, pageHandler, routeValues);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPage(string pageName, string fragment)
=> RedirectToPage(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, string fragment)
=> RedirectToPage(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPage(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, pageHandler, routeValues, fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>.
@ -1004,30 +1028,49 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues)
=> RedirectToPagePermanent(pageName, routeValues, fragment: null);
=> RedirectToPagePermanent(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler)
=> RedirectToPagePermanent(pageName, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string fragment)
=> RedirectToPagePermanent(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, string fragment)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, permanent: true, fragment: fragment);
public virtual RedirectToPageResult RedirectToPagePermanent(
string pageName,
string pageHandler,
object routeValues,
string fragment)
{
return new RedirectToPageResult(pageName, pageHandler, routeValues, permanent: true, fragment: fragment);
}
/// <summary>
/// Redirects (<see cref="StatusCodes.Status307TemporaryRedirect"/>) to the specified page with
@ -1035,12 +1078,14 @@ namespace Microsoft.AspNetCore.Mvc
/// 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="pageHandler">The page handler to redirect to.</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>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePreserveMethod(
string pageName,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
@ -1051,6 +1096,7 @@ namespace Microsoft.AspNetCore.Mvc
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: false,
preserveMethod: true,
@ -1063,12 +1109,14 @@ namespace Microsoft.AspNetCore.Mvc
/// 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="pageHandler">The page handler to redirect to.</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>
[NonAction]
public virtual RedirectToPageResult RedirectToPagePermanentPreserveMethod(
string pageName,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
@ -1079,6 +1127,7 @@ namespace Microsoft.AspNetCore.Mvc
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: true,
preserveMethod: true,

View File

@ -36,6 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var urlHelper = result.UrlHelper ?? _urlHelperFactory.GetUrlHelper(context);
var destinationUrl = urlHelper.Page(
result.PageName,
result.PageHandler,
result.RouteValues,
result.Protocol,
result.Host,

View File

@ -26,6 +26,17 @@ namespace Microsoft.AspNetCore.Mvc
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The page to redirect to.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
public RedirectToPageResult(string pageName, string pageHandler)
: this(pageName, pageHandler, routeValues: null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
@ -33,7 +44,19 @@ namespace Microsoft.AspNetCore.Mvc
/// <param name="pageName">The page to redirect to.</param>
/// <param name="routeValues">The parameters for the route.</param>
public RedirectToPageResult(string pageName, object routeValues)
: this(pageName, routeValues, permanent: false)
: this(pageName, pageHandler: null, routeValues: routeValues, permanent: false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RedirectToPageResult"/> with the values
/// provided.
/// </summary>
/// <param name="pageName">The page to redirect to.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for the route.</param>
public RedirectToPageResult(string pageName, string pageHandler, object routeValues)
: this(pageName, pageHandler, routeValues, permanent: false)
{
}
@ -42,13 +65,15 @@ namespace Microsoft.AspNetCore.Mvc
/// provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</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,
string pageHandler,
object routeValues,
bool permanent)
: this(pageName, routeValues, permanent, fragment: null)
: this(pageName, pageHandler, routeValues, permanent, fragment: null)
{
}
@ -56,15 +81,17 @@ namespace Microsoft.AspNetCore.Mvc
/// 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="pageHandler">The page handler to redirect to.</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,
string pageHandler,
object routeValues,
bool permanent,
bool preserveMethod)
: this(pageName, routeValues, permanent, preserveMethod, fragment: null)
: this(pageName, pageHandler, routeValues, permanent, preserveMethod, fragment: null)
{
}
@ -73,13 +100,15 @@ namespace Microsoft.AspNetCore.Mvc
/// provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for the route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
public RedirectToPageResult(
string pageName,
string pageHandler,
object routeValues,
string fragment)
: this(pageName, routeValues, permanent: false, fragment: fragment)
: this(pageName, pageHandler, routeValues, permanent: false, fragment: fragment)
{
}
@ -88,19 +117,19 @@ namespace Microsoft.AspNetCore.Mvc
/// provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</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(
string pageName,
string pageHandler,
object routeValues,
bool permanent,
string fragment)
: this(pageName, pageHandler, routeValues, permanent, preserveMethod: false, fragment: fragment)
{
PageName = pageName;
RouteValues = routeValues == null ? new RouteValueDictionary() : new RouteValueDictionary(routeValues);
Permanent = permanent;
Fragment = fragment;
}
/// <summary>
@ -108,18 +137,21 @@ namespace Microsoft.AspNetCore.Mvc
/// provided.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</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,
string pageHandler,
object routeValues,
bool permanent,
bool preserveMethod,
string fragment)
{
PageName = pageName;
PageHandler = pageHandler;
RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues);
PreserveMethod = preserveMethod;
Permanent = permanent;
@ -136,6 +168,11 @@ namespace Microsoft.AspNetCore.Mvc
/// </summary>
public string PageName { get; set; }
/// <summary>
/// Gets or sets the the page handler to redirect to.
/// </summary>
public string PageHandler { get; set; }
/// <summary>
/// Gets or sets the route data to use for generating the URL.
/// </summary>

View File

@ -351,13 +351,10 @@ namespace Microsoft.AspNetCore.Mvc
/// </summary>
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="values">An object that contains route values.</param>
/// <param name="pageHandler">The handler to generate the url for.</param>
/// <returns>The generated URL.</returns>
public static string Page(
this IUrlHelper urlHelper,
string pageName,
object values)
=> Page(urlHelper, pageName, values, protocol: null);
public static string Page(this IUrlHelper urlHelper, string pageName, string pageHandler)
=> Page(urlHelper, pageName, pageHandler, values: null);
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.
@ -365,20 +362,48 @@ namespace Microsoft.AspNetCore.Mvc
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="values">An object that contains route values.</param>
/// <returns>The generated URL.</returns>
public static string Page(this IUrlHelper urlHelper, string pageName, object values)
=> Page(urlHelper, pageName, pageHandler: null, values: values);
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="pageHandler">The handler to generate the url for.</param>
/// <param name="values">An object that contains route values.</param>
/// <returns>The generated URL.</returns>
public static string Page(
this IUrlHelper urlHelper,
string pageName,
string pageHandler,
object values)
=> Page(urlHelper, pageName, pageHandler, values, protocol: null);
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="pageHandler">The handler to generate the url for.</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>
/// <returns>The generated URL.</returns>
public static string Page(
this IUrlHelper urlHelper,
string pageName,
string pageHandler,
object values,
string protocol)
=> Page(urlHelper, pageName, values, protocol, host: null, fragment: null);
=> Page(urlHelper, pageName, pageHandler, values, protocol, host: null, fragment: null);
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="pageHandler">The handler to generate the url for.</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>
@ -386,16 +411,18 @@ namespace Microsoft.AspNetCore.Mvc
public static string Page(
this IUrlHelper urlHelper,
string pageName,
string pageHandler,
object values,
string protocol,
string host)
=> Page(urlHelper, pageName, values, protocol, host, fragment: null);
=> Page(urlHelper, pageName, pageHandler, values, protocol, host, fragment: null);
/// <summary>
/// Generates a URL with an absolute path for the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="urlHelper">The <see cref="IUrlHelper"/>.</param>
/// <param name="pageName">The page name to generate the url for.</param>
/// <param name="pageHandler">The handler to generate the url for.</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>
@ -404,6 +431,7 @@ namespace Microsoft.AspNetCore.Mvc
public static string Page(
this IUrlHelper urlHelper,
string pageName,
string pageHandler,
object values,
string protocol,
string host,
@ -429,11 +457,18 @@ namespace Microsoft.AspNetCore.Mvc
routeValues["page"] = CalculatePageName(urlHelper.ActionContext, pageName);
}
if (!routeValues.ContainsKey("handler") &&
ambientValues.TryGetValue("handler", out var handler))
if (string.IsNullOrEmpty(pageHandler))
{
// Clear out handler unless it's explicitly specified in the routeValues.
routeValues["handler"] = null;
if (!routeValues.ContainsKey("handler") &&
ambientValues.TryGetValue("handler", out var handler))
{
// Clear out formaction unless it's explicitly specified in the routeValues.
routeValues["handler"] = null;
}
}
else
{
routeValues["handler"] = pageHandler;
}
return urlHelper.RouteUrl(

View File

@ -160,7 +160,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
}
}
#region Factory methods
/// <summary>
/// Creates a <see cref="ChallengeResult"/>.
/// </summary>
@ -970,6 +969,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
public virtual RedirectToPageResult RedirectToPage(string pageName)
=> RedirectToPage(pageName, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler)
=> RedirectToPage(pageName, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/>.
@ -978,28 +987,30 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, object routeValues)
=> RedirectToPage(pageName, routeValues, fragment: null);
=> RedirectToPage(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, string fragment)
=> RedirectToPage(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, string fragment)
=> RedirectToPage(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, pageHandler, routeValues, fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>.
@ -1007,7 +1018,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <param name="pageName">The name of the page.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName)
=> RedirectToPagePermanent(pageName, routeValues: null);
=> RedirectToPagePermanent(pageName, pageHandler: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
@ -1017,28 +1028,51 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues)
=> RedirectToPagePermanent(pageName, routeValues, fragment: null);
=> RedirectToPagePermanent(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, object routeValues)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string fragment)
=> RedirectToPagePermanent(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, string fragment)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
protected RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, permanent: true, fragment: fragment);
protected RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, pageHandler, routeValues, permanent: true, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status307TemporaryRedirect"/>) to the specified page with
@ -1046,16 +1080,19 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// 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="pageHandler">The page handler to redirect to.</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,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: false,
preserveMethod: true,
@ -1068,16 +1105,19 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// 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="pageHandler">The page handler to redirect to.</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,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: true,
preserveMethod: true,
@ -1157,11 +1197,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// Returning a <see cref="PageViewResult"/> from a page handler method is equivalent to returning void.
/// The view associated with the page will be executed.
/// </remarks>
protected PageViewResult View()
{
return new PageViewResult(this);
}
#endregion Factory methods
protected PageViewResult View() => new PageViewResult(this);
/// <summary>
/// Updates the specified <paramref name="model"/> instance using values from the <see cref="Page"/>'s current

View File

@ -488,7 +488,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
propertyFilter);
}
#region Factory methods
/// <summary>
/// Creates a <see cref="ChallengeResult"/>.
/// </summary>
@ -1298,9 +1297,30 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected internal RedirectToPageResult RedirectToPage(string pageName)
public virtual RedirectToPageResult RedirectToPage(string pageName)
=> RedirectToPage(pageName, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler)
=> RedirectToPage(pageName, pageHandler, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="pageHandler"/> and <paramref name="routeValues"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, object routeValues)
=> RedirectToPage(pageName, pageHandler, routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/>.
@ -1308,37 +1328,39 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected internal RedirectToPageResult RedirectToPage(string pageName, object routeValues)
=> RedirectToPage(pageName, routeValues, fragment: null);
public virtual RedirectToPageResult RedirectToPage(string pageName, object routeValues)
=> RedirectToPage(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected internal RedirectToPageResult RedirectToPage(string pageName, string fragment)
=> RedirectToPage(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, string fragment)
=> RedirectToPage(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status302Found"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/>.</returns>
protected internal RedirectToPageResult RedirectToPage(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, fragment);
public virtual RedirectToPageResult RedirectToPage(string pageName, string pageHandler, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, pageHandler, routeValues, fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
protected internal RedirectToPageResult RedirectToPagePermanent(string pageName)
=> RedirectToPagePermanent(pageName, routeValues: null);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName)
=> RedirectToPagePermanent(pageName, pageHandler: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
@ -1347,29 +1369,62 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
protected internal RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues)
=> RedirectToPagePermanent(pageName, routeValues, fragment: null);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues)
=> RedirectToPagePermanent(pageName, pageHandler: null, routeValues: routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, object routeValues)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues, fragment: null);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
protected internal RedirectToPageResult RedirectToPagePermanent(string pageName, string fragment)
=> RedirectToPagePermanent(pageName, routeValues: null, fragment: fragment);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, string fragment)
=> RedirectToPagePermanent(pageName, pageHandler, routeValues: null, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> RedirectToPagePermanent(pageName, pageHandler: null, routeValues: routeValues, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status301MovedPermanently"/>) to the specified <paramref name="pageName"/>
/// using the specified <paramref name="routeValues"/> and <paramref name="fragment"/>.
/// </summary>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to redirect to.</param>
/// <param name="routeValues">The parameters for a route.</param>
/// <param name="fragment">The fragment to add to the URL.</param>
/// <returns>The <see cref="RedirectToPageResult"/> with <see cref="RedirectToPageResult.Permanent"/> set.</returns>
protected internal RedirectToPageResult RedirectToPagePermanent(string pageName, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, routeValues, permanent: true, fragment: fragment);
public virtual RedirectToPageResult RedirectToPagePermanent(string pageName, string pageHandler, object routeValues, string fragment)
=> new RedirectToPageResult(pageName, pageHandler, routeValues, permanent: true, fragment: fragment);
/// <summary>
/// Redirects (<see cref="StatusCodes.Status307TemporaryRedirect"/>) to the specified page with
@ -1377,16 +1432,19 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// 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="pageHandler">The page handler to redirect to.</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,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: false,
preserveMethod: true,
@ -1399,16 +1457,19 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// 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="pageHandler">The page handler to redirect to.</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,
string pageHandler = null,
object routeValues = null,
string fragment = null)
{
return new RedirectToPageResult(
pageName: pageName,
pageHandler: pageHandler,
routeValues: routeValues,
permanent: true,
preserveMethod: true,
@ -1493,7 +1554,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
{
return new PageViewResult(Page);
}
#endregion Factory methods
/// <summary>
/// Validates the specified <paramref name="model"/> instance.

View File

@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("a", Attributes = ControllerAttributeName)]
[HtmlTargetElement("a", Attributes = AreaAttributeName)]
[HtmlTargetElement("a", Attributes = PageAttributeName)]
[HtmlTargetElement("a", Attributes = PageHandlerAttributeName)]
[HtmlTargetElement("a", Attributes = FragmentAttributeName)]
[HtmlTargetElement("a", Attributes = HostAttributeName)]
[HtmlTargetElement("a", Attributes = ProtocolAttributeName)]
@ -29,6 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string ControllerAttributeName = "asp-controller";
private const string AreaAttributeName = "asp-area";
private const string PageAttributeName = "asp-page";
private const string PageHandlerAttributeName = "asp-page-handler";
private const string FragmentAttributeName = "asp-fragment";
private const string HostAttributeName = "asp-host";
private const string ProtocolAttributeName = "asp-protocol";
@ -95,6 +97,16 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlAttributeName(PageAttributeName)]
public string Page { get; set; }
/// <summary>
/// The name of the page handler.
/// </summary>
/// <remarks>
/// Must be <c>null</c> if <see cref="Route"/> or <see cref="Action"/>, or <see cref="Controller"/>
/// is non-<c>null</c>.
/// </remarks>
[HtmlAttributeName(PageHandlerAttributeName)]
public string PageHandler { get; set; }
/// <summary>
/// The protocol for the URL, such as &quot;http&quot; or &quot;https&quot;.
/// </summary>
@ -172,6 +184,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Controller != null ||
Area != null ||
Page != null ||
PageHandler != null ||
Route != null ||
Protocol != null ||
Host != null ||
@ -191,7 +204,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
ProtocolAttributeName,
HostAttributeName,
FragmentAttributeName,
PageAttributeName));
PageAttributeName,
PageHandlerAttributeName));
}
return;
@ -199,7 +213,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var routeLink = Route != null;
var actionLink = Controller != null || Action != null;
var pageLink = Page != null;
var pageLink = Page != null || PageHandler != null;
if ((routeLink && actionLink) || (routeLink && pageLink) || (actionLink && pageLink))
{
@ -208,7 +222,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Resources.FormatCannotDetermineAttributeFor(Href, "<a>"),
RouteAttributeName,
ControllerAttributeName + ", " + ActionAttributeName,
PageAttributeName);
PageAttributeName + ", " + PageHandlerAttributeName);
throw new InvalidOperationException(message);
}
@ -236,6 +250,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
ViewContext,
linkText: string.Empty,
pageName: Page,
pageHandler: PageHandler,
protocol: Protocol,
hostname: Host,
fragment: Fragment,

View File

@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("button", Attributes = ControllerAttributeName)]
[HtmlTargetElement("button", Attributes = AreaAttributeName)]
[HtmlTargetElement("button", Attributes = PageAttributeName)]
[HtmlTargetElement("button", Attributes = PageHandlerAttributeName)]
[HtmlTargetElement("button", Attributes = FragmentAttributeName)]
[HtmlTargetElement("button", Attributes = RouteAttributeName)]
[HtmlTargetElement("button", Attributes = RouteValuesDictionaryName)]
@ -27,6 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("input", Attributes = ImageControllerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImageAreaAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImagePageAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImagePageHandlerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImageFragmentAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImageRouteAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = ImageRouteValuesDictionarySelector, TagStructure = TagStructure.WithoutEndTag)]
@ -35,6 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("input", Attributes = SubmitControllerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitAreaAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitPageAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitPageHandlerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitFragmentAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitRouteAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("input", Attributes = SubmitRouteValuesDictionarySelector, TagStructure = TagStructure.WithoutEndTag)]
@ -45,6 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string AreaAttributeName = "asp-area";
private const string ControllerAttributeName = "asp-controller";
private const string PageAttributeName = "asp-page";
private const string PageHandlerAttributeName = "asp-page-handler";
private const string FragmentAttributeName = "asp-fragment";
private const string RouteAttributeName = "asp-route";
private const string RouteValuesDictionaryName = "asp-all-route-data";
@ -55,6 +59,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string ImageActionAttributeSelector = ImageTypeSelector + ActionAttributeName;
private const string ImageAreaAttributeSelector = ImageTypeSelector + AreaAttributeName;
private const string ImagePageAttributeSelector = ImageTypeSelector + PageAttributeName;
private const string ImagePageHandlerAttributeSelector = ImageTypeSelector + PageHandlerAttributeName;
private const string ImageFragmentAttributeSelector = ImageTypeSelector + FragmentAttributeName;
private const string ImageControllerAttributeSelector = ImageTypeSelector + ControllerAttributeName;
private const string ImageRouteAttributeSelector = ImageTypeSelector + RouteAttributeName;
@ -65,6 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string SubmitActionAttributeSelector = SubmitTypeSelector + ActionAttributeName;
private const string SubmitAreaAttributeSelector = SubmitTypeSelector + AreaAttributeName;
private const string SubmitPageAttributeSelector = SubmitTypeSelector + PageAttributeName;
private const string SubmitPageHandlerAttributeSelector = SubmitTypeSelector + PageHandlerAttributeName;
private const string SubmitFragmentAttributeSelector = SubmitTypeSelector + FragmentAttributeName;
private const string SubmitControllerAttributeSelector = SubmitTypeSelector + ControllerAttributeName;
private const string SubmitRouteAttributeSelector = SubmitTypeSelector + RouteAttributeName;
@ -118,6 +124,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlAttributeName(PageAttributeName)]
public string Page { get; set; }
/// <summary>
/// The name of the page handler.
/// </summary>
[HtmlAttributeName(PageHandlerAttributeName)]
public string PageHandler { get; set; }
/// <summary>
/// Gets or sets the URL fragment.
/// </summary>
@ -180,6 +192,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
if (Action != null ||
Controller != null ||
Area != null ||
Page != null ||
PageHandler != null ||
Fragment != null ||
Route != null ||
(_routeValues != null && _routeValues.Count > 0))
@ -188,14 +202,16 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
// attribute.
throw new InvalidOperationException(
Resources.FormatFormActionTagHelper_CannotOverrideFormAction(
FormAction,
output.TagName,
RouteValuesPrefix,
ActionAttributeName,
ControllerAttributeName,
AreaAttributeName,
FragmentAttributeName,
RouteAttributeName,
RouteValuesPrefix,
FormAction));
PageAttributeName,
PageHandlerAttributeName));
}
return;
@ -203,7 +219,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var routeLink = Route != null;
var actionLink = Controller != null || Action != null;
var pageLink = Page != null;
var pageLink = Page != null || PageHandler != null;
if ((routeLink && actionLink) || (routeLink && pageLink) || (actionLink && pageLink))
{
@ -212,7 +228,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Resources.FormatCannotDetermineAttributeFor(FormAction, '<' + output.TagName + '>'),
RouteAttributeName,
ControllerAttributeName + ", " + ActionAttributeName,
PageAttributeName);
PageAttributeName + ", " + PageHandlerAttributeName);
throw new InvalidOperationException(message);
}
@ -238,7 +254,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
string url;
if (pageLink)
{
url = urlHelper.Page(Page, routeValues, protocol: null, host: null, fragment: Fragment);
url = urlHelper.Page(Page, PageHandler, routeValues, protocol: null, host: null, fragment: Fragment);
}
else if (routeLink)
{

View File

@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string AntiforgeryAttributeName = "asp-antiforgery";
private const string AreaAttributeName = "asp-area";
private const string PageAttributeName = "asp-page";
private const string PageHandlerAttributeName = "asp-page-handler";
private const string FragmentAttributeName = "asp-fragment";
private const string ControllerAttributeName = "asp-controller";
private const string RouteAttributeName = "asp-route";
@ -74,6 +75,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlAttributeName(PageAttributeName)]
public string Page { get; set; }
/// <summary>
/// The name of the page handler.
/// </summary>
[HtmlAttributeName(PageHandlerAttributeName)]
public string PageHandler { get; set; }
/// <summary>
/// Whether the antiforgery token should be generated.
/// </summary>
@ -164,6 +171,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Controller != null ||
Area != null ||
Page != null ||
PageHandler != null ||
Fragment != null ||
Route != null ||
(_routeValues != null && _routeValues.Count > 0))
@ -179,7 +187,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
FragmentAttributeName,
AreaAttributeName,
RouteAttributeName,
PageAttributeName));
PageAttributeName,
PageHandlerAttributeName));
}
string attributeValue = null;
@ -210,7 +219,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
{
var routeLink = Route != null;
var actionLink = Controller != null || Action != null;
var pageLink = Page != null;
var pageLink = Page != null || PageHandler != null;
if ((routeLink && actionLink) || (routeLink && pageLink) || (actionLink && pageLink))
{
@ -259,6 +268,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
tagBuilder = Generator.GeneratePageForm(
ViewContext,
Page,
PageHandler,
routeValues,
Fragment,
method: null,

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
=> string.Format(CultureInfo.CurrentCulture, GetString("CannotDetermineAttributeFor"), p0, p1);
/// <summary>
/// Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', or '{10}' attribute.
/// Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}' or '{11}' attribute.
/// </summary>
internal static string AnchorTagHelper_CannotOverrideHref
{
@ -33,13 +33,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
}
/// <summary>
/// Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', or '{10}' attribute.
/// Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}' or '{11}' attribute.
/// </summary>
internal static string FormatAnchorTagHelper_CannotOverrideHref(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7, object p8, object p9, object p10)
=> string.Format(CultureInfo.CurrentCulture, GetString("AnchorTagHelper_CannotOverrideHref"), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
internal static string FormatAnchorTagHelper_CannotOverrideHref(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7, object p8, object p9, object p10, object p11)
=> string.Format(CultureInfo.CurrentCulture, GetString("AnchorTagHelper_CannotOverrideHref"), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
/// <summary>
/// Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}' or '{8}' attribute.
/// Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.
/// </summary>
internal static string FormTagHelper_CannotOverrideAction
{
@ -47,10 +47,10 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
}
/// <summary>
/// Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}' or '{8}' attribute.
/// Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.
/// </summary>
internal static string FormatFormTagHelper_CannotOverrideAction(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7, object p8)
=> string.Format(CultureInfo.CurrentCulture, GetString("FormTagHelper_CannotOverrideAction"), p0, p1, p2, p3, p4, p5, p6, p7, p8);
internal static string FormatFormTagHelper_CannotOverrideAction(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7, object p8, object p9)
=> string.Format(CultureInfo.CurrentCulture, GetString("FormTagHelper_CannotOverrideAction"), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
/// <summary>
/// Unexpected '{1}' expression result type '{2}' for {0}. '{1}' must be of type '{3}' or '{4}' that can be parsed as a '{3}' if '{5}' is '{6}'.
@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
=> string.Format(CultureInfo.CurrentCulture, GetString("PropertyOfTypeCannotBeNull"), p0, p1);
/// <summary>
/// Cannot override the '{7}' attribute for &lt;{0}&gt;. &lt;{0}&gt; elements with a specified '{7}' must not have attributes starting with '{6}' or an '{1}', '{2}', '{3}', '{4}', or '{5}' attribute.
/// Cannot override the '{0}' attribute for &lt;{1}&gt;. &lt;{1}&gt; elements with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.
/// </summary>
internal static string FormActionTagHelper_CannotOverrideFormAction
{
@ -159,10 +159,10 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
}
/// <summary>
/// Cannot override the '{7}' attribute for &lt;{0}&gt;. &lt;{0}&gt; elements with a specified '{7}' must not have attributes starting with '{6}' or an '{1}', '{2}', '{3}', '{4}', or '{5}' attribute.
/// Cannot override the '{0}' attribute for &lt;{1}&gt;. &lt;{1}&gt; elements with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.
/// </summary>
internal static string FormatFormActionTagHelper_CannotOverrideFormAction(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7)
=> string.Format(CultureInfo.CurrentCulture, GetString("FormActionTagHelper_CannotOverrideFormAction"), p0, p1, p2, p3, p4, p5, p6, p7);
internal static string FormatFormActionTagHelper_CannotOverrideFormAction(object p0, object p1, object p2, object p3, object p4, object p5, object p6, object p7, object p8, object p9)
=> string.Format(CultureInfo.CurrentCulture, GetString("FormActionTagHelper_CannotOverrideFormAction"), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
private static string GetString(string name, params string[] formatterNames)
{

View File

@ -121,10 +121,10 @@
<value>Cannot determine the '{0}' attribute for {1}. The following attributes are mutually exclusive:</value>
</data>
<data name="AnchorTagHelper_CannotOverrideHref" xml:space="preserve">
<value>Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', or '{10}' attribute.</value>
<value>Cannot override the '{0}' attribute for {1}. An {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}' or '{11}' attribute.</value>
</data>
<data name="FormTagHelper_CannotOverrideAction" xml:space="preserve">
<value>Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}' or '{8}' attribute.</value>
<value>Cannot override the '{0}' attribute for {1}. A {1} with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.</value>
</data>
<data name="InputTagHelper_InvalidExpressionResult" xml:space="preserve">
<value>Unexpected '{1}' expression result type '{2}' for {0}. '{1}' must be of type '{3}' or '{4}' that can be parsed as a '{3}' if '{5}' is '{6}'.</value>
@ -148,6 +148,6 @@
<value>The '{0}' property of '{1}' must not be null.</value>
</data>
<data name="FormActionTagHelper_CannotOverrideFormAction" xml:space="preserve">
<value>Cannot override the '{7}' attribute for &lt;{0}&gt;. &lt;{0}&gt; elements with a specified '{7}' must not have attributes starting with '{6}' or an '{1}', '{2}', '{3}', '{4}', or '{5}' attribute.</value>
<value>Cannot override the '{0}' attribute for &lt;{1}&gt;. &lt;{1}&gt; elements with a specified '{0}' must not have attributes starting with '{2}' or an '{3}', '{4}', '{5}', '{6}', '{7}', '{8}' or '{9}' attribute.</value>
</data>
</root>

View File

@ -147,6 +147,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
ViewContext viewContext,
string linkText,
string pageName,
string pageHandler,
string protocol,
string hostname,
string fragment,
@ -164,7 +165,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
}
var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);
var url = urlHelper.Page(pageName, routeValues, protocol, hostname, fragment);
var url = urlHelper.Page(pageName, pageHandler, routeValues, protocol, hostname, fragment);
return GenerateLink(linkText, url, htmlAttributes);
}
@ -311,6 +312,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
public virtual TagBuilder GeneratePageForm(
ViewContext viewContext,
string pageName,
string pageHandler,
object routeValues,
string fragment,
string method,
@ -347,7 +349,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
else
{
var urlHelper = _urlHelperFactory.GetUrlHelper(viewContext);
action = urlHelper.Page(pageName, values: routeValues,protocol: null, host: null, fragment: fragment);
action = urlHelper.Page(pageName, pageHandler, routeValues, protocol: null, host: null, fragment: fragment);
}
return GenerateFormCore(viewContext, action, method, htmlAttributes);

View File

@ -60,6 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
/// <param name="viewContext">The <see cref="ViewContext"/> instance for the current scope.</param>
/// <param name="linkText">The text to insert inside the element.</param>
/// <param name="pageName">The page name.</param>
/// <param name="pageHandler">The page handler.</param>
/// <param name="protocol">The protocol (scheme) for the generated link.</param>
/// <param name="hostname">The hostname for the generated link.</param>
/// <param name="fragment">The fragment for the genrated link.</param>
@ -80,6 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
ViewContext viewContext,
string linkText,
string pageName,
string pageHandler,
string protocol,
string hostname,
string fragment,
@ -161,7 +163,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
/// <paramref name="pageName"/> will process the request.
/// </summary>
/// <param name="viewContext">A <see cref="ViewContext"/> instance for the current scope.</param>
/// <param name="pageName">The name of the action method.</param>
/// <param name="pageName">The name of the page.</param>
/// <param name="pageHandler">The page handler to generate a form for.</param>
/// <param name="routeValues">
/// An <see cref="object"/> that contains the parameters for a route. The parameters are retrieved through
/// reflection by examining the properties of the <see cref="object"/>. This <see cref="object"/> is typically
@ -180,6 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
TagBuilder GeneratePageForm(
ViewContext viewContext,
string pageName,
string pageHandler,
object routeValues,
string fragment,
string method,

View File

@ -1014,7 +1014,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var pageName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues);
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
@ -1035,7 +1035,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var routeName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues);
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);

View File

@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Mvc
new ActionDescriptor());
var urlHelper = GetUrlHelper(actionContext, expectedUrl);
var result = new RedirectToPageResult("/MyPage", new { id = 10, test = "value" }, permanentRedirect)
var result = new RedirectToPageResult("/MyPage", null, new { id = 10, test = "value" }, permanentRedirect)
{
UrlHelper = urlHelper,
};
@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Mvc
.Callback((UrlRouteContext c) => context = c)
.Returns("some-value");
var values = new { test = "test-value" };
var result = new RedirectToPageResult("/MyPage", values, true, "test-fragment")
var result = new RedirectToPageResult("/MyPage", "page-handler", values, true, "test-fragment")
{
UrlHelper = urlHelper.Object,
Protocol = "ftp",
@ -121,6 +121,11 @@ namespace Microsoft.AspNetCore.Mvc
{
Assert.Equal("page", value.Key);
Assert.Equal("/MyPage", value.Value);
},
value =>
{
Assert.Equal("handler", value.Key);
Assert.Equal("page-handler", value.Value);
});
Assert.Equal("ftp", context.Protocol);
Assert.Equal("test-fragment", context.Fragment);

View File

@ -1132,7 +1132,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
.Callback((UrlRouteContext context) => actual = context);
// Act
urlHelper.Object.Page("/TestPage", new { id = 13 }, "https");
urlHelper.Object.Page("/TestPage", pageHandler: null, values: new { id = 13 }, protocol: "https");
// Assert
urlHelper.Verify();
@ -1164,7 +1164,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
.Callback((UrlRouteContext context) => actual = context);
// Act
urlHelper.Object.Page("/TestPage", new { id = 13 }, "https", "mytesthost");
urlHelper.Object.Page("/TestPage", pageHandler: null, values: new { id = 13 }, protocol: "https", host: "mytesthost");
// Assert
urlHelper.Verify();
@ -1196,7 +1196,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
.Callback((UrlRouteContext context) => actual = context);
// Act
urlHelper.Object.Page("/TestPage", new { id = 13 }, "https", "mytesthost", "#toc");
urlHelper.Object.Page("/TestPage", "test-handler", new { id = 13 }, "https", "mytesthost", "#toc");
// Assert
urlHelper.Verify();
@ -1212,6 +1212,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
{
Assert.Equal("page", value.Key);
Assert.Equal("/TestPage", value.Value);
},
value =>
{
Assert.Equal("handler", value.Key);
Assert.Equal("test-handler", value.Value);
});
Assert.Equal("https", actual.Protocol);
Assert.Equal("mytesthost", actual.Host);
@ -1241,7 +1246,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Act
string page = null;
urlHelper.Object.Page(page, new { id = 13 }, "https", "mytesthost", "#toc");
urlHelper.Object.Page(page, new { id = 13 });
// Assert
urlHelper.Verify();
@ -1258,9 +1263,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
Assert.Equal("page", value.Key);
Assert.Equal("ambient-page", value.Value);
});
Assert.Equal("https", actual.Protocol);
Assert.Equal("mytesthost", actual.Host);
Assert.Equal("#toc", actual.Fragment);
}
[Fact]
@ -1287,7 +1289,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Act
string page = null;
urlHelper.Object.Page(page, new { id = 13 }, "https", "mytesthost", "#toc");
urlHelper.Object.Page(page, new { id = 13 });
// Assert
urlHelper.Verify();
@ -1335,7 +1337,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Act
string page = null;
urlHelper.Object.Page(page, new { handler = "exact-handler" }, "https", "mytesthost", "#toc");
urlHelper.Object.Page(page, "exact-handler", new { handler = "route-value-handler" });
// Assert
urlHelper.Verify();
@ -1354,6 +1356,49 @@ namespace Microsoft.AspNetCore.Mvc.Routing
});
}
[Fact]
public void Page_UsesValueFromRouteValueIfPageHandlerIsNotExplicitySpecified()
{
// Arrange
UrlRouteContext actual = null;
var routeData = new RouteData
{
Values =
{
{ "page", "ambient-page" },
{ "handler", "ambient-handler" },
}
};
var actionContext = new ActionContext
{
RouteData = routeData,
};
var urlHelper = CreateMockUrlHelper(actionContext);
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
.Callback((UrlRouteContext context) => actual = context);
// Act
string page = null;
urlHelper.Object.Page(page, pageHandler: null, values: new { handler = "route-value-handler" });
// Assert
urlHelper.Verify();
Assert.NotNull(actual);
Assert.Null(actual.RouteName);
Assert.Collection(Assert.IsType<RouteValueDictionary>(actual.Values),
value =>
{
Assert.Equal("handler", value.Key);
Assert.Equal("route-value-handler", value.Value);
},
value =>
{
Assert.Equal("page", value.Key);
Assert.Equal("ambient-page", value.Value);
});
}
[Theory]
[InlineData("Sibling", "/Dir1/Dir2/Sibling")]
[InlineData("Dir3/Sibling", "/Dir1/Dir2/Dir3/Sibling")]

View File

@ -160,13 +160,15 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
public async Task FormTagHelper_WithPage_AllowsPostingToAnotherPage()
{
//Arrange
var expected = "<form method=\"POST\" action=\"/TagHelper/SelfPost/10\">";
var expected =
@"<form method=""POST"" action=""/TagHelper/SelfPost/10""></form>
<form method=""POST"" action=""/TagHelper/PostWithHandler/Delete/10""></form>";
// Act
var response = await Client.GetStringAsync("/TagHelper/CrossPost");
// Assert
Assert.Contains(expected, response.Trim());
Assert.Equal(expected, response.Trim());
}
[Fact]
@ -176,7 +178,10 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
var expected =
@"<button formaction=""/TagHelper/CrossPost/10"" />
<input type=""submit"" formaction=""/TagHelper/CrossPost/10"" />
<input type=""image"" formaction=""/TagHelper/CrossPost/10"" />";
<input type=""image"" formaction=""/TagHelper/CrossPost/10"" />
<button formaction=""/TagHelper/PostWithHandler/Edit/11"" />
<input type=""submit"" formaction=""/TagHelper/PostWithHandler/Edit/11"" />
<input type=""image"" formaction=""/TagHelper/PostWithHandler/Delete/11"" />";
// Act
var response = await Client.GetStringAsync("/TagHelper/FormAction");

View File

@ -965,7 +965,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
var pageName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues);
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
@ -986,7 +986,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
var routeName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues);
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);

View File

@ -1042,7 +1042,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
var pageName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues);
var resultPermanent = pageModel.RedirectToPagePreserveMethod(pageName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);
@ -1063,7 +1063,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
var routeName = "CustomRouteName";
// Act
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues);
var resultPermanent = pageModel.RedirectToPagePermanentPreserveMethod(routeName, routeValues: routeValues);
// Assert
Assert.IsType<RedirectToPageResult>(resultPermanent);

View File

@ -393,6 +393,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
It.IsAny<ViewContext>(),
string.Empty,
"/User/Home/Index",
"page-handler",
"http",
"contoso.com",
"hello=world",
@ -403,6 +404,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var anchorTagHelper = new AnchorTagHelper(generator.Object)
{
Page = "/User/Home/Index",
PageHandler = "page-handler",
Fragment = "hello=world",
Host = "contoso.com",
Protocol = "http",
@ -424,6 +426,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[InlineData("Fragment")]
[InlineData("asp-route-")]
[InlineData("Page")]
[InlineData("PageHandler")]
public async Task ProcessAsync_ThrowsIfHrefConflictsWithBoundAttributes(string propertyName)
{
// Arrange
@ -451,7 +454,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var expectedErrorMessage = "Cannot override the 'href' attribute for <a>. An <a> with a specified " +
"'href' must not have attributes starting with 'asp-route-' or an " +
"'asp-action', 'asp-controller', 'asp-area', 'asp-route', 'asp-protocol', 'asp-host', " +
"'asp-fragment', or 'asp-page' attribute.";
"'asp-fragment', 'asp-page' or 'asp-page-handler' attribute.";
var context = new TagHelperContext(
tagName: "test",
@ -491,7 +494,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
"Cannot determine the 'href' attribute for <a>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "test",
@ -529,7 +532,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
"Cannot determine the 'href' attribute for <a>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "test",
@ -567,7 +570,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
"Cannot determine the 'href' attribute for <a>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "test",

View File

@ -475,7 +475,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var expectedErrorMessage = $"Cannot override the 'formaction' attribute for <{tagName}>. <{tagName}> " +
"elements with a specified 'formaction' must not have attributes starting with 'asp-route-' or an " +
"'asp-action', 'asp-controller', 'asp-area', 'asp-fragment', or 'asp-route' attribute.";
"'asp-action', 'asp-controller', 'asp-area', 'asp-fragment', 'asp-route', 'asp-page' or 'asp-page-handler' attribute.";
var context = new TagHelperContext(
tagName: "form-action",
@ -515,7 +515,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
$"Cannot determine the 'formaction' attribute for <{tagName}>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "form-action",
@ -553,7 +553,45 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
$"Cannot determine the 'formaction' attribute for <{tagName}>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "form-action",
allAttributes: new TagHelperAttributeList(
Enumerable.Empty<TagHelperAttribute>()),
items: new Dictionary<object, object>(),
uniqueId: "test");
// Act & Assert
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => tagHelper.ProcessAsync(context, output));
Assert.Equal(expectedErrorMessage, ex.Message);
}
[Theory]
[InlineData("button")]
[InlineData("submit")]
public async Task ProcessAsync_ThrowsIfRouteAndPageHandlerProvided(string tagName)
{
// Arrange
var urlHelperFactory = new Mock<IUrlHelperFactory>().Object;
var tagHelper = new FormActionTagHelper(urlHelperFactory)
{
Route = "Default",
PageHandler = "PageHandler",
};
var output = new TagHelperOutput(
tagName,
attributes: new TagHelperAttributeList(),
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(null));
var expectedErrorMessage = string.Join(
Environment.NewLine,
$"Cannot determine the 'formaction' attribute for <{tagName}>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "form-action",
@ -591,7 +629,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
$"Cannot determine the 'formaction' attribute for <{tagName}>. The following attributes are mutually exclusive:",
"asp-route",
"asp-controller, asp-action",
"asp-page");
"asp-page, asp-page-handler");
var context = new TagHelperContext(
tagName: "form-action",

View File

@ -775,6 +775,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
.Setup(mock => mock.GeneratePageForm(
viewContext,
"/Home/Admin/Post",
"page-handler",
null,
"hello-world",
null,
@ -786,6 +787,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Antiforgery = false,
ViewContext = viewContext,
Page = "/Home/Admin/Post",
PageHandler = "page-handler",
Fragment = "hello-world",
};
@ -851,6 +853,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[InlineData("Action")]
[InlineData("Controller")]
[InlineData("Page")]
[InlineData("PageHandler")]
[InlineData("asp-route-")]
public async Task ProcessAsync_ThrowsIfActionConflictsWithBoundAttributes(string propertyName)
{
@ -874,7 +877,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var expectedErrorMessage = "Cannot override the 'action' attribute for <form>. A <form> with a specified " +
"'action' must not have attributes starting with 'asp-route-' or an " +
"'asp-action', 'asp-controller', 'asp-fragment', 'asp-area', 'asp-route' or 'asp-page' attribute.";
"'asp-action', 'asp-controller', 'asp-fragment', 'asp-area', 'asp-route', 'asp-page' or 'asp-page-handler' attribute.";
var context = new TagHelperContext(
tagName: "form",

View File

@ -1,5 +1,4 @@
@page "{id:int?}"
<form method="POST" asp-page="/TagHelper/SelfPost" asp-route-id="10">
<input type="submit" value="Submit" />
</form>
<form method="POST" asp-page="/TagHelper/SelfPost" asp-route-id="10" asp-antiforgery="false"></form>
<form method="POST" asp-page="PostWithHandler" asp-page-handler="Delete" asp-route-id="10" asp-antiforgery="false"></form>

View File

@ -1,4 +1,7 @@
@page
<button asp-page="/TagHelper/CrossPost" asp-route-id="10" />
<input type="submit" asp-page="/TagHelper/CrossPost" asp-route-id="10" />
<input type="image" asp-page="/TagHelper/CrossPost" asp-route-id="10" />
<input type="image" asp-page="/TagHelper/CrossPost" asp-route-id="10" />
<button asp-page="PostWithHandler" asp-page-handler="Edit" asp-route-id="11" />
<input type="submit" asp-page="PostWithHandler" asp-page-handler="Edit" asp-route-id="11" />
<input type="image" asp-page="PostWithHandler" asp-page-handler="Delete" asp-route-id="11" />

View File

@ -0,0 +1,16 @@
@page "{handler?}/{id?}"
@function
{
public IActionResult OnPostEdit(int id)
{
return View();
}
public IActionResult OnPostDelete(int id)
{
return View();
}
}
<form method="post" asp-page-handler="Edit" asp-route-id="10" asp-antiforgery="false"></form>