Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Change ViewDataDictionary copy constructor to ensure ModelMetadata is never that for object #1441

Closed
wants to merge 3 commits into from

Conversation

dougbu
Copy link
Member

@dougbu dougbu commented Oct 23, 2014

nit:

  • fix existing comment in main ViewDataDictionary copy constructor
  • add some <remarks/> to the four ViewDataDictionary copy constructors

plus tests

@dougbu
Copy link
Member Author

dougbu commented Oct 23, 2014

/cc @yishaigalatzer @pranavkm

// If we're constructing a derived ViewDataDictionary (or any other value type),
// SetModel will throw if we try to set it to null. We should not throw in that case.
// Slightly optimize SetModel and avoid creating unnecessary new ModelMetadata instances. Tests also depend
// on ModelMetadata being copied along when the model type does not change.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pranavkm tests were one reason I found changing ViewDataDictionary<TModel>.ModelMetadata untenable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really an optimization? Why do tests depend on this behavior if it's not guaranteed on the main codepath during execution?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests may be driving this choice 😸 but on the other hand, they're demonstrating an undocumented capability our users may be relying on. that is our users may also be doing things like the following and expecting their DisplayName value to be used in the generated HTML.

  helper.ViewData.ModelMetadata.DisplayName = displayName;
  ...
  @Html.EditorFor(m => m)

we had an offline conversation about this flow and I'm going to take a crack at updating the various ViewDataDictionary constructors to be more explicit about intent.

@rynowak
Copy link
Member

rynowak commented Oct 24, 2014

:shipit:

// SetModel will throw if we try to set it to null. We should not throw in that case.
// Avoid copying information about the object type. To do so when model==null would confuse the
// ViewDataDictionary<TModel>.ModelMetadata getter.
if (typeof(object) != source.ModelMetadata?.ModelType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do yoda condition

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

@pranavkm
Copy link
Contributor

:shipit:

…` is

 never that for `object`
- `ViewDataDictionary<TModel>.ModelMetadata` was for `object` after base
 copy constructor got value from `ViewDataDictionary<object>`
- problem led to #1426 symptoms
- with copy constructor leaving `base.ModelMetadata==null` more often,
 `ViewDataDictionary<TModel>.ModelMetadata` usually tracks `TModel` if
 `Model==null`

nit:
- fix existing comment in main `ViewDataDictionary` copy constructor
- exercises display and editor helpers when `Model==null`
@dougbu dougbu force-pushed the release.correct.metadata.1426 branch from 2df96b5 to 0f34c61 Compare October 27, 2014 23:22
@dougbu
Copy link
Member Author

dougbu commented Oct 27, 2014

Pushed into Release w/ commits 8d2a1c4 through cfcb1f2 and merged into Dev

@dougbu dougbu closed this Oct 27, 2014
@dougbu dougbu deleted the release.correct.metadata.1426 branch October 28, 2014 03:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants