diff --git a/src/System.Web.Mvc/Html/SelectExtensions.cs b/src/System.Web.Mvc/Html/SelectExtensions.cs
index af4a6cbff..bc76a4bdd 100644
--- a/src/System.Web.Mvc/Html/SelectExtensions.cs
+++ b/src/System.Web.Mvc/Html/SelectExtensions.cs
@@ -285,7 +285,7 @@ private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, ModelMetadata
private static IEnumerable GetSelectData(this HtmlHelper htmlHelper, string name)
{
object o = null;
- if (htmlHelper.ViewData != null)
+ if (htmlHelper.ViewData != null && !String.IsNullOrEmpty(name))
{
o = htmlHelper.ViewData.Eval(name);
}
@@ -396,9 +396,9 @@ private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMet
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
- if (defaultValue == null && !String.IsNullOrEmpty(name))
+ if (defaultValue == null)
{
- if (!usedViewData)
+ if (!usedViewData && !String.IsNullOrEmpty(name))
{
defaultValue = htmlHelper.ViewData.Eval(name);
}
diff --git a/test/System.Web.Mvc.Test/Html/Test/SelectExtensionsTest.cs b/test/System.Web.Mvc.Test/Html/Test/SelectExtensionsTest.cs
index f43a3862f..71da0b1a1 100644
--- a/test/System.Web.Mvc.Test/Html/Test/SelectExtensionsTest.cs
+++ b/test/System.Web.Mvc.Test/Html/Test/SelectExtensionsTest.cs
@@ -19,6 +19,7 @@ public class SelectExtensionsTest : IDisposable
{
private static readonly ViewDataDictionary _listBoxViewData = new ViewDataDictionary { { "foo", new[] { "Bravo" } } };
private static readonly ViewDataDictionary _dropDownListViewData = new ViewDataDictionary { { "foo", "Bravo" } };
+ private static readonly ViewDataDictionary _nestedDropDownListViewData = new ViewDataDictionary { { "foo", "Bravo" } };
private static readonly ViewDataDictionary _nonIEnumerableViewData = new ViewDataDictionary { { "foo", 1 } };
private static readonly ViewDataDictionary _enumDropDownListViewData = new ViewDataDictionary
{
@@ -1191,6 +1192,48 @@ public void DropDownListForUsesLambdaDefaultValue()
+ "",
html.ToHtmlString());
}
+
+ [Fact]
+ public void DropDownListForUsesLambdaDefaultValueWhenNested()
+ {
+ // Arrange
+ FooModel model = new FooModel { foo = "Bravo" };
+ ViewDataDictionary viewData = new ViewDataDictionary(model);
+ ViewDataDictionary nestedViewData = MvcHelper.GetNestedViewData(viewData, m => m.foo);
+ HtmlHelper helper = MvcHelper.GetHtmlHelper(nestedViewData);
+ SelectList selectList = new SelectList(MultiSelectListTest.GetSampleStrings());
+
+ // Act
+ MvcHtmlString html = helper.DropDownListFor(m => m, selectList);
+
+ // Assert
+ Assert.Equal(
+ "",
+ html.ToHtmlString());
+ }
+
+ [Fact]
+ public void DropDownListForUsesLambdaDefaultValueFromViewDataWhenNested()
+ {
+ // Arrange
+ ViewDataDictionary nestedViewData = MvcHelper.GetNestedViewData(_nestedDropDownListViewData, m => m.inner);
+ HtmlHelper helper = MvcHelper.GetHtmlHelper(nestedViewData);
+ SelectList selectList = new SelectList(MultiSelectListTest.GetSampleStrings());
+
+ // Act
+ MvcHtmlString html = helper.DropDownListFor(m => m.foo, selectList);
+
+ // Assert
+ Assert.Equal(
+ "",
+ html.ToHtmlString());
+ }
[Fact]
public void DropDownListForUsesLambdaDefaultValueWithNullSelectListUsesViewData()
@@ -1215,6 +1258,33 @@ public void DropDownListForUsesLambdaDefaultValueWithNullSelectListUsesViewData(
html.ToHtmlString());
}
+ [Fact]
+ public void DropDownListForUsesLambdaDefaultValueWithNullSelectListUsesViewDataWhenNested()
+ {
+ // Arrange
+ FooContainerModel model = new FooContainerModel { inner = new FooModel { foo = "Bravo" } };
+ ViewDataDictionary vdd = new ViewDataDictionary(model)
+ {
+ { "foo", new SelectList(MultiSelectListTest.GetSampleStrings()) }
+ };
+
+ ViewDataDictionary nestedViewData = MvcHelper.GetNestedViewData(vdd, m => m.inner);
+
+
+ HtmlHelper helper = MvcHelper.GetHtmlHelper(nestedViewData);
+
+ // Act
+ MvcHtmlString html = helper.DropDownListFor(m => m.foo, selectList: null);
+
+ // Assert
+ Assert.Equal(
+ "",
+ html.ToHtmlString());
+ }
+
[Fact]
public void DropDownListForWithAttributesDictionary()
{
@@ -3330,6 +3400,10 @@ private static IEnumerable GetSelectListWithNumericValuesForEnum
return selectList;
}
+ private class FooContainerModel
+ {
+ public FooModel inner { get; set; }
+ }
private class FooModel
{
public string foo { get; set; }
diff --git a/test/System.Web.Mvc.Test/Util/MvcHelper.cs b/test/System.Web.Mvc.Test/Util/MvcHelper.cs
index 992bb481f..8cc869d5c 100644
--- a/test/System.Web.Mvc.Test/Util/MvcHelper.cs
+++ b/test/System.Web.Mvc.Test/Util/MvcHelper.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.IO;
+using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
@@ -152,6 +153,25 @@ public static HttpContextBase GetHttpContext(string appPath, string requestPath,
return GetHttpContext(appPath, requestPath, httpMethod, Uri.UriSchemeHttp.ToString(), -1);
}
+ public static ViewDataDictionary GetNestedViewData(ViewDataDictionary viewData, Expression> expression)
+ {
+ var metadata = ModelMetadata.FromLambdaExpression(expression, viewData);
+ var htmlFieldName = ExpressionHelper.GetExpressionText(expression);
+
+
+ ViewDataDictionary nestedViewData = new ViewDataDictionary(viewData)
+ {
+ Model = metadata.Model,
+ ModelMetadata = metadata,
+ TemplateInfo = new TemplateInfo
+ {
+ HtmlFieldPrefix = viewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName),
+ }
+ };
+
+ return new ViewDataDictionary(nestedViewData);
+ }
+
public static ViewContext GetViewContextWithPath(string appPath, ViewDataDictionary viewData)
{
HttpContextBase httpContext = GetHttpContext(appPath, "/request", "GET");