Hi,
I'm facing an issue with nested masterpages in Asp.net MVC 2.0.
When using a normal master (not nested - below default.master), the login functionality works fine.
Using the nested master, the ajax form post results in a full page render of the default.master inside the UpdateTarget div. Since in this case the referred master is twocolumn.master this makes no sense.
Any ideas or suggestions?
Setup & Code:
default.master:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleTagContent" runat="server" />
</title>
<!--script includes -->
</head>
<body>
<div id="main">
<div id="header">
<div id="brand">
<a href="#">
<img src="/content/site_images/lgo_justProud.gif" width="264" height="62" alt="Just Proud" /></a></div>
<div id="logMenu" class="noPrint">
<asp:ContentPlaceHolder ID="LoginContentArea" runat="server">
<div id="login">
<%if (SessionHelper.LoggedInUser == null)
{
Html.RenderPartial("UserNamePasswordLogin", null);
}
else
{
Html.RenderPartial("UserLoginStatus", null);
}; %>
</div>
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="Content_MainZone" runat="server">
</asp:ContentPlaceHolder>
</div>
</div>
</body>
</html>
TwoColumn.master:
<asp:Content ID="Content1" ContentPlaceHolderID="Content_MainZone" runat="server">
<div class="bodyTop">
</div>
<div class="headerSmall">
<h1>
<asp:ContentPlaceHolder ID="Content_SubTitle" runat="server">
</asp:ContentPlaceHolder>
</h1>
</div>
<div class="twoColumns">
<div class="contentLeft">
<asp:ContentPlaceHolder ID="Content_MainLeft" runat="server">
</asp:ContentPlaceHolder>
</div>
<div class="contentRight">
<asp:ContentPlaceHolder ID="Content_MainRight" runat="server">
</asp:ContentPlaceHolder>
</div>
<div class="clearfloats" />
</div>
</asp:Content>
<asp:Content ContentPlaceHolderID="HeadTagContent" ID="Content2" runat="server">
<asp:ContentPlaceHolder ID="HeadTagContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ContentPlaceHolderID="TitleTagContent" ID="Content3" runat="server">
<asp:ContentPlaceHolder ID="TitleTagContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
UserNamePasswordLogin.ascx:
<div class="notLoggedIn">
<%using (Ajax.BeginForm("Login", "Authentication", new AjaxOptions() { UpdateTargetId = "login" }))
{ %>
<%=Html.ValidationSummary()%>
<table cellpadding="0" cellspacing="0">
<tr>
<td class="username" colspan="2">
<%--<input name="username" type="text" value="username" size="12" />--%>
<%=Html.TextBox("username", null, new { size = "12" })%>
<%=Html.ValidationMessage("username", "*")%>
</td>
<td class="password">
<%--<input name="password" type="text" value="Password" size="12" />--%>
<%=Html.Password("password", null, new { size = "12" })%>
<%=Html.ValidationMessage("password", "*")%>
</td>
<td>
<%=Html.Hidden("returnUrl", Request.RawUrl)%>
<%-- <input type="button" value="Go" />--%>
<input type="submit" value="Login" />
</td>
</tr>
<tr>
<td>
<div class="checkbox">
<input name="rememberMe" type="checkbox" value="true" />
</div>
</td>
<td class="usernameTxt" align="left" width="90">
<span class="txt">
<%=GlobalizationProperties.Labels.RememberMe%></span>
</td>
<td class="passwordTxt">
<span class="txt"><a href="#">Forgot your pasword</a></span>
</td>
</tr>
</table>
<%};%>
Login Action :
[HttpPost]
public ActionResult Login(string username, string password, bool? rememberMe, string returnUrl)
{
LoginDTO dto = new LoginDTO() { Login = username, Password = password, RememberMe = rememberMe };
// Basic parameter validation
if (String.IsNullOrEmpty(username))
{
ViewData.ModelState.AddModelError("username", GlobalizationProperties.ErrorMessages.LoginRequired);
}
if (String.IsNullOrEmpty(password))
{
ViewData.ModelState.AddModelError("password", GlobalizationProperties.ErrorMessages.PasswordRequired);
}
if (ViewData.ModelState.IsValid)
{
bool loginSuccess = LoginHelper.PerformLogin(dto);
if (loginSuccess)
{
return JavaScript(string.Format("document.location.replace('{0}');", HttpUtility.HtmlEncode(returnUrl)));;
}
else
{
ViewData.ModelState.AddModelError("username", GlobalizationProperties.ErrorMessages.LoginPassNotFound);
}
}
ViewData["LoginForm"] = "LoginForm";
return PartialView("UserNamePasswordLogin");
}
Regards, Bart