我是MVC的新手,我想实现部分LogIn,我可以在几个视图中使用它。但我有一个我无法理解的问题。
所以在/views/shared/_LogOnPartial.cshtml我有下一个代码:
@using netlek.ViewModels.Account
@model LogOnModel
<div class="widget-main padding-6">
@using (Html.BeginForm("LogOn", "Account", new { ReturnUrl = @Request.QueryString["ReturnUrl"] }))
{
@Html.ValidationSummary(true, "Oops, that didn't work.", new Dictionary<string, object>() { })
<div class="loginctr">
<fieldset class="account">
<label class="block clearfix">
<span class="input-icon input-icon-right">
@Html.TextBoxFor(m => m.UserName, new { placeholder = "Username / Email" })
</span>
<span class="block">@Html.ValidationMessageFor(m => m.UserName)</span>
</label>
<label class="block clearfix">
<span class="input-icon input-icon-right">
@Html.PasswordFor(m => m.Password, new { placeholder = "Password" })
</span>
<span class="block">@Html.ValidationMessageFor(m => m.Password)</span>
</label>
<div class="fl">
<input type="submit" value="Log On" class="btn btn-primary btn-large" style="margin: 20px 0;" />
</div>
</fieldset>
</div>
}
</div>
所以这是发布到/ Account / LogOn(AccountController)的简单Post Form:
public class AccountController : ControllerBase
{
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
model.NoCcRequired = !ApplicationSettings.RequireCcUpfront;
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
TrackingTasks.SetUserAction(MvcApplication.DbSession, model.UserName, TrackingActionType.LoggedIn, TrackingPropertyType.LastLoginDate, DateTime.UtcNow);
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return this.RedirectToFirstPage(model.UserName, returnUrl);
}
return this.RedirectToFirstPage(model.UserName, string.Empty);
}
var user = Membership.GetUser(model.UserName);
if (user != null && user.IsLockedOut)
{
ModelState.AddModelError(string.Empty, "To protect your account, you have been locked out due to too many failed login attempts. Please contact support.");
return this.View(model);
}
ModelState.AddModelError(string.Empty, "The user name or password provided is incorrect.");
}
// If we got this far, something failed, redisplay form
return this.View(model);
}
}
现在我想在两个不同的页面(两个视图模型)中使用此部分登录:
/views/Account/LogOn.cshtml(标准LogOn页面):
@using netlek.ViewModels.Account
@model LogOnModel
@{
Layout = "~/Views/Shared/_NoHeaderLayout.cshtml";
ViewBag.Title = "Log On";
}
//SOME HTML BEFORE
<div class="span4 align-left">
@Html.Partial("_LogOnPartial")
</div>
//SOME HTML AFTER
我想在另一个页面(另一个视图)中使用它
/views/Extension/LogOn.cshtml:
@using netlek.ViewModels.Account
@model LogOnModel
@{
Layout = "~/Views/Shared/_NoHeaderLayout.cshtml";
ViewBag.Title = "Log On";
}
<div id="logon-wrap" class="span4">
@Html.Partial("_LogOnPartial")
</div>
我遇到的问题是如果我访问第二个LogOn页面(Extension / LogOn),并提交没有用户名和密码的登录表单,那么它就失败了。它在AccountController中命中LogOn()方法,因为它失败了,我返回this.View(model);它将我重定向到标准的LogOn页面(/ Account / LogOn)。
所以,如果我访问第二页,我有这个部分LogOn:
/ External / LogOn和我点击LogIn按钮没有任何细节失败并将我重定向到/ Account / LogOn页面,但我想留在同一页面/ External / LogOn。
我理解为什么会发生这种情况,因为它击中了AccountControler.LogOn()并返回View(模型),它返回“View / Account / LogOn.cshtml”。但我不知道如何正确地修复/实现它。
所以我希望这个部分登录在多个视图中使用,如果它无法返回视图,我提交表单并不总是/ Account / LogOn视图。
答案 0 :(得分:0)
您可以做的是从AccountController继承您的ExternalController类,并修改部分视图以发布到LogOn操作。现在LogOn方法也存在于ExternalController类中,返回View(model)
返回外部登录视图。 (你正在混合扩展和外部,但我认为它们是相同的。)
您的代码的其他一些评论可以使它们更安全:检查returnUrl是否在您的域中,并包含防伪代码以防止您的网站遭受CSRF攻击。
答案 1 :(得分:0)
尝试更改控制器参数,例如
public ActionResult LogOn(LogOnModel model, string returnUrl, string view = string.Empty)
{
// Your code here and then write below condition
if(view == "External")
return RedirectToAction("Extension/LogOn");
else
return View(model);
}
现在从父视图调用部分视图,如下所示;
/views/Account/LogOn.cshtml(标准LogOn页面):
@using netlek.ViewModels.Account
@model LogOnModel
@{
Layout = "~/Views/Shared/_NoHeaderLayout.cshtml";
ViewBag.Title = "Log On";
}
//SOME HTML BEFORE
<div id="LogOn" class="span4 align-left">
// @Html.Partial("_LogOnPartial")
</div>
<script>
$(document).ready(function () {
$("#LogOn").load("/LogOnPartial/", { view: "Account" });
});
</script>
你的另一页将是;
/views/Extension/LogOn.cshtml:
@using netlek.ViewModels.Account
@model LogOnModel
@{
Layout = "~/Views/Shared/_NoHeaderLayout.cshtml";
ViewBag.Title = "Log On";
}
<div id="logon-wrap" class="span4">
// @Html.Partial("_LogOnPartial")
</div>
<script>
$(document).ready(function () {
$("#logon-wrap").load("/LogOnPartial/", { view: "External" });
});
</script>