diff --git a/src/Microsoft.AspNet.Mvc.TagHelpers/SelectTagHelper.cs b/src/Microsoft.AspNet.Mvc.TagHelpers/SelectTagHelper.cs
index 6a6acc50b2..d3ecbd7034 100644
--- a/src/Microsoft.AspNet.Mvc.TagHelpers/SelectTagHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.TagHelpers/SelectTagHelper.cs
@@ -18,6 +18,16 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
[ContentBehavior(ContentBehavior.Append)]
public class SelectTagHelper : TagHelper
{
+ ///
+ /// Key used for selected values in .
+ ///
+ ///
+ /// Value for this dictionary entry will either be null (indicating no has
+ /// executed within this <form/>) or an instance. Elements of the
+ /// collection are based on current .
+ ///
+ public static readonly string SelectedValuesFormDataKey = nameof(SelectTagHelper) + "-SelectedValues";
+
// Protected to ensure subclasses are correctly activated. Internal for ease of use when testing.
[Activate]
protected internal IHtmlGenerator Generator { get; set; }
@@ -114,6 +124,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Ensure GenerateSelect() _never_ looks anything up in ViewData.
var items = Items ?? Enumerable.Empty();
+ ICollection selectedValues;
var tagBuilder = Generator.GenerateSelect(
ViewContext,
For.Metadata,
@@ -121,13 +132,18 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
name: For.Name,
selectList: items,
allowMultiple: allowMultiple,
- htmlAttributes: null);
+ htmlAttributes: null,
+ selectedValues: out selectedValues);
if (tagBuilder != null)
{
output.SelfClosing = false;
output.Merge(tagBuilder);
}
+
+ // Whether or not (not being highly unlikely) we generate anything, could update contained
+ // elements. Provide selected values for tag helpers. They'll run next.
+ ViewContext.FormContext.FormData[SelectedValuesFormDataKey] = selectedValues;
}
}
}
diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/SelectTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/SelectTagHelperTest.cs
index 7543badd65..da26800d39 100644
--- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/SelectTagHelperTest.cs
+++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/SelectTagHelperTest.cs
@@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Skip last two test cases because DefaultHtmlGenerator evaluates expression name against
// ViewData, not using ModelMetadata.Model. ViewData.Eval() handles simple property paths and some
- // dictionary lookups, but not indexing into an array or list. Will file a follow-up bug on this...
+ // dictionary lookups, but not indexing into an array or list. See #1468...
////{ models, typeof(Model), () => models[1].Text,
//// new NameAndId("[1].Text", "z1__Text"), outerSelected },
////{ models, typeof(NestedModel), () => models[1].NestedModel.Text,
@@ -213,6 +213,14 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal(expectedContent, output.Content);
Assert.False(output.SelfClosing);
Assert.Equal(expectedTagName, output.TagName);
+
+ Assert.NotNull(viewContext.FormContext?.FormData);
+ var keyValuePair = Assert.Single(
+ viewContext.FormContext.FormData,
+ entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey);
+ Assert.NotNull(keyValuePair.Value);
+ var selectedValues = Assert.IsAssignableFrom>(keyValuePair.Value);
+ Assert.InRange(selectedValues.Count, 0, 1);
}
[Theory]
@@ -278,6 +286,14 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal(expectedContent, output.Content);
Assert.False(output.SelfClosing);
Assert.Equal(expectedTagName, output.TagName);
+
+ Assert.NotNull(viewContext.FormContext?.FormData);
+ var keyValuePair = Assert.Single(
+ viewContext.FormContext.FormData,
+ entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey);
+ Assert.NotNull(keyValuePair.Value);
+ var selectedValues = Assert.IsAssignableFrom>(keyValuePair.Value);
+ Assert.InRange(selectedValues.Count, 0, 1);
}
[Theory]
@@ -312,6 +328,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var htmlGenerator = new Mock(MockBehavior.Strict);
var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider);
+ ICollection selectedValues = new string[0];
htmlGenerator
.Setup(real => real.GenerateSelect(
viewContext,
@@ -320,7 +337,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
propertyName, // name
expectedItems,
expectedAllowMultiple,
- null)) // htmlAttributes
+ null, // htmlAttributes
+ out selectedValues))
.Returns((TagBuilder)null)
.Verifiable();
@@ -338,6 +356,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
+
+ Assert.NotNull(viewContext.FormContext?.FormData);
+ var keyValuePair = Assert.Single(
+ viewContext.FormContext.FormData,
+ entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey);
+ Assert.Same(selectedValues, keyValuePair.Value);
}
[Theory]
@@ -363,6 +387,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
var htmlGenerator = new Mock(MockBehavior.Strict);
var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider);
+ ICollection selectedValues = new string[0];
htmlGenerator
.Setup(real => real.GenerateSelect(
viewContext,
@@ -371,7 +396,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
propertyName, // name
It.IsAny>(),
allowMultiple,
- null)) // htmlAttributes
+ null, // htmlAttributes
+ out selectedValues))
.Returns((TagBuilder)null)
.Verifiable();
@@ -387,6 +413,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
// Assert
htmlGenerator.Verify();
+
+ Assert.NotNull(viewContext.FormContext?.FormData);
+ var keyValuePair = Assert.Single(
+ viewContext.FormContext.FormData,
+ entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey);
+ Assert.Same(selectedValues, keyValuePair.Value);
}
[Theory]