c# - ASP.NET MVC2 Login form in master page -


i'm trying find elegant way of having login form in master page. means unless user logs in, login form should appear on every page. (this common these days)

taking example comes mvc2 application in visual studio have created this:

public class masterviewmodel {     public string user { get; set; } // omitted validation attributes     public string pass{ get; set; }     public bool rememberme { get; set; } } 

every view model inherits masterviewmodel

public class registerviewmodel : masterviewmodel {     public string username { get; set; }     public string email { get; set; }     public string password { get; set; }     public string confirmpassword { get; set; } } 

my master page renders partial view

<%@ master language="c#" inherits="system.web.mvc.viewmasterpage<mylogon.viewmodels.masterviewmodel>" %> .....             <div id="logindisplay">                 <% html.renderpartial("logon"); %>             </div>  ...... 

strongly-typed partial view:

<%@ control language="c#" inherits="system.web.mvc.viewusercontrol<mylogon.viewmodels.masterviewmodel>" %>     <%         if (request.isauthenticated) {     %>             welcome <b><%= html.encode(page.user.identity.name) %></b>!             <div>[ <%= html.actionlink("change password", "changepassword", "account") %> ]</div>                     <div>[ <%= html.actionlink("log off", "logoff", "account") %> ]</div>     <%         }         else {     %>          <%= html.validationsummary(true, "login unsuccessful. please correct errors , try again.") %>          <% using (html.beginform("logon", "account",formmethod.post)) { %>             <div>                 <fieldset>                     <legend>account information</legend>                      <div class="editor-label">                         <%= html.labelfor(m => m.user) %>                     </div>                     <div class="editor-field">                         <%= html.textboxfor(m => m.user) %>                         <%= html.validationmessagefor(m => m.user) %>                     </div>                      <div class="editor-label">                         <%= html.labelfor(m => m.pass) %>                     </div>                     <div class="editor-field">                         <%= html.passwordfor(m => m.pass) %>                         <%= html.validationmessagefor(m => m.pass) %>                     </div>                      <div class="editor-label">                         <%= html.checkboxfor(m => m.rememberme) %>                         <%= html.labelfor(m => m.rememberme) %>                     </div>                                   <p>                         <input type="submit" value="log on" />                     </p>                 </fieldset>             </div>         <% } %>     <%         }     %> 

register page:

<%@ page language="c#" masterpagefile="~/views/shared/site.master" inherits="system.web.mvc.viewpage<mylogon.models.registerviewmodel>" %> ...     <h2>create new account</h2>     <p>         use form below create new account.      </p>     <p>         passwords required minimum of <%= html.encode(viewdata["passwordlength"]) %> characters in length.     </p>      <% using (html.beginform("register", "account" ,formmethod.post))        { %>         <%= html.validationsummary(true, "account creation unsuccessful. please correct errors , try again.") %>         <div>             <fieldset>                 <legend>account information</legend>                  <div class="editor-label">                     <%= html.labelfor(m => m.username) %>                 </div>                 <div class="editor-field">                     <%= html.textboxfor(m => m.username) %>                     <%= html.validationmessagefor(m => m.username) %>                 </div>                  <div class="editor-label">                     <%= html.labelfor(m => m.email) %>                 </div>                 <div class="editor-field">                     <%= html.textboxfor(m => m.email) %>                     <%= html.validationmessagefor(m => m.email) %>                 </div>                  <div class="editor-label">                     <%= html.labelfor(m => m.password) %>                 </div>                 <div class="editor-field">                     <%= html.passwordfor(m => m.password) %>                     <%= html.validationmessagefor(m => m.password) %>                 </div>                  <div class="editor-label">                     <%= html.labelfor(m => m.confirmpassword) %>                 </div>                 <div class="editor-field">                     <%= html.passwordfor(m => m.confirmpassword) %>                     <%= html.validationmessagefor(m => m.confirmpassword) %>                 </div>                  <p>                     <input type="submit" value="register" />                 </p>             </fieldset>         </div>     <% } %> </asp:content> 

since view models inherit masterviewmodel logon partial view satisfied i'm finding solution inelegant. there other way achieve this?

use partial view have different views based on logged in status. return 1 view anonymous users login form/lunk register page , second view logged in users.

partial views can have own models not need inherit master view model.

inheriting models can cause problems later (it makes using html.editformodel() or .displayformodel() tricky render common master view fields too).

oh , in general, it's bad practice view rely on outside model - test on request.isauthenticated may fine if want absolutely correct, should have model.isauthenticated property set action. said, switching views obviate problem entirely.

edit: 1 last improvement. on lines one:

welcome <b><%= html.encode(page.user.identity.name) %></b>! 

instead do:

welcome <b><%: page.user.identity.name %></b>! 

actually better hit model:

welcome <b><%: model.username %></b>! 

(note <%: not <%=). form of tag indicates contents should html-encoded. what's better if encounters string, encode it. if encounters htmlstring, won't. .net mvc functions return string or html string appropriate can this:

<%: html.editfor(x => x.fieldname) %> <%: model.somefield %> 

the first not html encoded editfor() returns htmlstring. second encoded (if somefield standard string)

this make code both neater , more robust. can use dynamically generate html should have , have encoded/not appropriate. eg have helper functions handle including css/js. return htmlstrings...

<%: helper.includecss("somecss.css") %> 

Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -