Search code examples
c#asp.net-core-mvcasp.net-identity

ASP.NET Core MVC post form data not bind using identity loginmodel?


I am using ASP.NET Core MVC with identity but I want to perform my own logic on login. So, what I did is I scaffolded the login page and make my own design.

Here is my form:

@page
@model LoginModel

@{
    ViewData["Title"] = "Login";
}

<div class="login-page cnt-bg-photo overview-bgi" style="background-image: 
 url('@Url.Content("~/assets/img/banner-1.jpg")')">
    <div class="container">
        <div class="row">
            <div class="col-lg-12">
                <div class="forgot-box contact-2 clearfix">
                    <div class="login-header clearfix">
                        <div class="pull-left">
                            <h4>Login</h4>
                        </div>
                    </div>
                    <!--                            <div role="alert" 
class="alert alert-danger font-12">
                                                    <strong>Oops!!</strong> Invalid Email or Password
                                                </div>-->

                    <p>Please enter your user name and password to login</p>

                    <form action="/Account/Login" method="POST">
                        <div class="form-group">
                            <label asp-for="Input.Email"></label>
                            <input asp-for="Input.Email" class="form-control" />
                            <span asp-validation-for="Input.Email" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Input.Password"></label>
                            <input asp-for="Input.Password" class="form-control" />
                            <span asp-validation-for="Input.Password" class="text-danger"></span>
                        </div>
                        <div class="form-group w-46-f float-left">
                            <div class="form-check checkbox-theme pull-left">
                                <div class="checkbox">
                                    <label asp-for="Input.RememberMe">
                                        <input asp-for="Input.RememberMe" />
                                        @Html.DisplayNameFor(m => m.Input.RememberMe)
                                    </label>
                                </div>

                            </div>
                        </div>
                        <div class="form-group  float-right">
                            <label class="pull-right forgotpassword-label"><a href="#">Forgot Password ?</a></label>
                        </div>
                        <div class="clearfix"></div>
                        <button type="submit" class="btn btn-color btn-md pull-right">Login</button>
                    </form>

                    <div class="clearfix"></div>

                    <div class="text-center p-t-46 p-b-20 font-14">
                        <span class="txt2">
                            Or Login with
                        </span>
                    </div>
                    <div class="login100-form-social flex-c-m">
                        <form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post">

                            @foreach (var provider in Model.ExternalLogins)
                            {
                                if (provider.DisplayName == "Google")
                                {
                                    <button type="submit" class="btn login100-form-social-item flex-c-m bg3 m-r-5" style="display: inline-block" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account"><i class="fab fa-google"></i></button>
                                }
                                else if (provider.DisplayName == "Facebook")
                                {
                                    <button type="submit" class="btn login100-form-social-item flex-c-m bg1 m-r-5" style="display: inline-block" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account"> <i class="fab fa-facebook-f"></i></button>
                                }
                                else if (provider.DisplayName == "Twitter")
                                {
                                    <button type="submit" class="btn login100-form-social-item flex-c-m bg2 m-r-5" style="display: inline-block" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account"> <i class="fab fa-twitter"></i></button>
                                }

                            }

                        </form>

                    </div>

                    <hr>

                    <div class="text-center forgotpassword-label font-14">

                        Not a member?

                        <a href="@Url.Action("Packages","Account")">
                            <strong>Sign up now</strong>
                        </a>
                    </div>

                </div>

            </div>
        </div>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Now I want to post the login data to my own controller action. But it get null on my action method. Parameters are not filled with actual data of the form.

Here is my controller method:

[HttpPost]
public IActionResult Login(LoginModel.InputModel model)
{
    //My logic
    return View();
}

Why does it get model parameter as null?


Solution

  • Well, specifically, the source of it being null is the fact that in the Razor Page, all the input names begin with Input. because for the code-behind, the model being bound to is LoginModel and the data in those inputs will be bound to the InputModel property (Input) there. However, in your controller, you're binding directly to InputModel, and InputModel has no Input member. As a result, none of the posted inputs match anything and are therefore not bound.

    If you're going to post from a Razor Page, you need to do it to a Razor Page. There's just too many inconsistencies between Razor Pages and MVC to line everything up correctly. If you you want to use a controller, you're going to need a view specifically geared for that, not your Razor Page.