내 MVC 3 아키텍처에서 중첩 된 뷰를 설정하는 데 문제가 있습니다. 현재 내가 가지고있는 것입니다 :MVC 3의 중첩 된 뷰
그래서 기본적으로 내 _Layout.cshtml 페이지는 내 마스터 페이지입니다. 그럼 Logon.cshtml이 있습니다. 이것은 내 로그온 페이지의 "마스터 페이지"역할을합니다. 그 밑에는 Login.cshtml과 ForgotPassword.cshtml이라는 부분 뷰가 있습니다. 이것 모두 뒤에 AccountController라는 컨트롤러가 있습니다. 첫째,/내가 당신이
조회수/계정 Logon.cshtml 보여 내가 로그인을 렌더링 가지고 Html.RenderAction와 부분적인 전망을 ForgotPassword 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>
주의하자. 나는 이들 각각이 실제로 형태이고 AccountController에 게시해야하기 때문에이 작업을 수행하고 있습니다. 다음으로, 내가 당신에게 내 Login.cshtml 파일을 보여주지 :
조회수/계정/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>
}
당신이 볼 수 있듯이을, 이것은 단순한 형태입니다. 여기에 두 가지 모델을 사용하려고합니다. 각보기마다 하나씩. 하나는 부모 용이고 다른 하나는 자식보기 용입니다 (forgotpassword에는 하나도 있습니다). 어쨌든,/내 AccountController 당신에게
컨트롤러를 표시하는 방법 [HttpPost] 로그인 (...)에
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");
}
//........
}
AccountController.cs
을하자, 나는 사용자 creds가 올바른지 있는지 확인하고 있습니다. 그렇다면 모든 것이 잘 작동하지만 문제는 오류입니다. 내가return View(model)
을 사용하면
return View("Logon");
을 사용하는 경우 무한 루프가 발생한다고 생각합니다. Login.cshtml에 대한 부분 뷰를 얻었고
return RedirectToAction("Index", "Home");
을 사용하면 올바르게 로그온 뷰로 돌아 왔지만 추가 한 오류가 발생합니다. 표시되지 않습니다 (그들은 내가
return View(model);
일 때 표시됩니다.) 여기서 잘못된 점이 무엇입니까? 내 설치가 적절하다고 생각하지만 정상적으로 작동하는 방법을 알아낼 수 없습니다. 반환을 통해 로그온을 렌더링하고 싶습니다. . 오류와 cshtml보기 그냥 완료하기 위해, 여기 내 두 ViewModels 제공된보기위한 것입니다 :
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; }
}
최고를! 나는 더 가깝다! ImportModelStateFromTempData에서 Logon.cshtml을 렌더링 할 때 오류가 발생하는 것을 볼 수 있지만 오류가 발생하지만 Login.cshtml (하위 부분 뷰)을 렌더링하면 다른 부분을 치고 제거하는 중입니다. 따라서 오류가 발생해야하는보기가 계속 손실됩니다. 부모보기는 기본적으로 그들을 먹고 있습니다. 생각? –
@Tyler -'ViewResult'와'PartialViewResult'가 모두'ViewResultBase'를 확장하기 때문에 결과가'ViewResult' 대신에'ViewResultBase' 타입인지 확인하기 위해'if' 문을 변경하는 것이 쉬운 문제입니다. 그러나 다른 부분 뷰에도 오류를 표시 할 영역이 있으면 두 번 표시 될 수 있습니다. 또 다른 방법은 Login.cshtml 대신 Logon.cshtml에 두 부분의 오류를 표시하는 것입니다. –
도움 주셔서 감사합니다. ViewResultBase 사용에 대한 귀하의 제안을 사용하여 종료되었습니다. 내보내기에서 오류를 던진 작업 이름과 함께 tempdata 값을 추가하여 중복 된 오류 표시를 방지했습니다. 가져 오기 필터는 현재 작업이 tempdata의 작업과 일치하는 경우에만 모델 상태를 병합합니다. 또한 가져 오기/내보내기 및 ViewResult를 사용하여 상위 뷰로 오류를 버블 링하는 또 다른 필터를 만들 수도 있습니다. 다시 한 번 감사드립니다! –