Mvc Partial LogIn Page

时间:2016-05-08 23:19:30

标签: c# asp.net asp.net-mvc razor login

我是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视图。

2 个答案:

答案 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>
相关问题