Rework `ViewDataDictionary` to ensure `ModelMetadata` is never `null` (#1466)

This is the reanimation of #1453, now done against dev.  No significant changes from that PR after I addressed comments there.

See individual commits for details.

/cc @pranavkm @rynowak @yishaigalatzer 
I think you answered this before, so humour me... Why do we end up here, and why is storing `declaredModelType: typeof(object)` correct? Won't we end up with the `object` model metadata? Isn't that bad?