如何在 AJAX post 之后刷新 _loginPartial.cshtml
How to refresh _loginPartial.cshtml after AJAX post
我现在正在开发一个简单的 asp.net 网络应用程序,我遇到了一些障碍,形式是我的 _loginPartial.cshtml 在异步登录后没有重新加载。
我已将基本登录更改为使用模态和异步登录,并在适当的地方发出成功消息。问题是页面必须在再次点击 if (Request.Authenticated) 块之前刷新以显示登录用户名而不是 'login' 按钮。
我的问题 - 是否有一行 javascript 我可以在我的 ajax 成功块中使用来刷新 _loginPartial.cshtml 而无需重新加载整个页面?
这是我的 _loginPartial.cshtml:
@using Microsoft.AspNet.Identity
<script>
$(function () {
$("#btnShowLogin").click(function () {
if (($('#RegisterModal').hasClass('in')))
$('#RegisterModal').modal('hide');
$('#LoginModal').modal('show');
});
$('#btnShowRegister').click(function () {
if (($('#LoginModal').hasClass('in')))
$('#LoginModal').modal('hide');
$('#RegisterModal').modal('show');
})
})
$(document).keydown(function (event) {
if (event.keyCode == 27) {
$('#LoginModal').modal('hide');
}
});
</script>
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}
}
else
{
<ul class="nav navbar-nav navbar-right">
<a class="btn btn-green" href="#" id="btnShowRegister">
Sign Up
<i class="fa fa-user-plus "></i>
</a>
<a class="btn btn-green" href="#" id="btnShowLogin">
Log In
<i class="fa fa-sign-in "></i>
</a>
</ul>
@Html.Partial("~/Views/Account/Login.cshtml", new VaceProject.Models.LoginViewModel())
@Html.Partial("~/Views/Account/Register.cshtml", new VaceProject.Models.RegisterViewModel())
}
这是我的 Login.cshtml
@using VaceProject.Models
@model LoginViewModel
@{
ViewBag.Title = "Log in";
}
<script>
//form submit event
$(document).ready(function () {
$('#login-form').submit(function (e) {
e.preventDefault();
// Create formData object with antiforgeryToken
var formData = new FormData($('#login-form')[0]);
formData.append('Email', $('#emailTxt').val());
//validate empty fields
var isValid = IsModelValidated(formData);
if (isValid) {
$.ajax({
type: "POST",
url: "@Url.Action("Login","Account")",
data: formData,
contentType: false,
processData: false,
success: function (data) {
if (data == "Success") { //toastr popup
toastr.success("Logged in.");
$('#LoginModal').modal('hide');
}
else if (data == "Failure")
toastr.error("Login failed. Check your credentials and try again.");
else if (data == "Locked out")
toastr.info("Login failed because this account is locked out. Please contact an admin for help.");
},
error: function (xhr, status) {
toastr.error("Something went wrong.");
}
});
}
})
})
</script>
<div class="modal fade container" id="LoginModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog ">
<div class="modal-content col-10 col-md-10 col-sm-10">
<form class="form-horizontal" method="post" id="login-form" role="form">
@Html.AntiForgeryToken()
<div class="modal-header">
<h5>Login using your VACE Edu account details or click <a href="#">here</a> to register your interest in a personalised communication program.</h5>
</div>
<div class="modal-body">
<div class="fieldlist">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control", @id = "emailTxt" })
@Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="margin-left-33">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group pull-right padding-10">
<input type="submit" value="Log in" class="btn btn-default" />
<input type="button" value="Cancel" data-dismiss="modal" class="btn btn-info cancel-btn" />
</div>
</div>
@* Enable this once you have account confirmation enabled for password reset functionality
<p>
@Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>*@
</form>
</div>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
aa 和我的 Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - VACE Education</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="~/Scripts/toastr.min.js?v=1"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css" />
<link href="~/Content/toastr.min.css?v=1" rel="stylesheet" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("VACE EDU", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
@if (User.IsInRole("Admin"))
{
<li>@Html.ActionLink("Manage Students", "Index", "Student")</li>
}
<li>@Html.ActionLink("Courses", "Index", "Course")</li>
<li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
<li>@Html.ActionLink("Departments", "Index", "Department")</li>
</ul>
<div id="loginPartial">
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - VACE Education</p>
</footer>
</div>
@RenderSection("scripts", required: false)
</body>
</html>
<script>
//Validates form fields against empty
function IsModelValidated(formData) {
debugger;
var errorMessage = '';
for (var [key, value] of formData.entries()) {
console.log(key, value);
switch (key) {
case "ForeName":
if (value == '')
errorMessage += '<li>Please enter forename.</li>';
break;
case "LastName":
if (value == '')
errorMessage += '<li>Please enter surname.</li>';
break;
case "Email":
if (value == '')
errorMessage += '<li>Please enter a valid email address.</li>';
case "DOB":
if (value == '')
errorMessage += '<li>Please select a valid date of birth.</li>';
default:
}
}
if (errorMessage !== '') {
toastr.error(errorMessage);
return false;
}
else
return true;
}
</script>
最后是我的登录方式
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
ApplicationUser signedInUser = UserManager.FindByEmail(model.Email);
ViewBag.IsAdmin = isAdminUser(signedInUser);
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(signedInUser.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return Json("Success");
case SignInStatus.LockedOut:
return Json("Locked out");
//case SignInStatus.RequiresVerification:
// return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return Json("Failure");
}
}
return Json("Success");
}
现在所有发生的事情是吐司出现 'Login successful' 但 _loginPartial 不会刷新以显示登录的用户名,直到页面刷新。
希望我已经足够清楚地描述了我的问题,我期待阅读任何回复!
<div id="loginPartial">
@Html.Partial("_LoginPartial")
</div>
通过 ajax 刷新整个局部视图,使用包装 div 替换其内容。
您可以创建一个新控制器或利用现有控制器,其中 returns _LoginPartial
局部视图如下:
[HttpGet]
public PartialViewResult RefreshLoginPartial()
{
// do something
return PartialView("_LoginPartial");
}
然后使用 html()
函数刷新 div
包含要在 data == "Success"
条件内替换的部分视图的元素,如下例所示:
$.ajax({
type: "POST",
url: "@Url.Action("Login","Account")",
data: formData,
contentType: false,
processData: false,
success: function (data) {
if (data == "Success") { //toastr popup
toastr.success("Logged in.");
$('#LoginModal').modal('hide');
// refresh login partial view from AJAX
// $.get is shorthand form of AJAX GET request, see https://api.jquery.com/jquery.get/
$.get('@Url.Action("RefreshLoginPartial", "ControllerName")', function (result) {
$('#loginPartial').html(result);
});
}
else if (data == "Failure")
toastr.error("Login failed. Check your credentials and try again.");
else if (data == "Locked out")
toastr.info("Login failed because this account is locked out. Please contact an admin for help.");
},
error: function (xhr, status) {
toastr.error("Something went wrong.");
}
});
我现在正在开发一个简单的 asp.net 网络应用程序,我遇到了一些障碍,形式是我的 _loginPartial.cshtml 在异步登录后没有重新加载。
我已将基本登录更改为使用模态和异步登录,并在适当的地方发出成功消息。问题是页面必须在再次点击 if (Request.Authenticated) 块之前刷新以显示登录用户名而不是 'login' 按钮。
我的问题 - 是否有一行 javascript 我可以在我的 ajax 成功块中使用来刷新 _loginPartial.cshtml 而无需重新加载整个页面?
这是我的 _loginPartial.cshtml:
@using Microsoft.AspNet.Identity
<script>
$(function () {
$("#btnShowLogin").click(function () {
if (($('#RegisterModal').hasClass('in')))
$('#RegisterModal').modal('hide');
$('#LoginModal').modal('show');
});
$('#btnShowRegister').click(function () {
if (($('#LoginModal').hasClass('in')))
$('#LoginModal').modal('hide');
$('#RegisterModal').modal('show');
})
})
$(document).keydown(function (event) {
if (event.keyCode == 27) {
$('#LoginModal').modal('hide');
}
});
</script>
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}
}
else
{
<ul class="nav navbar-nav navbar-right">
<a class="btn btn-green" href="#" id="btnShowRegister">
Sign Up
<i class="fa fa-user-plus "></i>
</a>
<a class="btn btn-green" href="#" id="btnShowLogin">
Log In
<i class="fa fa-sign-in "></i>
</a>
</ul>
@Html.Partial("~/Views/Account/Login.cshtml", new VaceProject.Models.LoginViewModel())
@Html.Partial("~/Views/Account/Register.cshtml", new VaceProject.Models.RegisterViewModel())
}
这是我的 Login.cshtml
@using VaceProject.Models
@model LoginViewModel
@{
ViewBag.Title = "Log in";
}
<script>
//form submit event
$(document).ready(function () {
$('#login-form').submit(function (e) {
e.preventDefault();
// Create formData object with antiforgeryToken
var formData = new FormData($('#login-form')[0]);
formData.append('Email', $('#emailTxt').val());
//validate empty fields
var isValid = IsModelValidated(formData);
if (isValid) {
$.ajax({
type: "POST",
url: "@Url.Action("Login","Account")",
data: formData,
contentType: false,
processData: false,
success: function (data) {
if (data == "Success") { //toastr popup
toastr.success("Logged in.");
$('#LoginModal').modal('hide');
}
else if (data == "Failure")
toastr.error("Login failed. Check your credentials and try again.");
else if (data == "Locked out")
toastr.info("Login failed because this account is locked out. Please contact an admin for help.");
},
error: function (xhr, status) {
toastr.error("Something went wrong.");
}
});
}
})
})
</script>
<div class="modal fade container" id="LoginModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog ">
<div class="modal-content col-10 col-md-10 col-sm-10">
<form class="form-horizontal" method="post" id="login-form" role="form">
@Html.AntiForgeryToken()
<div class="modal-header">
<h5>Login using your VACE Edu account details or click <a href="#">here</a> to register your interest in a personalised communication program.</h5>
</div>
<div class="modal-body">
<div class="fieldlist">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control", @id = "emailTxt" })
@Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="margin-left-33">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group pull-right padding-10">
<input type="submit" value="Log in" class="btn btn-default" />
<input type="button" value="Cancel" data-dismiss="modal" class="btn btn-info cancel-btn" />
</div>
</div>
@* Enable this once you have account confirmation enabled for password reset functionality
<p>
@Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>*@
</form>
</div>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
aa 和我的 Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - VACE Education</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="~/Scripts/toastr.min.js?v=1"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css" />
<link href="~/Content/toastr.min.css?v=1" rel="stylesheet" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("VACE EDU", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
@if (User.IsInRole("Admin"))
{
<li>@Html.ActionLink("Manage Students", "Index", "Student")</li>
}
<li>@Html.ActionLink("Courses", "Index", "Course")</li>
<li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
<li>@Html.ActionLink("Departments", "Index", "Department")</li>
</ul>
<div id="loginPartial">
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - VACE Education</p>
</footer>
</div>
@RenderSection("scripts", required: false)
</body>
</html>
<script>
//Validates form fields against empty
function IsModelValidated(formData) {
debugger;
var errorMessage = '';
for (var [key, value] of formData.entries()) {
console.log(key, value);
switch (key) {
case "ForeName":
if (value == '')
errorMessage += '<li>Please enter forename.</li>';
break;
case "LastName":
if (value == '')
errorMessage += '<li>Please enter surname.</li>';
break;
case "Email":
if (value == '')
errorMessage += '<li>Please enter a valid email address.</li>';
case "DOB":
if (value == '')
errorMessage += '<li>Please select a valid date of birth.</li>';
default:
}
}
if (errorMessage !== '') {
toastr.error(errorMessage);
return false;
}
else
return true;
}
</script>
最后是我的登录方式
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
ApplicationUser signedInUser = UserManager.FindByEmail(model.Email);
ViewBag.IsAdmin = isAdminUser(signedInUser);
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(signedInUser.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return Json("Success");
case SignInStatus.LockedOut:
return Json("Locked out");
//case SignInStatus.RequiresVerification:
// return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return Json("Failure");
}
}
return Json("Success");
}
现在所有发生的事情是吐司出现 'Login successful' 但 _loginPartial 不会刷新以显示登录的用户名,直到页面刷新。
希望我已经足够清楚地描述了我的问题,我期待阅读任何回复!
<div id="loginPartial">
@Html.Partial("_LoginPartial")
</div>
通过 ajax 刷新整个局部视图,使用包装 div 替换其内容。
您可以创建一个新控制器或利用现有控制器,其中 returns _LoginPartial
局部视图如下:
[HttpGet]
public PartialViewResult RefreshLoginPartial()
{
// do something
return PartialView("_LoginPartial");
}
然后使用 html()
函数刷新 div
包含要在 data == "Success"
条件内替换的部分视图的元素,如下例所示:
$.ajax({
type: "POST",
url: "@Url.Action("Login","Account")",
data: formData,
contentType: false,
processData: false,
success: function (data) {
if (data == "Success") { //toastr popup
toastr.success("Logged in.");
$('#LoginModal').modal('hide');
// refresh login partial view from AJAX
// $.get is shorthand form of AJAX GET request, see https://api.jquery.com/jquery.get/
$.get('@Url.Action("RefreshLoginPartial", "ControllerName")', function (result) {
$('#loginPartial').html(result);
});
}
else if (data == "Failure")
toastr.error("Login failed. Check your credentials and try again.");
else if (data == "Locked out")
toastr.info("Login failed because this account is locked out. Please contact an admin for help.");
},
error: function (xhr, status) {
toastr.error("Something went wrong.");
}
});