I am in doubt how to construct my views and viewmodels… Lets see a (simplified) situation. I have a registration view with two variations: openid and strandard username/password. I see two ways how to
implement this:
1.) First way: one view model and one view (some kind of Pseudocode):
class RegisterViewModel:
- public string OpenId {get;set;} // used only in openid registration
- public string Username {get;set;} // used only in username/password registration
- public string Password {get;set;} // used only in username/password registration
- public string PasswordConfirmation {get;set;} // used only in username/password registration
- public string Email {get;set;} // used in both registrations
- public string FirstName {get;set;} // used in both registrations
- public string LastName {get;set;} // used in both registrations
- public RegistrationType Type {get;set;} // used in both registrations
...
RegisterView.aspx (System.Web.Mvc.ViewPage):
...
<h1>Account info</h1>
<% if (Model.Type == Registration.Type.OpenId) { %>
<%= Html.TextBox("OpenId") %>
<% } else { %>
<%= Html.TextBox("Username") %>
<%= Html.TextBox("Password") %>
<%= Html.TextBox("PasswordConfirmation") %>
<% } %>
<%= Html.TextBox("Email") %>
<h1>Personal info</h1>
<%= Html.TextBox("FirstName") %>
<%= Html.TextBox("LastName") %>
..
2.) Second way: several view models and several views (user controls):
abstract class RegisterViewModel:
- public string Email {get;set;}
- public string FirstName {get;set;}
- public string LastName {get;set;}
class OpenIdRegisterViewModel:
- public string OpenId {get;set;}
class UsernameRegisterViewModel:
- public string Username {get;set;}
- public string Password {get;set;}
- public string PasswordConfirmation {get;set;}
UserControl.ascx:
...
<h1>Personal info</h1>
<%= Html.TextBox("FirstName")
<%= Html.TextBox("LastName")
...
OpenIdRegisterView.aspx (System.Web.Mvc.ViewPage):
...
<h1>Account info</h1>
<%= Html.TextBox("OpenId") %>
<%= Html.TextBox("Email") %>
<% Html.RenderPartial("UserControl") %>
..
UsernameRegisterView.aspx (System.Web.Mvc.ViewPage):
...
<h1>Account info</h1>
<%= Html.TextBox("Username") %>
<%= Html.TextBox("Password") %>
<%= Html.TextBox("PasswordConfirmation") %>
<%= Html.TextBox("Email") %>
<% Html.RenderPartial("UserControl") %>
...
I think that the first way is not so OO, but it is easiery to align the view, and the second way is more oo, but it is hard to align elements – that is the reason why I didn’t put email into the user control, because I want to have email near account info.
What option would you choose and why? Maybe some 3rd option? Where is the limit between these two options (when you choose first, when second)…
Many thanks!
I use the second option:
use Ajax I can have one ascx loaded
asynchronously if javascript is
enabled or load the full page if not.
That makes it easier to implement
both: an Ajax and non-Ajax version
I would only pass the required Model into ascx:
I am not shure if I would realy put the common fields on the main view. It would be better to just be able to put the ascx on some other view and have all the fields you need.
Most of us come from WebForm – world where ascx are very powerfull. It was the first thing I looked at when evaluating MVC. Well there was not much to see.
But even in this very limited form they are usefull.