简体   繁体   English

ASP.NET MVC为什么不从视图中调用此post动作?

[英]ASP.NET MVC Why doesn't this post action get called from the view?

In a system that uses Identity framework for authentication, I have the following Model, Controller action, and View respectively to implement a password change feature (I saw many articles for learning how to reset a password, but not how to change a password even though the current one is known): 在使用Identity框架进行身份验证的系统中,我分别使用以下Model,Controller操作和View来实现密码更改功能(我看到很多文章用于学习如何重置密码,但不知道如何更改密码,即使当前的一个是已知的):

Model: 模型:

public class ChangePasswordBindingModel
    {
        [Required]
        [DataType(DataType.Password)]
        public string OldPassword { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
}

Controller action in AccountController.cs : AccountController.cs控制器操作:

[HttpPost]
public async Task<ActionResult> ChangePassword(ChangePasswordBindingModel loginChange)
{

    IdentityResult fffx = await UserManager.ChangePasswordAsync("userId", loginChange.OldPassword, loginChange.NewPassword);
    return View("Index");
}

View for password change form, called ChangePassword.cshtml : 查看密码更改表单,名为ChangePassword.cshtml

@model IdentityDevelopment.Models.ChangePasswordBindingModel
@{ ViewBag.Title = "ChangePassword";}
<h2>Change Password</h2>


@using (Html.BeginForm("ChangePassword","Account", FormMethod.Post))
{
    //@Html.AntiForgeryToken();
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />

    <div class="form-group">
        <label>Current Password</label>
        @Html.PasswordFor(x => x.OldPassword, new { @class = "form-control" })
    </div>

    <div class="form-group">
        <label>New Password</label>
        @Html.PasswordFor(x => x.NewPassword, new { @class = "form-control" })
    </div>


    <div class="form-group">
        <label>Re-enter New Password</label>
        @Html.PasswordFor(x => x.ConfirmPassword, new { @class = "form-control" })
    </div>

    <button class="btn btn-primary" type="submit">Save</button>
}

Why would clicking on the "Save" button on the form not call the post action method? 为什么单击表单上的“保存”按钮而不调用post action方法?

EDIT 1: 编辑1:

I am including the controller method for Login, in where a scenario causes the ChangePassword form to appear. 我包含Login的控制器方法,其中一个场景导致ChangePassword表单出现。 Maybe there is something here that is a problem? 也许这里有什么问题?

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginModel details, string returnUrl)
{
  if (ModelState.IsValid)
    {
       AppUser user = await UserManager.FindAsync(details.Name,
                    details.Password);
        if (user == null)
         {
                    ModelState.AddModelError("", "Invalid name or password.");
          }
      else
       {

    //Check if this is initial login of user, force password change if so
                    PasswordChangeChecker PassCheck = new PasswordChangeChecker();
                    string userId = user.Id.ToString();
                    bool proceed = PassCheck.IsPasswordChangedFromInitial(userId);
                    if (proceed)
                    {
                        ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user,
                                             DefaultAuthenticationTypes.ApplicationCookie);
                        ident.AddClaims(LocationClaimsProvider.GetClaims(ident));
                        ident.AddClaims(ClaimsRoles.CreateRolesFromClaims(ident));
                        AuthManager.SignOut();
                        AuthManager.SignIn(new AuthenticationProperties
                        {
                            IsPersistent = false
                        }, ident);


                        //persist login into db
                        Loginobject login = new Loginobject();
                        login.Username = user.UserName;
                        login.SessionId = HttpContext.Session.SessionID;
                        Session["sessionid"] = HttpContext.Session.SessionID;
                        login.Date = DateTime.Now;
                        SQLLoginrecord sqlLogin = new SQLLoginrecord();
                        sqlLogin.PutOrPostLogin(login);

                        TempData["LoginMsg"] = "Any existing sessions are now deactivated.";

                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return View("ChangePassword", new ChangePasswordBindingModel());
                    }
                }
            }
            ViewBag.returnUrl = returnUrl;
            return View(details);
        }

EDIT 2: 编辑2:

It looks like the cause of the issue is a global custom authorization filter (thanks for the comment stephen.vakil) [AuthorizeSingleLogin] that I have put over the definition of AccountController.cs 看起来这个问题的原因是全局自定义授权过滤器(感谢评论stephen.vakil) [AuthorizeSingleLogin]我已经把它放在了AccountController.cs的定义上

AuthorizeSingleLogin.cs AuthorizeSingleLogin.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace IdentityDevelopment.Infrastructure
{
    public class AuthorizeSingleLogin : AuthorizeAttribute
    {
        private AppIdentityDbContext db = new AppIdentityDbContext();
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool isAuthorized = base.AuthorizeCore(httpContext);

            string user = httpContext.User.Identity.Name;

            string access = httpContext.Session.SessionID;

            if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(access))
            {
                return isAuthorized;
            }

            SQLLoginrecord sqlLogin = new SQLLoginrecord();

            return sqlLogin.IsLoggedIn(user, access);
        }
    }
}

SQLLoginrecord.cs SQLLoginrecord.cs

using IdentityDevelopment.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using static IdentityDevelopment.Models.Loginobject;

namespace IdentityDevelopment.Infrastructure
{
    public class SQLLoginrecord
    {

        private LoginobjectDBContext db = new LoginobjectDBContext();
        private bool PriorSessionActive = false;
        public void PutOrPostLogin(Loginobject login)
        {
            var logins = db.Loginobjects.Where(l => l.Username == login.Username);

            if (logins.Any())
            {
                Loginobject tempLogin = logins.First();
                tempLogin.SessionId = login.SessionId;
                tempLogin.Date = login.Date;
                db.Entry(tempLogin).State = EntityState.Modified;
                PriorSessionActive = true;
            }
            else
            {
                db.Loginobjects.Add(login);
            }
            db.SaveChanges();


        }

        public bool IsLoggedIn(string user, string session)
        {
            var logins = db.Loginobjects.Where(l => l.Username == user && l.SessionId == session);

            if (logins.Any())
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool PriorSessionUpdated()
        {
            return this.PriorSessionActive;
        }


    }

}

Thank you. 谢谢。

Your 您的

<button class="btn btn-primary" type="submit">Save</button>

element needs to be an 元素必须是一个

<input class="btn btn-primary" type="submit" value="Save"/>

element. 元件。

If your action is not being hit on post and it is instead going elsewhere, that would lead me to believe that one of two things is happening: 如果你的行动没有在帖子上被击中,而是转移到其他地方,那将导致我相信发生了两件事之一:

  1. Your routing tables are configured incorrectly 您的路由表配置不正确

  2. You have a global filter (especially a global authorization filter) that is interfering with your intended behavior by intercepting the request and disallowing or overriding it. 您有一个全局过滤器(尤其是全局授权过滤器),它通过拦截请求并禁止或覆盖它来干扰您的预期行为。

Through debugging and trial an error, you should be able to determine the culprit in either case. 通过调试和试错,您应该能够确定任何一种情况的罪魁祸首。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM