[Fixes #4013] Added support for areas in 'a' and 'form' tag helpers
This commit is contained in:
parent
65858b8d8b
commit
ac23e5aec6
|
|
@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
/// </summary>
|
||||
[HtmlTargetElement("a", Attributes = ActionAttributeName)]
|
||||
[HtmlTargetElement("a", Attributes = ControllerAttributeName)]
|
||||
[HtmlTargetElement("a", Attributes = AreaAttributeName)]
|
||||
[HtmlTargetElement("a", Attributes = FragmentAttributeName)]
|
||||
[HtmlTargetElement("a", Attributes = HostAttributeName)]
|
||||
[HtmlTargetElement("a", Attributes = ProtocolAttributeName)]
|
||||
|
|
@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
private const string ActionAttributeName = "asp-action";
|
||||
private const string ControllerAttributeName = "asp-controller";
|
||||
private const string AreaAttributeName = "asp-area";
|
||||
private const string FragmentAttributeName = "asp-fragment";
|
||||
private const string HostAttributeName = "asp-host";
|
||||
private const string ProtocolAttributeName = "asp-protocol";
|
||||
|
|
@ -67,6 +69,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
[HtmlAttributeName(ControllerAttributeName)]
|
||||
public string Controller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the area.
|
||||
/// </summary>
|
||||
/// <remarks>Must be <c>null</c> if <see cref="Route"/> is non-<c>null</c>.</remarks>
|
||||
[HtmlAttributeName(AreaAttributeName)]
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The protocol for the URL, such as "http" or "https".
|
||||
/// </summary>
|
||||
|
|
@ -147,6 +156,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
if (Action != null ||
|
||||
Controller != null ||
|
||||
Area != null ||
|
||||
Route != null ||
|
||||
Protocol != null ||
|
||||
Host != null ||
|
||||
|
|
@ -159,6 +169,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
"<a>",
|
||||
ActionAttributeName,
|
||||
ControllerAttributeName,
|
||||
AreaAttributeName,
|
||||
RouteAttributeName,
|
||||
ProtocolAttributeName,
|
||||
HostAttributeName,
|
||||
|
|
@ -180,6 +191,17 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
if (Area != null)
|
||||
{
|
||||
if (routeValues == null)
|
||||
{
|
||||
routeValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
// Unconditionally replace any value from asp-route-area.
|
||||
routeValues["area"] = Area;
|
||||
}
|
||||
|
||||
TagBuilder tagBuilder;
|
||||
if (Route == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
/// </summary>
|
||||
[HtmlTargetElement("form", Attributes = ActionAttributeName)]
|
||||
[HtmlTargetElement("form", Attributes = AntiforgeryAttributeName)]
|
||||
[HtmlTargetElement("form", Attributes = AreaAttributeName)]
|
||||
[HtmlTargetElement("form", Attributes = ControllerAttributeName)]
|
||||
[HtmlTargetElement("form", Attributes = RouteAttributeName)]
|
||||
[HtmlTargetElement("form", Attributes = RouteValuesDictionaryName)]
|
||||
|
|
@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
private const string ActionAttributeName = "asp-action";
|
||||
private const string AntiforgeryAttributeName = "asp-antiforgery";
|
||||
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";
|
||||
|
|
@ -66,6 +68,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
[HtmlAttributeName(ControllerAttributeName)]
|
||||
public string Controller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the area.
|
||||
/// </summary>
|
||||
[HtmlAttributeName(AreaAttributeName)]
|
||||
public string Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the antiforgery token should be generated.
|
||||
/// </summary>
|
||||
|
|
@ -141,7 +149,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// If "action" is already set, it means the user is attempting to use a normal <form>.
|
||||
if (output.Attributes.ContainsName(HtmlActionAttributeName))
|
||||
{
|
||||
if (Action != null || Controller != null || Route != null || RouteValues.Count != 0)
|
||||
if (Action != null || Controller != null || Area != null || Route != null || RouteValues.Count != 0)
|
||||
{
|
||||
// User also specified bound attributes we cannot use.
|
||||
throw new InvalidOperationException(
|
||||
|
|
@ -150,6 +158,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
HtmlActionAttributeName,
|
||||
ActionAttributeName,
|
||||
ControllerAttributeName,
|
||||
AreaAttributeName,
|
||||
RouteAttributeName,
|
||||
RouteValuesPrefix));
|
||||
}
|
||||
|
|
@ -171,6 +180,17 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
if (Area != null)
|
||||
{
|
||||
if (routeValues == null)
|
||||
{
|
||||
routeValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
// Unconditionally replace any value from asp-route-area.
|
||||
routeValues["area"] = Area;
|
||||
}
|
||||
|
||||
TagBuilder tagBuilder;
|
||||
if (Route == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot override the '{8}' attribute for {0}. An {0} with a specified '{8}' must not have attributes starting with '{7}' or an '{1}', '{2}', '{3}', '{4}', '{5}', or '{6}' attribute.
|
||||
/// Cannot override the '{9}' attribute for {0}. An {0} with a specified '{9}' must not have attributes starting with '{8}' or an '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', or '{7}' attribute.
|
||||
/// </summary>
|
||||
internal static string AnchorTagHelper_CannotOverrideHref
|
||||
{
|
||||
|
|
@ -35,15 +35,15 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot override the '{8}' attribute for {0}. An {0} with a specified '{8}' must not have attributes starting with '{7}' or an '{1}', '{2}', '{3}', '{4}', '{5}', or '{6}' attribute.
|
||||
/// Cannot override the '{9}' attribute for {0}. An {0} with a specified '{9}' must not have attributes starting with '{8}' or an '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', or '{7}' 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)
|
||||
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)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("AnchorTagHelper_CannotOverrideHref"), p0, p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("AnchorTagHelper_CannotOverrideHref"), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{5}' or an '{2}' or '{3}' or '{4}' attribute.
|
||||
/// Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{6}' or an '{2}' or '{3}' or '{4}' or '{5}' attribute.
|
||||
/// </summary>
|
||||
internal static string FormTagHelper_CannotOverrideAction
|
||||
{
|
||||
|
|
@ -51,11 +51,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{5}' or an '{2}' or '{3}' or '{4}' attribute.
|
||||
/// Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{6}' or an '{2}' or '{3}' or '{4}' or '{5}' attribute.
|
||||
/// </summary>
|
||||
internal static string FormatFormTagHelper_CannotOverrideAction(object p0, object p1, object p2, object p3, object p4, object p5)
|
||||
internal static string FormatFormTagHelper_CannotOverrideAction(object p0, object p1, object p2, object p3, object p4, object p5, object p6)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("FormTagHelper_CannotOverrideAction"), p0, p1, p2, p3, p4, p5);
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("FormTagHelper_CannotOverrideAction"), p0, p1, p2, p3, p4, p5, p6);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -121,10 +121,10 @@
|
|||
<value>Cannot determine an '{4}' attribute for {0}. An {0} with a specified '{1}' must not have an '{2}' or '{3}' attribute.</value>
|
||||
</data>
|
||||
<data name="AnchorTagHelper_CannotOverrideHref" xml:space="preserve">
|
||||
<value>Cannot override the '{8}' attribute for {0}. An {0} with a specified '{8}' must not have attributes starting with '{7}' or an '{1}', '{2}', '{3}', '{4}', '{5}', or '{6}' attribute.</value>
|
||||
<value>Cannot override the '{9}' attribute for {0}. An {0} with a specified '{9}' must not have attributes starting with '{8}' or an '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', or '{7}' attribute.</value>
|
||||
</data>
|
||||
<data name="FormTagHelper_CannotOverrideAction" xml:space="preserve">
|
||||
<value>Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{5}' or an '{2}' or '{3}' or '{4}' attribute.</value>
|
||||
<value>Cannot override the '{1}' attribute for {0}. A {0} with a specified '{1}' must not have attributes starting with '{6}' or an '{2}' or '{3}' or '{4}' or '{5}' 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}' if '{4}' is '{5}'.</value>
|
||||
|
|
|
|||
|
|
@ -187,6 +187,178 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
Assert.True(output.Content.IsEmpty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_AddsAreaToRouteValuesAndCallsIntoActionLinkWithExpectedParameters()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
output.Content.SetContent(string.Empty);
|
||||
|
||||
var generator = new Mock<IHtmlGenerator>();
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", "Admin" } };
|
||||
|
||||
generator
|
||||
.Setup(mock => mock.GenerateActionLink(
|
||||
It.IsAny<ViewContext>(),
|
||||
string.Empty,
|
||||
"Index",
|
||||
"Home",
|
||||
"http",
|
||||
"contoso.com",
|
||||
"hello=world",
|
||||
expectedRouteValues,
|
||||
null))
|
||||
.Returns(new TagBuilder("a"))
|
||||
.Verifiable();
|
||||
var anchorTagHelper = new AnchorTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Controller = "Home",
|
||||
Area = "Admin",
|
||||
Fragment = "hello=world",
|
||||
Host = "contoso.com",
|
||||
Protocol = "http",
|
||||
};
|
||||
|
||||
// Act
|
||||
await anchorTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("a", output.TagName);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_AspAreaOverridesAspRouteArea()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
output.Content.SetContent(string.Empty);
|
||||
|
||||
var generator = new Mock<IHtmlGenerator>();
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", "Admin" } };
|
||||
|
||||
generator
|
||||
.Setup(mock => mock.GenerateActionLink(
|
||||
It.IsAny<ViewContext>(),
|
||||
string.Empty,
|
||||
"Index",
|
||||
"Home",
|
||||
"http",
|
||||
"contoso.com",
|
||||
"hello=world",
|
||||
expectedRouteValues,
|
||||
null))
|
||||
.Returns(new TagBuilder("a"))
|
||||
.Verifiable();
|
||||
var anchorTagHelper = new AnchorTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Controller = "Home",
|
||||
Area = "Admin",
|
||||
Fragment = "hello=world",
|
||||
Host = "contoso.com",
|
||||
Protocol = "http",
|
||||
RouteValues = new Dictionary<string, string> { { "area", "Home" } }
|
||||
};
|
||||
|
||||
// Act
|
||||
await anchorTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("a", output.TagName);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_EmptyStringOnAspAreaIsPassedThroughToRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
output.Content.SetContent(string.Empty);
|
||||
|
||||
var generator = new Mock<IHtmlGenerator>();
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", string.Empty } };
|
||||
|
||||
generator
|
||||
.Setup(mock => mock.GenerateActionLink(
|
||||
It.IsAny<ViewContext>(),
|
||||
string.Empty,
|
||||
"Index",
|
||||
"Home",
|
||||
"http",
|
||||
"contoso.com",
|
||||
"hello=world",
|
||||
expectedRouteValues,
|
||||
null))
|
||||
.Returns(new TagBuilder("a"))
|
||||
.Verifiable();
|
||||
var anchorTagHelper = new AnchorTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Controller = "Home",
|
||||
Area = string.Empty,
|
||||
Fragment = "hello=world",
|
||||
Host = "contoso.com",
|
||||
Protocol = "http"
|
||||
};
|
||||
|
||||
// Act
|
||||
await anchorTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("a", output.TagName);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Action")]
|
||||
[InlineData("Controller")]
|
||||
|
|
@ -221,7 +393,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-route', 'asp-protocol', 'asp-host', or " +
|
||||
"'asp-action', 'asp-controller', 'asp-area', 'asp-route', 'asp-protocol', 'asp-host', or " +
|
||||
"'asp-fragment' attribute.";
|
||||
|
||||
var context = new TagHelperContext(
|
||||
|
|
|
|||
|
|
@ -283,6 +283,175 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_AspAreaAddsAreaToRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var viewContext = CreateViewContext();
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", "Admin" } };
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
generator
|
||||
.Setup(mock => mock.GenerateForm(
|
||||
viewContext,
|
||||
"Index",
|
||||
"Home",
|
||||
expectedRouteValues,
|
||||
null,
|
||||
null))
|
||||
.Returns(new TagBuilder("form"))
|
||||
.Verifiable();
|
||||
var formTagHelper = new FormTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Antiforgery = false,
|
||||
Controller = "Home",
|
||||
Area = "Admin",
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
||||
// Act
|
||||
await formTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("form", output.TagName);
|
||||
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.Empty(output.PreElement.GetContent());
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_EmptyStringOnAspAreaIsPassedThroughToRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var viewContext = CreateViewContext();
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", string.Empty } };
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
generator
|
||||
.Setup(mock => mock.GenerateForm(
|
||||
viewContext,
|
||||
"Index",
|
||||
"Home",
|
||||
expectedRouteValues,
|
||||
null,
|
||||
null))
|
||||
.Returns(new TagBuilder("form"))
|
||||
.Verifiable();
|
||||
var formTagHelper = new FormTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Antiforgery = false,
|
||||
Controller = "Home",
|
||||
Area = string.Empty,
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
||||
// Act
|
||||
await formTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("form", output.TagName);
|
||||
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.Empty(output.PreElement.GetContent());
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_AspAreaOverridesAspRouteArea()
|
||||
{
|
||||
// Arrange
|
||||
var viewContext = CreateViewContext();
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var expectedRouteValues = new Dictionary<string, object> { { "area", "Admin" } };
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
generator
|
||||
.Setup(mock => mock.GenerateForm(
|
||||
viewContext,
|
||||
"Index",
|
||||
"Home",
|
||||
expectedRouteValues,
|
||||
null,
|
||||
null))
|
||||
.Returns(new TagBuilder("form"))
|
||||
.Verifiable();
|
||||
var formTagHelper = new FormTagHelper(generator.Object)
|
||||
{
|
||||
Action = "Index",
|
||||
Antiforgery = false,
|
||||
Controller = "Home",
|
||||
Area = "Admin",
|
||||
RouteValues = new Dictionary<string, string> { { "area", "Client" } },
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
||||
// Act
|
||||
await formTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
generator.Verify();
|
||||
|
||||
Assert.Equal("form", output.TagName);
|
||||
Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode);
|
||||
Assert.Empty(output.Attributes);
|
||||
Assert.Empty(output.PreElement.GetContent());
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_CallsIntoGenerateRouteFormWithExpectedParameters()
|
||||
{
|
||||
|
|
@ -415,7 +584,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' or 'asp-controller' or 'asp-route' attribute.";
|
||||
"'asp-action' or 'asp-controller' or 'asp-area' or 'asp-route' attribute.";
|
||||
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
|
|
|
|||
Loading…
Reference in New Issue