Как проверить форму, не возвращая представление в asp.net? - PullRequest
2 голосов
/ 15 июня 2019

Я сделал выпадающее меню, в котором пользователь может войти в систему с панели навигации вместо нажатия кнопки входа в систему и перенаправления на учетную запись / вход в систему.Это было сделано в частичном представлении и отображается на панели навигации в _layout.cshtml.частичное представление выглядит так:



´´´
@using Microsoft.AspNet.Identity
@model Rent_a_Car.Models.LoginViewModel

@{

    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">


                <div class="dropdown">
                    <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                        @User.Identity.GetUserName()
                    </a>

                    <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
                        @Html.ActionLink("My account", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage", @class = "dropdown-item" })
                        <a class="dropdown-item disabled" href="#">My orders</a>
                        <div class="dropdown-divider"></div>
                        <a class="dropdown-item" href="javascript:document.getElementById('logoutForm').submit()">Log off</a>

                    </div>
                </div>



                <li></li>
            </ul>
        }
    }
    else
    {
        <div class="dropleft">

            <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Log-In </button>
            <div class="dropdown-menu" aria-labelledby="dropdownMenuButton" style="width: 300px">

                @* form starting *@

                @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                    @Html.AntiForgeryToken()

                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })


                    <div class="col-lg-12">
                        <div class="text-center">
                            <h3><b>Log In</b></h3>
                        </div>
                        <form id="ajax-login-form" method="post" role="form" autocomplete="off">
                            <div class="form-group">
                                <label for="username">Username</label>
                                @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @placeholder = "Email" })
                            </div>

                            <div class="form-group">
                                <label for="password">Password</label>
                                @Html.PasswordFor(m => m.Password, new { @class = "form-control", @placeholder = "Password" })
                            </div>

                            <div class="form-group">
                                <div class="col-xs-5">


                                    <input type="submit" name="Login" id="login-submit" tabindex="4" class="form-control btn btn-danger" value="Log In">
                                </div>
                            </div>


                            <div class="col-xs-5" align="Center">
                                @Html.CheckBoxFor(m => m.RememberMe)
                                <label for="remember"> Remember Me</label>
                            </div>


                            <div class="form-group">
                                <div class="row">
                                    <div class="col-lg-12">
                                        <div class="text-center">
                                            <a tabindex="5" class="forgot-password">Forgot Password?</a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </form>
                    </div>

                }
                @*form ending*@

            </div>
        </div>
    }


}


@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

}

´´´

и это контроллер.Как видите, когда проверка не проходит, меня возвращают в модель, чего я не хочу.

 public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            // 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(model.Email, model.Password, model.RememberMe, shouldLockout: false);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View(model);
            }
        }

Мне просто нужно, чтобы сообщения об ошибках проверки появлялись в выпадающем меню, не перенаправляя меня на другую страницу.Как мне этого добиться?

1 Ответ

0 голосов
/ 15 июня 2019

Большой вопрос, который задали другие, заключается в том, почему бы не использовать javascript для вызова API для входа в систему, например, с помощью сообщения ajax

$.post("your api here",
{
    userName: "",
    password: "",
    rememberMe: ""
},function(data, status){
     //show user what ever
});

этот код достаточно прост, но если вы не можете использовать javascript из-за чего-то, что "я бы не знал", у вас будет длинный приведенный ниже код и некоторые реализации на ваших существующих контроллерах

Я объясню вместе

Вам нужно будет добавить ReturnUrl к вашей форме, измените форму входа на эту

@using Microsoft.AspNet.Identity
@model Rent_a_Car.Models.LoginViewModel
@{
if (Request.IsAuthenticated)
{
    using (Html.BeginForm("LogOff", "Account", new { returnUrl = Request.Url.PathAndQuery }, FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {
        @Html.AntiForgeryToken()            
        <ul class="nav navbar-nav navbar-right">
            <div class="dropdown">
                <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    @User.Identity.GetUserName()
                </a>
                <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
                    @Html.ActionLink("My account", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage", @class = "dropdown-item" })
                    <a class="dropdown-item disabled" href="#">My orders</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
                </div>
            </div>
        </ul>
    }
}
else
{
    <div class="dropleft">
        <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Log-In </button>
        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton" style="width: 300px">
            @* form starting *@
            @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
            {
                @Html.AntiForgeryToken()
                <p>@ViewBag.error</p>@*Display the error here*@
                <div class="col-lg-12">
                    <div class="text-center">
                        <h3><b>Log In</b></h3>
                    </div>
                    <form id="ajax-login-form" method="post" role="form" autocomplete="off">
                        <div class="form-group">
                            <label for="username">Username</label>
                            @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @placeholder = "Email" })
                        </div>
                        <div class="form-group">
                            <label for="password">Password</label>
                            @Html.PasswordFor(m => m.Password, new { @class = "form-control", @placeholder = "Password" })
                        </div>
                        <div class="form-group">
                            <div class="col-xs-5">
                                <input type="submit" name="Login" id="login-submit" tabindex="4" class="form-control btn btn-danger" value="Log In">
                            </div>
                        </div>
                        <div class="col-xs-5" align="Center">
                            @Html.CheckBoxFor(m => m.RememberMe)
                            <label for="remember"> Remember Me</label>
                        </div>
                        <div class="form-group">
                            <div class="row">
                                <div class="col-lg-12">
                                    <div class="text-center">
                                        <a tabindex="5" class="forgot-password">Forgot Password?</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            }
            @*form ending*@
        </div>
    </div>
}
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Затем в вашем Account Controller верните перенаправление в представление, в котором находится пользователь, потому что это перенаправление, вам придется поместить вашу модель в TempData, поэтому @Html.ValidationSummary(true, "", new { @class = "text-danger" }) и некоторые другие модели ошибка может не сработать для вас, поэтому вы сами проводите проверку.

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        //here send back the error and the model with validation message to any view
        TempData["LoginModel"] = model;
        TempData["LoginError"] = "Incorrect details";
        return Redirect(returnUrl);
    }
    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            TempData["LoginModel"] = model;
            TempData["LoginError"] = "Invalid login attempt";
            return Redirect(returnUrl);                    
    }
}

Теперь у вас много дел.

Вам нужно перейти на все возможные контроллеры, где пользователь может сначала нажать (я советую всем вашим контроллером) и получить TempData (модель) и ошибку. Например, метод Index вашего CarController может быть таким:

public ActionResult Index(int Id)
{
    LoginViewModel model = (LoginViewModel) TempData["LoginModel"];
    ViewBag.error = TempData["LoginError"];
    //Do other logic
    return View(model);
}
...