-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Most string-based HTML helpers use unprefixed ViewDataDictionary
entries if called from templates
#1487
Comments
This problem was inherited from MVC 5.2. Fix would probably require a general change in how we evaluate expressions that may be in The current code mixes Fix isn't particularly risky because we have good but still-improving (see @pranavkm's work on #453) unit tests touching on |
- #1468 - Always use `ModelExplorer` in `<select/>`, `DropDownListFor()` and `ListBoxFor()` cases - allows evaluation of more-complex expressions - Use `ViewData.Model` in `DropDownList()` and `ListBox()` template cases - `ViewData` was previously ignored in these cases nit: change `ViewDataDictionary.Eval()` to return `Model` if `expression` is `null` or empty - now `throw` on `null` or empty `expression` name in `ViewDataEvaluator.Eval()` - simplifies some of the higher-level code - no change to `selectList` fallback; `Model` incorrect for that case - no change to `GenerateRadioButton()`; would change behaviour unrelated to #1468 - this helper uses incorrect `ViewData` lookup text, see #1487
- #1468 - Always use `ModelExplorer` in `<select/>`, `DropDownListFor()` and `ListBoxFor()` cases - allows evaluation of more-complex expressions - Use `ViewData.Model` in `DropDownList()` and `ListBox()` template cases - `ViewData` was previously ignored in these cases nit: change `ViewDataDictionary.Eval()` to return `Model` if `expression` is `null` or empty - now `throw` on `null` or empty `expression` name in `ViewDataEvaluator.Eval()` - simplifies some of the higher-level code - no change to `selectList` fallback; `Model` incorrect for that case - no change to `GenerateRadioButton()`; would change behaviour unrelated to #1468 - this helper uses incorrect `ViewData` lookup text, see #1487
Problem also affects how client validation attributes are found. For example with the following in an @{
// Don't do this; causes template to ignore `ViewData.Model` and overwrite existing `ViewData`.
ViewData[string.Empty] = "two";
ViewData[Html.ViewData.TemplateInfo.HtmlFieldPrefix] = 23;
}
@Html.TextBox(expression: string.Empty); The generated HTML will be <input id="z0__Number" name="[0].Number" type="text" value="23" /> The HTML helper finds the correct value but the incorrect |
- test additional cases _close_ to these bugs as well for #1485 - show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests - show odd `@Html.TextBox()` behaviour in functional tests (templates) for #1487 - show odd `@Html.Value()` behaviour in unit tests - show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests - show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper for #2662 - show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests for #2664 - show failures with `@Html.ListBox()` in unit tests nits: - test `IHtmlHelper` methods, not extensions - use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController` - name test methods a bit more consistently - rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
- builds on dougbu/testing.1485.1487.2662.2664 branch, unblocking some #1487 tests - use new property to correctly determine `isTargetEnum` in `GetCurrentValues()` - avoid `ArgumentNullException` in all cases where raw values are `enum` but target is not - also use new property instead of private `GetElementType()` methods where possible nits: - move properties above methods in `ModelMetadata` - avoid accidentally-incorrect "Remove Unnecessary Usings"
- test additional cases _close_ to these bugs as well for #1485 - show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests - show odd `@Html.TextBox()` behaviour in functional tests (templates) for #1487 - show odd `@Html.Value()` behaviour in unit tests - show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests - show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper for #2662 - show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests for #2664 - show failures with `@Html.ListBox()` in unit tests nits: - test `IHtmlHelper` methods, not extensions - use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController` - name test methods a bit more consistently - rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
- test additional cases _close_ to these bugs as well for #1485 - show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests - show odd `@Html.TextBox()` behaviour in functional tests (templates) for #1487 - show odd `@Html.Value()` behaviour in unit tests - show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests - show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper for #2662 - show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests for #2664 - show failures with `@Html.ListBox()` in unit tests nits: - test `IHtmlHelper` methods, not extensions - use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController` - name test methods a bit more consistently - rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
- builds on dougbu/testing.1485.1487.2662.2664 branch, unblocking some #1487 tests - use new property to correctly determine `isTargetEnum` in `GetCurrentValues()` - avoid `ArgumentNullException` in all cases where raw values are `enum` but target is not - also use new property instead of private `GetElementType()` methods where possible nits: - move properties above methods in `ModelMetadata` - avoid accidentally-incorrect "Remove Unnecessary Usings"
- test additional cases _close_ to these bugs as well for #1485 - show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests - show odd `@Html.TextBox()` behaviour in functional tests (templates) for #1487 - show odd `@Html.Value()` behaviour in unit tests - show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests - show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper for #2662 - show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests for #2664 - show failures with `@Html.ListBox()` in unit tests nits: - test `IHtmlHelper` methods, not extensions - use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController` - name test methods a bit more consistently - rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
- builds on dougbu/testing.1485.1487.2662.2664 branch, unblocking some #1487 tests - use new property to correctly determine `isTargetEnum` in `GetCurrentValues()` - avoid `ArgumentNullException` in all cases where raw values are `enum` but target is not - also use new property instead of private `GetElementType()` methods where possible nits: - move properties above methods in `ModelMetadata` - avoid accidentally-incorrect "Remove Unnecessary Usings"
- test additional cases _close_ to these bugs as well for #1485 - show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests - show odd `@Html.TextBox()` behaviour in functional tests (templates) for #1487 - show odd `@Html.Value()` behaviour in unit tests - show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests - show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper for #2662 - show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests for #2664 - show failures with `@Html.ListBox()` in unit tests nits: - test `IHtmlHelper` methods, not extensions - use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController` - name test methods a bit more consistently - rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
- #2664 - use new property to correctly determine `isTargetEnum` in `GetCurrentValues()` - avoid `ArgumentNullException` in all cases where raw values are `enum` but target is not - stop skipping tests blocked by #2664, exposing a couple more #1487 issues - use new property instead of private `GetElementType()` methods where possible - cleans up some duplicate code - also remove redundant use of `IsCollectionType` and `ElementMetadata` nits: - move properties above methods in `ModelMetadata` - avoid accidentally-incorrect "Remove Unnecessary Usings"
- #1485, #1487 - handle `TemplateInfo.HtmlFieldPrefix` in `ViewDataEvaluator.Eval()` - attempt lookup in the `ViewDataDictionary` using full name then evaluate relative `expression` against `viewData.Model` - handle `null` or empty `expression` special case in this method (remove `throw`s) - always pass relative `expression` name into `Eval()` - remove `null` or empty `expression` handling from higher-level code - in a couple of cases, special-case returned `ViewDataInfo` - #2662 - remove incorrect guard from `DefaultHtmlGenerator.GenerateRadioButtion()` - add doc comments for the core methods that have changed - enable unit tests skipped due to one of above bugs - fix one (yeah, just one) other test with incorrect expectations - remove functional test comments about the above bugs and update expectations nits: - move some comments describing `ViewDataEvaluator` methods above the methods
- #1485, #1487 - handle `TemplateInfo.HtmlFieldPrefix` in `ViewDataEvaluator.Eval()` - attempt lookup in the `ViewDataDictionary` using full name then evaluate relative `expression` against `viewData.Model` - handle `null` or empty `expression` special case in this method (remove `throw`s) - always pass relative `expression` name into `Eval()` - remove `null` or empty `expression` handling from higher-level code - in a couple of cases, special-case returned `ViewDataInfo` - #2662 - remove incorrect guard from `DefaultHtmlGenerator.GenerateRadioButtion()` - add doc comments for the core methods that have changed - enable unit tests skipped due to one of above bugs - fix one (yeah, just one) other test with incorrect expectations - remove functional test comments about the above bugs and update expectations nits: - move some comments describing `ViewDataEvaluator` methods above the methods
The string-based helpers not mentioned in #1485 (
@Html.TextArea()
etc.) also do not behave as expected in template views. But this problem occurs only if an entry exists in theViewDataDictionary
matching the (un-prefixed) expression name. So unexpected values will be used in the generated HTML -- luckily, in a somewhat narrow case.E.g. action contains
Index.cshtml contains
DisplayTemplates/Dependent.cshtml contains:
Result is:
Expect to see "13" displayed between the quotes.
The text was updated successfully, but these errors were encountered: