diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/AnchorTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/AnchorTagHelper.cs
index d4d7787952..8ef8ae97c6 100644
--- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/AnchorTagHelper.cs
+++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/AnchorTagHelper.cs
@@ -162,7 +162,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Protocol != null ||
Host != null ||
Fragment != null ||
- RouteValues.Count != 0)
+ (_routeValues != null && _routeValues.Count > 0))
{
// User specified an href and one of the bound attributes; can't determine the href attribute.
throw new InvalidOperationException(
@@ -194,7 +194,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
routeValues = new RouteValueDictionary();
}
- // Unconditionally replace any value from asp-route-area.
+ // Unconditionally replace any value from asp-route-area.
routeValues["area"] = Area;
}
diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ButtonTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/FormActionTagHelper.cs
similarity index 63%
rename from src/Microsoft.AspNetCore.Mvc.TagHelpers/ButtonTagHelper.cs
rename to src/Microsoft.AspNetCore.Mvc.TagHelpers/FormActionTagHelper.cs
index 7fc14aead7..4c4ba9c8d0 100644
--- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ButtonTagHelper.cs
+++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/FormActionTagHelper.cs
@@ -12,7 +12,8 @@ using Microsoft.AspNetCore.Routing;
namespace Microsoft.AspNetCore.Mvc.TagHelpers
{
///
- /// implementation targeting <button> elements.
+ /// implementation targeting <button> elements and <input> elements with
+ /// their type attribute set to image or submit.
///
[HtmlTargetElement("button", Attributes = ActionAttributeName)]
[HtmlTargetElement("button", Attributes = ControllerAttributeName)]
@@ -20,22 +21,51 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("button", Attributes = RouteAttributeName)]
[HtmlTargetElement("button", Attributes = RouteValuesDictionaryName)]
[HtmlTargetElement("button", Attributes = RouteValuesPrefix + "*")]
- public class ButtonTagHelper : TagHelper
+ [HtmlTargetElement("input", Attributes = ImageActionAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = ImageControllerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = ImageAreaAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = ImageRouteAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = ImageRouteValuesDictionarySelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = ImageRouteValuesSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitActionAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitControllerAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitAreaAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitRouteAttributeSelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitRouteValuesDictionarySelector, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement("input", Attributes = SubmitRouteValuesSelector, TagStructure = TagStructure.WithoutEndTag)]
+ public class FormActionTagHelper : TagHelper
{
private const string ActionAttributeName = "asp-action";
- private const string ControllerAttributeName = "asp-controller";
private const string AreaAttributeName = "asp-area";
+ private const string ControllerAttributeName = "asp-controller";
private const string RouteAttributeName = "asp-route";
private const string RouteValuesDictionaryName = "asp-all-route-data";
private const string RouteValuesPrefix = "asp-route-";
private const string FormAction = "formaction";
+
+ private const string ImageTypeSelector = "[type=image], ";
+ private const string ImageActionAttributeSelector = ImageTypeSelector + ActionAttributeName;
+ private const string ImageAreaAttributeSelector = ImageTypeSelector + AreaAttributeName;
+ private const string ImageControllerAttributeSelector = ImageTypeSelector + ControllerAttributeName;
+ private const string ImageRouteAttributeSelector = ImageTypeSelector + RouteAttributeName;
+ private const string ImageRouteValuesDictionarySelector = ImageTypeSelector + RouteValuesDictionaryName;
+ private const string ImageRouteValuesSelector = ImageTypeSelector + RouteValuesPrefix + "*";
+
+ private const string SubmitTypeSelector = "[type=submit], ";
+ private const string SubmitActionAttributeSelector = SubmitTypeSelector + ActionAttributeName;
+ private const string SubmitAreaAttributeSelector = SubmitTypeSelector + AreaAttributeName;
+ private const string SubmitControllerAttributeSelector = SubmitTypeSelector + ControllerAttributeName;
+ private const string SubmitRouteAttributeSelector = SubmitTypeSelector + RouteAttributeName;
+ private const string SubmitRouteValuesDictionarySelector = SubmitTypeSelector + RouteValuesDictionaryName;
+ private const string SubmitRouteValuesSelector = SubmitTypeSelector + RouteValuesPrefix + "*";
+
private IDictionary _routeValues;
///
- /// Creates a new .
+ /// Creates a new .
///
/// The .
- public ButtonTagHelper(IUrlHelperFactory urlHelperFactory)
+ public FormActionTagHelper(IUrlHelperFactory urlHelperFactory)
{
UrlHelperFactory = urlHelperFactory;
}
@@ -120,15 +150,20 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
throw new ArgumentNullException(nameof(output));
}
- // If "formaction" is already set, it means the user is attempting to use a normal button.
+ // If "formaction" is already set, it means the user is attempting to use a normal button or input element.
if (output.Attributes.ContainsName(FormAction))
{
- if (Action != null || Controller != null || Area != null || Route != null || RouteValues.Count != 0)
+ if (Action != null ||
+ Controller != null ||
+ Area != null ||
+ Route != null ||
+ (_routeValues != null && _routeValues.Count > 0))
{
- // User specified a formaction and one of the bound attributes; can't determine the formaction attribute.
+ // User specified a formaction and one of the bound attributes; can't override that formaction
+ // attribute.
throw new InvalidOperationException(
- Resources.FormatButtonTagHelper_CannotOverrideFormAction(
- "