You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.
With these changes, everything works properly (the right type gets instantiated and assigned for the model, etc.) up until something on the view requires contextualization.
The issue is that for the view, the HtmlHelpers the type of the View data is ViewData while at runtime, the type of the model is ViewData. When we try to contextualize the view, we try to cast ViewDataDictionary to ViewDataDictionary which obviously fails as there is no inheritance relationship between the two of them.
This instance of the problem will be an issue for each wrapping type that the view uses (only at the top level of the page) (By wrapping type I mean any type that has the model as a generic argument, the only instance I can think of at the moment is ViewDataDictionary)
What I'm proposing is that we handle this specific case and support "covariance" for the view data dictionary. This implies that first we try to cast ViewDataDictionary{ to ViewDataDictionary, if that casting fails, we check if TRuntime extends TModel and if that's the case, we create a new ViewDataDictionary(ViewDataDictionary,ViewDataDictionary.Model) and we use that new view data dictionary to provide context to other components.
A more realistic example (based on identity as a library)
@page@model LoginModel
publicabstractclassLoginModel:PageModel{// Define the input model and other elements of the contract with the view.}internalclassLoginModel<TUser>:LoginModelwhereTUser:IdentityUser{publicLoginModel(UserManager<TUser>userManager,SignInManager<TUser>signInManager){}// Provide implementations for OnGet, OnPost, etc.}
When plugged into MVC I define a contention in the form
In terms of user scenarios, I require this to allow customizing the user without requiring the scaffolding of all the views that aren't changing. For example, if i'm adding additional properites to the user, I might only want to customize the registration and user profile pages and leave any other page untouched.
On HtmlHelper<T> we now support contextualizing an instance of
HtmlHelper<TBase> with a ViewDataDictionary<TDerived> in
ViewContext.ViewData.
This can happen in some situations when the model for a RazorPage has
been changed using a page application model convention.
In these cases we just build a new ViewDataDictionary<TBase> and pass in
the TDerived model as an instance.
I really don't know how to properly name this issue, so I'm going to explain what I'm doing.
I have a razor page
Index.cshtml
At runtime I have an IPageApplicationModelConvention that I'm using to substitute the abstract version of the model with the derived version
With these changes, everything works properly (the right type gets instantiated and assigned for the model, etc.) up until something on the view requires contextualization.
The issue is that for the view, the HtmlHelpers the type of the View data is ViewData while at runtime, the type of the model is ViewData. When we try to contextualize the view, we try to cast ViewDataDictionary to ViewDataDictionary which obviously fails as there is no inheritance relationship between the two of them.
This instance of the problem will be an issue for each wrapping type that the view uses (only at the top level of the page) (By wrapping type I mean any type that has the model as a generic argument, the only instance I can think of at the moment is ViewDataDictionary)
What I'm proposing is that we handle this specific case and support "covariance" for the view data dictionary. This implies that first we try to cast ViewDataDictionary{ to ViewDataDictionary, if that casting fails, we check if TRuntime extends TModel and if that's the case, we create a new ViewDataDictionary(ViewDataDictionary,ViewDataDictionary.Model) and we use that new view data dictionary to provide context to other components.
A more realistic example (based on identity as a library)
When plugged into MVC I define a contention in the form
In terms of user scenarios, I require this to allow customizing the user without requiring the scaffolding of all the views that aren't changing. For example, if i'm adding additional properites to the user, I might only want to customize the registration and user profile pages and leave any other page untouched.
The change doesn't seem very complicated either, a naive implementation can be seen here:
10ec000#diff-bb87a648158c4f18c421ea59d5a1b120R66
I'm sure there are more places to chase this conversion down, but I don't expect it to be that many.
The text was updated successfully, but these errors were encountered: