diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs
index 794710399c..73ed23a559 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs
@@ -6,11 +6,9 @@ using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
-using System.IO;
using System.Linq;
using System.Net;
using System.Text;
-using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions;
@@ -157,21 +155,17 @@ namespace Microsoft.AspNet.Mvc.Rendering
string method,
object htmlAttributes)
{
- var tagBuilder = new TagBuilder("form");
- tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
-
var defaultMethod = false;
if (string.IsNullOrEmpty(method))
{
defaultMethod = true;
- method = FormMethod.Post.ToString();
}
else if (string.Equals(method, FormMethod.Post.ToString(), StringComparison.OrdinalIgnoreCase))
{
defaultMethod = true;
}
- string formAction;
+ string action;
if (actionName == null && controllerName == null && routeValues == null && defaultMethod &&
htmlAttributes == null)
{
@@ -179,20 +173,28 @@ namespace Microsoft.AspNet.Mvc.Rendering
// parameters. Also reachable in the even-more-unusual case that user called another BeginForm()
// overload with default argument values.
var request = viewContext.HttpContext.Request;
- formAction = request.PathBase + request.Path + request.QueryString;
+ action = request.PathBase + request.Path + request.QueryString;
}
else
{
- formAction = _urlHelper.Action(action: actionName, controller: controllerName, values: routeValues);
+ action = _urlHelper.Action(action: actionName, controller: controllerName, values: routeValues);
}
- // action is implicitly generated, so htmlAttributes take precedence.
- tagBuilder.MergeAttribute("action", formAction);
+ return GenerateFormCore(viewContext, action, method, htmlAttributes);
+ }
- // method is an explicit parameter, so it takes precedence over the htmlAttributes.
- tagBuilder.MergeAttribute("method", method, replaceExisting: true);
+ ///
+ public TagBuilder GenerateRouteForm(
+ [NotNull]ViewContext viewContext,
+ string routeName,
+ object routeValues,
+ string method,
+ object htmlAttributes)
+ {
+ var action =
+ _urlHelper.RouteUrl(routeName, values: routeValues, protocol: null, host: null, fragment: null);
- return tagBuilder;
+ return GenerateFormCore(viewContext, action, method, htmlAttributes);
}
///
@@ -780,6 +782,44 @@ namespace Microsoft.AspNet.Mvc.Rendering
return null;
}
+ ///
+ /// Generate a <form> element.
+ ///
+ /// A instance for the current scope.
+ /// The URL where the form-data should be submitted.
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
+ ///
+ /// A instance for the </form> element.
+ ///
+ protected virtual TagBuilder GenerateFormCore(
+ [NotNull] ViewContext viewContext,
+ string action,
+ string method,
+ object htmlAttributes)
+ {
+ var tagBuilder = new TagBuilder("form");
+ tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes));
+
+ // action is implicitly generated from other parameters, so htmlAttributes take precedence.
+ tagBuilder.MergeAttribute("action", action);
+
+ if (string.IsNullOrEmpty(method))
+ {
+ // Occurs only when called from a tag helper.
+ method = FormMethod.Post.ToString();
+ }
+
+ // For tag helpers, htmlAttributes will be null; replaceExisting value does not matter.
+ // method is an explicit parameter to HTML helpers, so it takes precedence over the htmlAttributes.
+ tagBuilder.MergeAttribute("method", method, replaceExisting: true);
+
+ return tagBuilder;
+ }
+
protected virtual TagBuilder GenerateInput(
[NotNull] ViewContext viewContext,
InputType inputType,
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
index 8d17a3172d..e133912408 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
@@ -218,6 +217,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
return GenerateForm(actionName, controllerName, routeValues, method, htmlAttributes);
}
+ ///
+ public MvcForm BeginRouteForm(string routeName, object routeValues, FormMethod method, object htmlAttributes)
+ {
+ return GenerateRouteForm(routeName, routeValues, method, htmlAttributes);
+ }
+
///
public void EndForm()
{
@@ -611,8 +616,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The name of the action method.
/// The name of the controller.
@@ -623,10 +628,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// instance containing the route parameters.
///
/// The HTTP method for processing the form, either GET or POST.
- /// An instance containing HTML
- /// attributes to set for the element.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
///
- /// An instance which emits the </form> end tag when disposed.
+ /// An instance which renders the </form> end tag when disposed.
///
///
/// In this context, "renders" means the method writes its output using .
@@ -653,6 +660,49 @@ namespace Microsoft.AspNet.Mvc.Rendering
return CreateForm();
}
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The name of the route.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route parameters.
+ ///
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ protected virtual MvcForm GenerateRouteForm(
+ string routeName,
+ object routeValues,
+ FormMethod method,
+ object htmlAttributes)
+ {
+ var tagBuilder = _htmlGenerator.GenerateRouteForm(
+ ViewContext,
+ routeName,
+ routeValues,
+ GetFormMethodString(method),
+ htmlAttributes);
+ if (tagBuilder != null)
+ {
+ ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
+ }
+
+ return CreateForm();
+ }
+
+
protected virtual HtmlString GenerateHidden(
ModelMetadata metadata,
string name,
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs
index 09595bf8f4..65a4c1ed7a 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs
@@ -49,9 +49,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
string name);
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Generate a <form> element. When the user submits the form, the method
+ /// will process the request.
///
+ /// A instance for the current scope.
/// The name of the action method.
/// The name of the controller.
///
@@ -61,14 +62,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// instance containing the route parameters.
///
/// The HTTP method for processing the form, either GET or POST.
- /// An instance containing HTML
- /// attributes to set for the element.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
///
- /// An instance which emits the </form> end tag when disposed.
+ /// A instance for the </form> element.
///
- ///
- /// In this context, "renders" means the method writes its output using .
- ///
TagBuilder GenerateForm(
[NotNull] ViewContext viewContext,
string actionName,
@@ -77,6 +77,33 @@ namespace Microsoft.AspNet.Mvc.Rendering
string method,
object htmlAttributes);
+ ///
+ /// Generate a <form> element. When the user submits the form, the route
+ /// will forward the request to an action method.
+ ///
+ /// A instance for the current scope.
+ /// The name of the route.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route parameters.
+ ///
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
+ ///
+ /// A instance for the </form> element.
+ ///
+ TagBuilder GenerateRouteForm(
+ [NotNull] ViewContext viewContext,
+ string routeName,
+ object routeValues,
+ string method,
+ object htmlAttributes);
+
TagBuilder GenerateHidden(
[NotNull] ViewContext viewContext,
ModelMetadata metadata,
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperFormExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperFormExtensions.cs
index fbfda8af2a..76508bbd7f 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperFormExtensions.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperFormExtensions.cs
@@ -28,8 +28,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// current action method will process the request.
///
/// The instance this method extends.
/// The HTTP method for processing the form, either GET or POST.
@@ -46,8 +46,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// current action method will process the request.
///
/// The instance this method extends.
/// The HTTP method for processing the form, either GET or POST.
@@ -72,8 +72,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// current action method will process the request.
///
/// The instance this method extends.
///
@@ -96,8 +96,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The instance this method extends.
/// The name of the action method.
@@ -118,8 +118,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The instance this method extends.
/// The name of the action method.
@@ -148,8 +148,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The instance this method extends.
/// The name of the action method.
@@ -172,8 +172,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The instance this method extends.
/// The name of the action method.
@@ -204,8 +204,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The instance this method extends.
/// The name of the action method.
@@ -232,5 +232,161 @@ namespace Microsoft.AspNet.Mvc.Rendering
return htmlHelper.BeginForm(actionName, controllerName, routeValues: null,
method: method, htmlAttributes: htmlAttributes);
}
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// default route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route
+ /// parameters.
+ ///
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm([NotNull] this IHtmlHelper htmlHelper, object routeValues)
+ {
+ return htmlHelper.BeginRouteForm(
+ routeName: null,
+ routeValues: routeValues,
+ method: FormMethod.Post,
+ htmlAttributes: null);
+ }
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ /// The name of the route.
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm([NotNull] this IHtmlHelper htmlHelper, string routeName)
+ {
+ return htmlHelper.BeginRouteForm(
+ routeName,
+ routeValues: null,
+ method: FormMethod.Post,
+ htmlAttributes: null);
+ }
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ /// The name of the route.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route
+ /// parameters.
+ ///
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm(
+ [NotNull] this IHtmlHelper htmlHelper,
+ string routeName,
+ object routeValues)
+ {
+ return htmlHelper.BeginRouteForm(routeName, routeValues, FormMethod.Post, htmlAttributes: null);
+ }
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ /// The name of the route.
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm(
+ [NotNull] this IHtmlHelper htmlHelper,
+ string routeName,
+ FormMethod method)
+ {
+ return htmlHelper.BeginRouteForm(routeName, routeValues: null, method: method, htmlAttributes: null);
+ }
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ /// The name of the route.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route
+ /// parameters.
+ ///
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm(
+ [NotNull] this IHtmlHelper htmlHelper,
+ string routeName,
+ object routeValues,
+ FormMethod method)
+ {
+ return htmlHelper.BeginRouteForm(routeName, routeValues, method, htmlAttributes: null);
+ }
+
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The instance this method extends.
+ /// The name of the route.
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML
+ /// attributes.
+ ///
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ public static MvcForm BeginRouteForm(
+ [NotNull] this IHtmlHelper htmlHelper,
+ string routeName,
+ FormMethod method,
+ object htmlAttributes)
+ {
+ return htmlHelper.BeginRouteForm(
+ routeName,
+ routeValues: null,
+ method: method,
+ htmlAttributes: htmlAttributes);
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
index b9e302236f..73ce13e961 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
@@ -82,8 +82,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
HtmlString AntiForgeryToken();
///
- /// Renders a <form> start tag to the response. When the user submits the form,
- /// the request will be processed by an action method.
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// method will process the request.
///
/// The name of the action method.
/// The name of the controller.
@@ -111,6 +111,34 @@ namespace Microsoft.AspNet.Mvc.Rendering
FormMethod method,
object htmlAttributes);
+ ///
+ /// Renders a <form> start tag to the response. When the user submits the form, the
+ /// route will forward the request to an action method.
+ ///
+ /// The name of the route.
+ ///
+ /// An that contains the parameters for a route. The parameters are retrieved through
+ /// reflection by examining the properties of the . This is typically
+ /// created using initializer syntax. Alternatively, an
+ /// instance containing the route parameters.
+ ///
+ /// The HTTP method for processing the form, either GET or POST.
+ ///
+ /// An that contains the HTML attributes for the element. Alternatively, an
+ /// instance containing the HTML attributes.
+ ///
+ ///
+ /// An instance which renders the </form> end tag when disposed.
+ ///
+ ///
+ /// In this context, "renders" means the method writes its output using .
+ ///
+ MvcForm BeginRouteForm(
+ string routeName,
+ object routeValues,
+ FormMethod method,
+ object htmlAttributes);
+
///
/// Returns an <input> element of type "checkbox" with value "true" and an <input> element of type
/// "hidden" with value "false".
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs
index f2d1982bfa..c0f94ae584 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs
@@ -758,6 +758,15 @@ Environment.NewLine;
throw new NotImplementedException();
}
+ public MvcForm BeginRouteForm(
+ string routeName,
+ object routeValues,
+ FormMethod method,
+ object htmlAttributes)
+ {
+ throw new NotImplementedException();
+ }
+
public HtmlString CheckBox(string name, bool? isChecked, object htmlAttributes)
{
return new HtmlString("__CheckBox__");