Kevin Garnett
Kevin Garnett

Reputation: 69

the model in view could not bind to the action in the controller in ASP.NET MVC4

I have defined the custom name about the input tag in Index view of Account. The name is iptloginPassWord and iptloginPassWord. However, in the controller the model will be null whenever the submit button is clicked.

I have attached the code below. Is this a model binding issue? Could you guys help to determine what is wrong here?

View:

<div class="rl-modal-body">
    <div class="login-model-body-wrap">
        @using (Html.BeginForm("Logon", "Account", FormMethod.Post, new { id = "loginForm" }))
        {
            <div class="rlf-model-group">
                <div class="ipt-container">
                    <div class="ipt-config ipt-UserName"></div>
                    @*h5提供了required属性,Name的N必须为大写*@
                    @*<input id="iptloginUserName" type="text" name="iptloginUserName" value="" placeholder="请输入用户名" class="ipt ipt-login" required="required" />*@
                    @Html.TextBoxFor(model => model.UserName, new { @id = "iptloginUserName", @Name = "iptloginUserName", @placeholder = "请输入用户名", @class = "ipt ipt-login", @required = "required" })
                </div>
                <p class="rl-p"></p>
            </div>
            <div class="rlf-model-group">
                <div class="ipt-container">
                    <div class="ipt-config ipt-Password"></div>
                    @*<input id="iptloginPassWord" type="password" name="iptloginPassWord" value="" placeholder="请输入密码" class="ipt ipt-login ipt-passwordforJS" required="required" />*@
                    @Html.PasswordFor(model => model.Password, new { @id = "iptloginPassWord", @Name = "iptloginPassWord", @placeholder = "请输入密码", @class = "ipt ipt-login ipt-passwordforJS", @required = "required" })
                </div>
                <p class="rl-p"></p>
            </div>
            <div class="rlf-model-group">
                <label for="AutoLogin">
                    <input id="AutoLogin" type="checkbox" checked="checked" />自动登录
                </label>
            </div>
            <div class="rlf-model-group">
                <p class="rl-p"></p>
                <input id="iptloginsubmit" type="submit" name="Button" value="登录" class="btn-red btn-full" />
            </div>
        }
    </div>
</div>


Controller:

public class AccountController : Controller
{
    //
    // GET: /Account/

    [AllowAnonymous]
    public ActionResult Index()
    {
        return View();
    }

    [AllowAnonymous]
    [HttpPost]
    public ActionResult Logon(User model)
    {
        string username = model.UserName;//this will get null 
        string password = model.Password;//this will also get null
        return View(model);
    }
}

Upvotes: 1

Views: 648

Answers (3)

Sarmin Akter
Sarmin Akter

Reputation: 120

If you want to use custom ids then uncomment the following lines from view

@*<input id="iptloginUserName" type="text" name="iptloginUserName" value="" placeholder="请输入用户名" class="ipt ipt-login" required="required" />*@

@*<input id="iptloginPassWord" type="password" name="iptloginPassWord" value="" placeholder="请输入密码" class="ipt ipt-login ipt-passwordforJS" required="required" />*@

And update method headers

[AllowAnonymous]
[HttpPost]
public ActionResult Logon(User model, string iptloginUserName, string iptloginPassWord)
{
    model.UserName= iptloginUserName;
    model.Password = iptloginPassWord;

    return View(model);
}

Upvotes: 0

nik0lai
nik0lai

Reputation: 2655

Have you tried Custom ModelBinder?

public class MyCustomModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, 
                            ModelBindingContext bindingContext)
    {
        HttpRequestBase request = controllerContext.HttpContext.Request;

        string username = request.Form.Get("iptloginUserName");
        string password = request.Form.Get("iptloginPassWord");

        return new User
                   {
                       UserName = title,
                       Password = password
                   };
    }
} 

You then need to inform the controller action of the new ModelBinder

[HttpPost]
    public ActionResult Index([ModelBinder(typeof(MyCustomModelBinder))] User home)
    {
        //use model here 
        return View();
    }

More information: http://codeproject.com/Articles/605595/ASP-NET-MVC-Custom-Model-Binder

Upvotes: 1

ekad
ekad

Reputation: 14614

When you do this

@Html.TextBoxFor(model => model.UserName)

The id and name attribute of the user name textbox will be set to UserName automatically, and that's what makes the value of model.UserName in the controller post method the same as the value of the user name textbox.

I'm not sure why you change the id and name attribute of the user name textbox to iptloginUserName, but if you remove the id and name attribute from this syntax

@Html.TextBoxFor(model => model.UserName, new { @id = "iptloginUserName", @Name = "iptloginUserName", @placeholder = "请输入用户名", @class = "ipt ipt-login", @required = "required" })

and change it to this

@Html.TextBoxFor(model => model.UserName, new { @placeholder = "请输入用户名", @class = "ipt ipt-login", @required = "required" })

model.UserName won't be null in your controller post method and it will contain the value entered in the user name textbox.

The same thing applies to the password textbox, so change this syntax

@Html.PasswordFor(model => model.Password, new { @id = "iptloginPassWord", @Name = "iptloginPassWord", @placeholder = "请输入密码", @class = "ipt ipt-login ipt-passwordforJS", @required = "required" })

to this

@Html.PasswordFor(model => model.Password, new { @placeholder = "请输入密码", @class = "ipt ipt-login ipt-passwordforJS", @required = "required" })

Upvotes: 3

Related Questions