MVC3アーキテクチャでネストされたビューを設定するのに問題があります。これは私が現在持っているものです:
_Layout.cshtml
Logon.cshtml
Login.cshtml
ForgotPassword.cshtml
つまり、基本的には、マスターページである_Layout.cshtmlページがあります。次に、Logon.cshtmlがあります。これは、ログオンページの「マスターページ」として機能します。その下に、Login.cshtmlとForgotPassword.cshtmlの2つの部分的なビューがあります。このすべての背後に、AccountControllerというコントローラーがあります。まず、Logon.cshtmlをお見せしましょう
ビュー/アカウント/Logon.cshtml
@model Coltrane.Web.Website.Models.Account.LogonViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Logon";
}
@*@this.CssIncludes(@Url.Content("~/Content/login.css"))*@
@this.ScriptIncludes(@Url.Content("~/Content/scripts/Account/logon.js"))
@this.InitFunctionIncludes("lga_loginTabs.init()")
@this.InitFunctionIncludes("lga_formFocus.init()")
<div id="container">
<div class="sectionFocus noBg">
<div style="margin: 24px auto; width: 450px;">
<div class="customerLogo" style="margin: 24px auto;">
logo
</div>
<div id="tabContainer" style="position: relative; width:100%;">
<div id="login" class="box_c" style="position:absolute; width:100%;">
<h1>User Login</h1>
<div class="box_c_content">
<div class="sepH_c">
@{ Html.RenderAction("Login", "Account"); }
<a href="#" id="gotoFogot">Forgot your password?</a>
</div>
</div>
</div>
<div id="forgot" class="box_c" style="position: absolute; width:100%;display: none;">
<h1>Forgot Your Password?</h1>
<div class="box_c_content">
<div class="sepH_c">
@{ Html.RenderAction("ForgotPassword", "Account"); }
<a href="#" id="gotoLogin">Back to Login</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
LoginビューとForgotPassword部分ビューをHtml.RenderActionでレンダリングしたことに注意してください。これらはそれぞれ実際にはフォームであり、AccountControllerに投稿する必要があるため、これを行っています。次に、Login.cshtmlファイルを表示します。
Views / Account / Login.cshtml
@model Coltrane.Web.Website.Models.Account.LoginViewModel
@{
Layout = null;
}
@this.ScriptIncludes(@Url.Content("~/Content/scripts/Account/login.js"))
@this.InitFunctionIncludes("login.init()")
<div class="sepH_a">
<label>
Please enter your email and password to log into the system.</label>
</div>
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "form_login" }))
{
<div class="sepH_a">
<div class="loginError">
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
@Html.ValidationMessageFor(m => m.UserName)<br />
@Html.ValidationMessageFor(m => m.Password)
</div>
</div>
<div class="sepH_a">
@Html.LabelFor(m => m.UserName, new { @class = "lbl_a" })
<br />
@Html.TextBoxFor(m => m.UserName, new { @class = "inpt_a_login", id = "lusername", name = "lusername" })
<span class="inputReqd" style="visibility: visible;">*</span>
</div>
<div class="sepH_a">
@Html.LabelFor(m => m.Password, new { @class = "lbl_a" })
<br />
@Html.PasswordFor(m => m.Password, new { @class = "inpt_a_login", id = "lpassword", name = "lpassword" })
<span class="inputReqd" style="visibility: visible;">*</span>
</div>
<div class="sepH_a">
@Html.CheckBoxFor(m => m.RememberMe, new { @class = "input_c", id = "remember" })
@Html.LabelFor(m => m.RememberMe, new { @class = "lbl_c" })
</div>
<div class="box_c_footer">
<button class="sectB btn_a" type="submit">
Login</button>
</div>
}
ご覧のとおり、これは単純な形式です。注意すべきことの1つは、ここで2つのモデルを使用しようとしていることです。ビューごとに1つ。1つは親用で、もう1つは両方の子ビュー用です(forgotpasswordにも1つあります)。とにかく、私のAccountControllerをお見せしましょう
Controllers / AccountController.cs
public class AccountController : Controller
{
private IAuthenticationService _authenticationService;
private ILoggingService _loggingService;
public AccountController(IAuthenticationService authenticationService,
ILoggingService loggingService)
{
_authenticationService = authenticationService;
_loggingService = loggingService;
}
public ActionResult Logon()
{
return View();
}
[HttpGet]
[ChildActionOnly]
public ActionResult Login()
{
return PartialView();
}
[HttpPost]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
else
{
ModelState.AddModelError("", "An error has occurred.");
}
// If we got this far, something failed, redisplay form
return View("Logon");
// return View(model)
// return RedirectToAction("Index", "Home");
}
//........
}
[HttpPost] Login(...)メソッドで、ユーザーの資格情報が正しいかどうかを確認しています。もしそうなら、すべてが正常に動作しますが、問題はエラーにあります。使用するreturn View("Logon");
と無限ループになると思います。使用するreturn View(model)
とLogin.cshtmlの部分ビューが表示され、を使用するとreturn RedirectToAction("Index", "Home");
ログオンビューに正しく戻りますが、追加したエラーは表示されません。 (私がいるときに表示されreturn View(model);
ます。ここで何が間違っているのですか?セットアップは理にかなっていると思いますが、正しく機能させる方法がわかりません。Logon.cshtmlビューをレンダリングするために戻ってください。エラー。完全を期すために、提供されたビューの2つのViewModelを次に示します。
public class LogonViewModel
{
}
public class LoginViewModel
{
[Required]
[Display(Name = "Email")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember Me?")]
public bool RememberMe { get; set; }
}