Why is Model Binding not working in my POST action method? - asp.net-mvc

I have a really wierd issue with MVC.
My models keeps getting submitted empty.
And it's probably really simple, but I just can't find the issue.
My model looks like this:
public class LoginModel
{
public string Username;
public string Password;
}
My controller like this:
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel loginTest)
{
if (loginTest.Username != "x" && loginTest.Password != "y")
{
ModelState.AddModelError("a", "Login failed.");
return View(loginTest);
}
else
{
return RedirectToAction("Home", "Welcome");
}
}
And the view is also very simple, like this.
#model LoginSolution.Models.LoginModel
#{
Layout = null;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
#using (Html.BeginForm("Login", "Home"))
{
<div> <span>Username : </span>
#Html.EditorFor(model => model.Username)
<br />
<span>Password : </span>
#Html.EditorFor(model => model.Password)
<br />
#Html.ValidationSummary()
<br />
<input type="submit" value="Login" name="Login" />
</div>
}
</body>
</html>
This is not a question about security or best practice.
This is just a question regarding why the model keeps returning itself as empty upon submitting.

Your model contains fields, not properties (no getter/setter) so the model binder cannot set the values. Change your model to
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}

Related

Model returning null from a View with multiple models

I have two models, LoginModel and DatabaseModel. Combining them, I have created DatabaseCombinedWithOtherModel. The View, Login.cshtml is Strongly-Typed with the combined model. On running the Login.cshtml, the LoginModel returns null
I have all the necessary get and set methods
Here is the Controller class
namespace ReadingCat.Controllers
{
public class LoginController : Controller
{
private int userid;
// GET: Login
[HttpGet]
public ActionResult Login()
{
return View(new DatabaseCombinedWithOtherModel());
}
[HttpPost]
public ActionResult Login(DatabaseCombinedWithOtherModel model)
{
string realPassword = "";
string paswordFromUser = "";
string query = "SELECT password, userid FROM USERS WHERE username
= '" + model.loginModel.username + "'";
DataSet dataSet = model.databaseModel.selectFunction(query);
if (realPassword == paswordFromUser)
{
userid =
Convert.ToInt32(dataSet.Tables[0].Rows[0].ItemArray[1]);
model.loginModel.userid = userid;
return View("~/Views/Profile/Profile.cshtml",
model.loginModel);
}
else
return View();
}
}
}
Here is the Model:
namespace ReadingCat.Models
{
public class DatabaseCombinedWithOtherModel
{
public DatabaseModel databaseModel { get; set; }
public LoginModel loginModel { get; set; }
}
}
And here is the View:
#model ReadingCat.Models.DatabaseCombinedWithOtherModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
<!-- Main css -->
<link rel="stylesheet" href="~/css/login.css">
</head>
<body>
<div class="login-page">
<div class="form">
<form class="register-form">
</form>
#using (Html.BeginForm("Login", "Login", FormMethod.Post))
{
<form class="login-form">
#Html.TextBox("Username", null, new { placeholder = "Username",
#class = "login.css" })
#Html.ValidationMessageFor(model => model.loginModel.username);
#Html.Password("Password", null, new { placeholder = "Password",
#class = "login.css" })
#Html.ValidationMessageFor(model => model.loginModel.password);
<div class="form-submit">
<button type="submit" value="Submit" class="submit"
id="submit" name="submit">Login</button>
</div>
<p class="message">Not registered? Create an account</p>
</form>
}
</div>
</div>
<img class="coffee-image" src="~/images/coffee.gif" alt="">
It is giving the following error
System.NullReferenceException: 'Object reference not set to an instance
of
an object.'
ReadingCat.Models.DatabaseCombinedWithOtherModel.loginModel.get returned
null.
I think this error about not fully declare DatabaseCombinedWithOtherModelthis model.
Please try this code.
private int userid
DatabaseCombinedWithOtherModel modelobj = new DatabaseCombinedWithOtherModel();
// GET: Login
[HttpGet]
public ActionResult Login()
{
return View(modelobj);
}
And also try this thing that before call the model in view firstly add some
values in objects from controller side pass return View(modelobj);and then call in view side.
Since you are not seting the loginmodel, it will be null Which will throw the exception.
Either initialize the loginModel in the otherModel's constructor or in the Login get action.
Try
namespace ReadingCat.Models
{
public class DatabaseCombinedWithOtherModel
{
public DatabaseModel databaseModel { get; set; }
public LoginModel loginModel { get; set; }
}
public DatabaseCombinedWithOtherModel()
{
loginModel = new LoginModel();
databaseModel = new DatabaseModel();
}
}
or
[HttpGet]
public ActionResult Login()
{
var vm = new DatabaseCombinedWithOtherModel()
vm.loginModel = new LoginModel();
vm.databaseModel = new DatabaseModel();
return View(vm);
}
The mentioned error goes away if #Html.Textbox is replaced with #Html.EditorFor. Then, another error arises with the DatabaseModel. It returns null. So I created a different object of DatabaseModel and worked with that.

ASP.NET Core MVC model binding to list returns empty list in POST method? [duplicate]

I have a really wierd issue with MVC.
My models keeps getting submitted empty.
And it's probably really simple, but I just can't find the issue.
My model looks like this:
public class LoginModel
{
public string Username;
public string Password;
}
My controller like this:
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel loginTest)
{
if (loginTest.Username != "x" && loginTest.Password != "y")
{
ModelState.AddModelError("a", "Login failed.");
return View(loginTest);
}
else
{
return RedirectToAction("Home", "Welcome");
}
}
And the view is also very simple, like this.
#model LoginSolution.Models.LoginModel
#{
Layout = null;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
#using (Html.BeginForm("Login", "Home"))
{
<div> <span>Username : </span>
#Html.EditorFor(model => model.Username)
<br />
<span>Password : </span>
#Html.EditorFor(model => model.Password)
<br />
#Html.ValidationSummary()
<br />
<input type="submit" value="Login" name="Login" />
</div>
}
</body>
</html>
This is not a question about security or best practice.
This is just a question regarding why the model keeps returning itself as empty upon submitting.
Your model contains fields, not properties (no getter/setter) so the model binder cannot set the values. Change your model to
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}

Html.BeginForm() is not returning value to controller [duplicate]

I have a really wierd issue with MVC.
My models keeps getting submitted empty.
And it's probably really simple, but I just can't find the issue.
My model looks like this:
public class LoginModel
{
public string Username;
public string Password;
}
My controller like this:
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel loginTest)
{
if (loginTest.Username != "x" && loginTest.Password != "y")
{
ModelState.AddModelError("a", "Login failed.");
return View(loginTest);
}
else
{
return RedirectToAction("Home", "Welcome");
}
}
And the view is also very simple, like this.
#model LoginSolution.Models.LoginModel
#{
Layout = null;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
#using (Html.BeginForm("Login", "Home"))
{
<div> <span>Username : </span>
#Html.EditorFor(model => model.Username)
<br />
<span>Password : </span>
#Html.EditorFor(model => model.Password)
<br />
#Html.ValidationSummary()
<br />
<input type="submit" value="Login" name="Login" />
</div>
}
</body>
</html>
This is not a question about security or best practice.
This is just a question regarding why the model keeps returning itself as empty upon submitting.
Your model contains fields, not properties (no getter/setter) so the model binder cannot set the values. Change your model to
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}

can we use html tags in asp.net mvc

I want to use following html tags in asp.net mvc,is it possible?
<form action="demo_form.asp">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="Submit">
</form>
You just have to make your view as strong typed view using these code u get able to use this code.I hope this will help u.
C# Controller Code
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(sample b)
{
return View();
}
C# Class Code
public class sample
{
public string fname { get; set; }
public string lname { get; set; }
}
Razor View Code
#model WebApplication1.Models.sample
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
#using (Html.BeginForm("index","Home"))
{
<input type="text" name="fname"><br>
<input type="text" name="lname"><br>
<input type="submit" value="Submit">
}
</body>
</html>
If you do not want to create a Strongly Typed View then you can just do like this.
[HttpPost]
public ActionResult Index(string fname, string lname)
{
return View();
}

ModelState.IsValid only when defining object in action?

I'm just starting off with MVC, so perhaps this is a silly question.
Going over Data Annotations to perform validations, I've noticed that ModelState.IsValid only works when the object is defined in the Action as below, also property names have to match input names:
CustomerController.cs
public ActionResult Submit(Customer obj) <-- here
{
//Customer obj = new Customer();
//obj.CustomerName = Request.Form["CustomerName"];
//obj.CustomerCode = Request.Form["CustomerCode"];
if (ModelState.IsValid)
{
return View("Customer", obj);
}
else
{
return View("EnterCustomer");
}
}
Customer.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace MyFirstWebApp.Models
{
public class Customer
{
[Required]
[StringLength(10)]
public string CustomerName { get; set; }
[Required]
[RegularExpression("^[A-Z]{3,3}[0-9]{4,4}$")]
public string CustomerCode { get; set; }
}
}
EnterCustomer.cshtml
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>EnterCustomer</title>
</head>
<body>
<div>
<form action="Submit" method="post">
Customer Name: <input name="CustomerName" type="text" /> <br />
#Html.ValidationMessageFor(x => x.CustomerName) <br />
Customer Code: <input name="CustomerCode" type="text" /> <br />
#Html.ValidationMessageFor(x => x.CustomerCode) <br />
<input id="Submit1" type="submit" value="submit" />
</form>
</div>
</body>
</html>
But if I define the obj as below, ModelState.IsValid is always true when I enter invalid values to perform validations, can someone tell me why?
CustomerController.cs
public ActionResult Submit()
{
Customer obj = new Customer();
obj.CustomerName = Request.Form["CustomerName"];
obj.CustomerCode = Request.Form["CustomerCode"];
if (ModelState.IsValid)
{
return View("Customer", obj);
}
else
{
return View("EnterCustomer");
}
}
You can use TryValidateModel inside a Controller to validate a model.
Customer obj = new Customer();
obj.CustomerName = Request.Form["CustomerName"];
obj.CustomerCode = Request.Form["CustomerCode"];
if (TryValidateModel(obj))
{
return View("Customer", obj);
}
else
{
return View("EnterCustomer");
}

Resources