2017-01-04 67 views
2

我想将登录表单设置为PartialView或ViewComponent。用户输入用户名和密码我想用ajax登录并显示可能的验证错误,无论是使用jQuery还是重新渲染服务器上的登录表单。我不在乎。使用AJAX和ASP.NET Core登录

这似乎微不足道,但是否有任何现有的样本或模板登录使用AJAX?我不想重新发明轮子。

我开始使用ASP.NET Core Web Application的默认Visual Studio模板,其中登录是独立页面的本地帐户。它使用引导程序。理想情况下,我想尽可能地贴近这一点。

登录后的动作是这样的:

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Login(LoginFormViewModel model, string returnUrl = null) 
    { 
     ViewData["ReturnUrl"] = returnUrl; 
     if (ModelState.IsValid) 
     { 
      // This doesn't count login failures towards account lockout 
      // To enable password failures to trigger account lockout, set lockoutOnFailure: true 
      var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); 
      if (result.Succeeded) 
      { 
       _logger.LogInformation(1, "User logged in."); 
       return RedirectToLocal(returnUrl); 
      } 
      if (result.IsLockedOut) 
      { 
       _logger.LogWarning(2, "User account locked out."); 
       return View("Lockout"); 
      } 
      else 
      { 
       ModelState.AddModelError(string.Empty, "Invalid login attempt."); 
      } 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

回答

1

这里是一个片段我在基于AJAX的登录,以获得帐户控制代码,您开始:

// GET: /Account/LoginAjax 
[HttpGet] 
[AllowAnonymous] 
[RequireHttps] 
public IActionResult LoginAjax(string returnUrl = null) 
{ 
    if (!_signInManager.IsSignedIn(User)) 
    { 
     if (Request.Cookies["Identity.External"] != null) 
     { 
      // TODO: this is a temp solution, see https://github.com/aspnet/Security/pull/980 
      // http://stackoverflow.com/questions/38751641/app-redirects-to-account-accessdenied-on-adding-oauth 
      // when fixed in Microsoft.AspNetCore.Authentication, remove the whole block 
      Response.Cookies.Delete("Identity.External"); 
     } 
    } 
    return PartialView("_LoginPartial", new LoginViewModel { RememberMe = true, ReturnUrl = returnUrl }); 
} 

// POST: /Account/LoginAjax 
[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
[RequireHttps] 
public async Task<IActionResult> LoginAjax(LoginViewModel model, string returnUrl = null) 
{ 
    returnObject ret = new returnObject(); 
    if (ModelState.IsValid) 
    { 
     // This doesn't count login failures towards account lockout 
     // To enable password failures to trigger account lockout, set lockoutOnFailure: true 
     var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); 
     if (result.Succeeded) 
     { 
      ret.success = true; 
      ret.message = "logged-in"; 
     } 
     else if (result.IsLockedOut) 
     { 
      ModelState.AddModelError(string.Empty, "This account has been locked out, please try again later."); 
     } 
     else 
     { 
      ModelState.AddModelError(string.Empty, "The email address or password supplied are incorrect. Please check your spelling and try again."); 
     } 
    } 
    if (!ret.success) //login was unsuccessful, return model errors 
     ret.message = ModelErorrs(ModelState); 

    return Json(ret); 
} 

public static string ModelErorrs(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) 
{ 
    return string.Join("; ", modelState.Values 
     .SelectMany(x => x.Errors) 
     .Select(x => x.ErrorMessage)); 
} 

public class returnObject 
{ 
    public bool success { get; set; } = false; 
    public string message { get; set; } = ""; 
    public string action { get; set; } = ""; 
} 

_LoginPartial.chtml:

<form id="formLoginAJAX" asp-controller="Account" asp-action="LoginAjax" asp-route-returnurl="@Model.ReturnUrl" method="post"> 
...... 
</form> 

Prototype fot客户端JS:

// dialog form submit handler 
$form.submit(function (event) { 
    event.preventDefault();     
    if (!$form.valid()) 
     return; // form is not valid 

    // submit validated form via Ajax 
    var res = { success: false, message: '' }; 
    $.ajax({ 
     type: 'POST', 
     dataType: 'json', 
     url: $form.attr('action'), 
     xhrFields: { 
      withCredentials: true 
     }, 
     data: $form.serializeObject(), 
     beforeSend: function() { 
      //disable submit button to prevent double-click       
     }, 
     success: function (data) { 
      res = data; 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      res.message = 'Request failed: ' + errorThrown; 
     }, 
     complete: function() { 
      if (res.success) { 
       // all good, user is logged-in 
       // do callbacks if needed 
       // close dialog 
      } else { 
       // no luck, show returned errors (res.message) in the summary (".validation-summary")        
      }       
     } 
    }); 
}); 
+0

而javascript? – Liero

+0

我的JS很复杂,但是我添加了精简版的JS和查看 – Ross

+0

@Liero - “[***你不受理?!! ***](http://knowyourmeme.com/memes/ )“对不起,呃,我的意思是,”任何在这里失踪的东西都会阻止它成为公认的答案?“ – ruffin