簡體   English   中英

登錄的局部視圖不能在控制器中調用名稱不同的操作方法

[英]Partial views for login can not call differently named action methods in controller

我正在構建一個成員的唯一ASP.NET MVC網站,它將為用戶提供多種使用FormsAuthentication登錄的方法。 因此,想法是,通常的用戶名和密碼認證將采用一種形式,對於電子證書認證,將采用另一種形式作為移動電話號碼。

現在,我已經閱讀了很多有關如何在一個視圖中求解多個表單的文檔,並且現在有了一個相當優雅的解決方案,即一個視圖包含兩個包含表單的部分視圖,一個視圖包含兩個模型屬性。 這為驗證提供了一個很好的解決方案,因此在按下相應的提交按鈕時,將分別驗證每個表單,而不是同時驗證兩個表單。

這是代碼:

Login.cshtml:

@model OneMeetingPortal2.Models.ViewModel

@{
    ViewBag.Title = "Login";
}

<div class="container">
    <div class="well">
        <h1>@ViewBag.Title.</h1>
    </div>

@Html.Partial("_LoginUsernamePasswordPartial", Model.UserPass)

@Html.Partial("_LoginMobilePartial", Model.Mobile)

</div>

_LoginUsernamePasswordPartial.cshtml:

@model OneMeetingPortal2.Models.LoginUsernamePasswordModel

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", @role = "form", @id = "_userNameForm" }))
{
    @Html.AntiForgeryToken()
    //Birtingu validation elements er stjórnað með CSS. Sjá .validation-summary-valid í Main.css. Birtist ef villa kemur fram.
    @Html.ValidationSummary("Eftirfarandi villur komu upp:", new { @class = "alert alert-danger col-sm-offset-2 col-sm-10" })

    <div class="form-group">
        @Html.LabelFor(m => m.UserName, new { @class = "control-label col-sm-2" })
        <div class="col-sm-10">
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.UserName)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "control-label col-sm-2" })
        <div class="col-sm-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Password)
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <input type="submit" value="Log in" class="btn btn-default" />
        </div>
    </div>
}

_LoginMobilePartial.cshtml。 請注意,如果將操作名稱參數更改為“ Login ,則會收到有關模棱兩可的操作名稱的錯誤消息:

@model OneMeetingPortal2.Models.LoginMobileModel

@using (Html.BeginForm("LoginM", "Account", FormMethod.Post, new { @class = "form-horizontal", @role = "form", @id = "_GSMForm" }))
{
    @Html.AntiForgeryToken()

    @Html.ValidationSummary("Eftirfarandi villur komu upp:", new { @class= "alert alert-danger col-sm-offset-2 col-sm-10" })

    <div class="form-group">
        @Html.LabelFor(m => m.MobileNumber, new { @class = "control-label col-sm-2" })
        <div class="col-sm-10">
            @Html.TextBoxFor(m => m.MobileNumber, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.MobileNumber)
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <input type="submit" value="Log in" class="btn btn-default" />
        </div>
    </div>
}

這是模型:

 public class ViewModel
    {
        public LoginMobileModel Mobile { get; set; }
        public LoginUsernamePasswordModel UserPass { get; set; }
    }

    public class LoginUsernamePasswordModel
    {
        [Required(ErrorMessage="Ekki má sleppa notandanafni.")]
        [Display(Name = "Notandanafn")]
        [StringLength(50, ErrorMessage = "Notandanafnið má ekki vera lengra en 50 stafir")]
        [MinLength(3, ErrorMessage = "Notandanafnið verður að vera a.m.k. 3 stafir")]
        public string UserName { get; set; }

        [Required(ErrorMessage="Ekki má sleppa lykilorði.")]
        [DataType(DataType.Password)]
        [Display(Name = "Lykilorð")]
        [StringLength(50, ErrorMessage="Lykilorðið má ekki vera lengra en 50 stafir")]
        [MinLength(3, ErrorMessage="Lykilorðið verður að vera a.m.k. 3 stafir")]
        public string Password { get; set; }  
    }

    public class LoginMobileModel
    {
        [Required(ErrorMessage = "Ekki má sleppa símanúmeri.")]
        [Display(Name = "Farsímanúmer")]
        [StringLength(7, ErrorMessage = "Símanúmer má ekki vera lengra en 7 stafir.")]
        [MinLength(7, ErrorMessage = "Símanúmer má ekki vera styttra en 7 stafir.")]
        public string MobileNumber { get; set; }
    }

然后是Controller方法:

        // GET: /Account/Login
        [HttpGet]
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            ViewModel m = new ViewModel();
            m.Mobile = new LoginMobileModel();
            m.UserPass = new LoginUsernamePasswordModel();
            return View(m);
        }

        //
        // POST: /Account/Login

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginUsernamePasswordModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (_accountService.Login(model.UserName, model.Password))
                {
                    string xmlString = _accountService.GetEmployeeDetails(model.UserName);
                    Session.Add("ProfileXml", xmlString);
                    Classes.Profile profile = new Classes.Profile(xmlString);
                    FormsAuthentication.RedirectFromLoginPage(profile.Subject, false);
                }
            }

            // If we got this far, something failed, redisplay form
            ViewModel m = new ViewModel();
            m.UserPass = model;
            m.Mobile = new LoginMobileModel();
            return View(m);
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult LoginM(LoginMobileModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                MobileLoginReturn mlr = _accountService.LoginGSM(model.MobileNumber);
                if(mlr.Error == null)
                {
                    Session.Add("ProfileXml", mlr.EmployeeXmlString);
                    Classes.Profile profile = new Classes.Profile(mlr.EmployeeXmlString);
                    FormsAuthentication.RedirectFromLoginPage(profile.Subject, false);
                }
                else
                {
                    ModelState.AddModelError("", mlr.Error.Message);
                }
            }

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

        }

但是,我得到一個奇怪的行為,該行為似乎僅與登錄頁面有關。 我想有兩種不同的操作方法,分別稱為LoginUserPassLoginMobile但我不能。 如果我這樣命名,這些動作將不會被調用。 有趣的是,當我在身份驗證后在站點的其他地方設置相同的方案時,例如在Home控制器中,一切正常,並且我可以基於部分視圖中的action name參數在控制器中調用不同的action方法,例如,我可以有:

@using (Html.BeginForm("LoginMobile", "Account", FormMethod.Post, new { @class = "form-horizontal", @role = "form", @id = "_GSMForm" }))
{
      [Code omitted]
}

public ActionResult LoginMobile(LoginMobileModel model, string returnUrl){ ... }

在控制器中。

因此,現在,我必須讓部分視圖之一中的第一個參數名稱為Login,這樣才能調用Login操作方法。 控制器中只能有兩種具有該名稱的方法,一種用於get,一種用於post,如果更多,我將得到模棱兩可的方法異常。 因此,目前我面臨這樣一個事實,我必須選擇是否要讓用戶使用手機號碼或用戶名和密碼登錄,因為我無法在登錄頁面上同時使用這兩種方法。 那當然是不可接受的,肯定有辦法兩者兼而有之吧?

我希望有人知道如何解決這個難題。 這與FormsAuthentication有關系嗎?

當我最終弄清楚是FormsAuthentication導致了此行為時,我在這里找到了答案

簡而言之,從web.config刪除<authorization>節點,然后在FilterConfig.cs添加filters.Add(new AuthorizeAttribute()); FilterConfig.cs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM