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");
}
Related
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.
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; }
}
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; }
}
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; }
}
I have a view with a number of checkboxes in it. I want to be able to pass the values of the checkboxes to the controller, then output a list of the OfficeNames that have been ticked. I am not sure how to pass the values of multiple checkboxes back to the controller, or how to output the OfficeNames based on which boxes have been ticked
View:
<p>
#using (Html.BeginForm())
{
<p>
Start Date: #Html.TextBox("StartDate") <br />
<br />
End Date: #Html.TextBox("EndDate") <br />
<br />
<input type="submit" value="Filter" />
</p>
}
<p>
#foreach (var item in Model.BettingOffices)
{
<label>#Html.DisplayFor(modelItem => item.OfficeName)</label>
<input type="checkbox" name="selectedShops" value="#item.OfficeName">
}
</p>
Controller:
public class DailyReportController : Controller
{
private RiskEntities _db = new RiskEntities();
// GET: /DailyReport/
public ActionResult Index(DateTime? startDate, DateTime? endDate)
{
if (startDate == null || endDate == null)
{
var dailyReportModelBlank = new DailyReportModel();
dailyReportModelBlank.BettingOffices = (from bo in _db.BettingOffices orderby bo.OfficeName select bo ).ToList();
//dailyReportModelBlank.DailyReports.Add(new DailyReport());
return View(dailyReportModelBlank);
}
var endDateToUse = (DateTime) endDate;
endDateToUse = endDateToUse.AddDays(+1);
var dailyReportModel = new DailyReportModel
{
DailyReports = (from dr in _db.DailyReports
where dr.DailyReportDate >= startDate
&& dr.DailyReportDate <= endDateToUse
select dr).ToList(),
BettingOffices = (from bo in _db.BettingOffices select bo).ToList()
};
return View(dailyReportModel);
}
Model:
public class DailyReportModel
{
private List<DailyReport> _dailyReports = new List<DailyReport>();
private List<BettingOffice> _bettingOffices = new List<BettingOffice>();
public List<DailyReport> DailyReports
{
get { return _dailyReports; }
set { _dailyReports = value; }
}
public List<BettingOffice> BettingOffices
{
get { return _bettingOffices; }
set { _bettingOffices = value; }
}
}
BettingOffice Class:
public partial class BettingOffice
{
public int BettingOfficeID { get; set; }
public string OfficeName { get; set; }
public string OfficeCode { get; set; }
public string IpAddress { get; set; }
public Nullable<bool> SupportOnly { get; set; }
public Nullable<int> SisSrNumer { get; set; }
public Nullable<bool> Local { get; set; }
public string Server { get; set; }
}
try this :
<p>
#using (Html.BeginForm())
{
<p>
Start Date: #Html.TextBox("StartDate")
<br />
<br />
End Date: #Html.TextBox("EndDate")
<br />
<br />
<input type="submit" value="Filter" />
</p>
}
</p>
<p>
#foreach (var item in Model.BettingOffices)
{
<label>#Html.DisplayFor(modelItem => item.OfficeName)</label>
<input type="checkbox" name="bettingOfficeIDs" value="#item.BettingOfficeID">
}
</p>
And in your Action you can get the selected office ids in bettingOfficeIDs variable:
public ActionResult YourActionName(int[] bettingOfficeIDs)
Few things that need to change here.
If you want values to be passed to action method they need to be within form not outside
For MVT to 'understand' checkbox values as array (or more complex object) you need to work with their html name attribute.
I will do demonstration application below that should help you understand how it works:
CsHtml: Notice that you need to add value attribute to checkboxes to be able to read their values, checkbox gets true only when checkbox is ticked and value is true, hence the javascript. You can add as many of complex object properties as hidden fields as long as you give them names that match to the object property names in viewModel. In this case I am only passing BettingOfficeID
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$(document).on("click", "[type='checkbox']", function(e) {
if (this.checked) {
$(this).attr("value", "true");
} else {
$(this).attr("value","false");}
});
<p>
#using (Html.BeginForm())
{
<p>
Start Date: #Html.TextBox("StartDate") <br />
<br />
End Date: #Html.TextBox("EndDate") <br />
<br />
</p>
<p>
<input type="checkbox" name="BettingOffices[0].Selected" value="true">
<input type="hidden" name="BettingOffices[0].BettingOfficeID" value="1">
<input type="checkbox" name="BettingOffices[1].Selected" value="false">
<input type="hidden" name="BettingOffices[1].BettingOfficeID" value="2">
<input type="checkbox" name="BettingOffices[2].Selected" value="true">
<input type="hidden" name="BettingOffices[2].BettingOfficeID" value="3">
<input type="checkbox" name="BettingOffices[3].Selected" value="false">
<input type="hidden" name="BettingOffices[3].BettingOfficeID" value="4">
<input type="checkbox" name="BettingOffices[4].Selected" value="true">
<input type="hidden" name="BettingOffices[4].BettingOfficeID" value="5">
</p>
<input type="submit" value="submit"/>
}
Post Action method to add to controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(BettingViewModel viewModel)
{
return null;
}
BettingViewModel: I have added Selected property to BettingOffice class.
public class BettingViewModel
{
public string StartDate { get; set; }
public string EndDate { get; set; }
public List<BettingOffice> BettingOffices { get; set; }
}
public class BettingOffice
{
public bool Selected { get; set; }
public int BettingOfficeID { get; set; }
public string OfficeName { get; set; }
public string OfficeCode { get; set; }
public string IpAddress { get; set; }
public Nullable<bool> SupportOnly { get; set; }
public Nullable<int> SisSrNumer { get; set; }
public Nullable<bool> Local { get; set; }
public string Server { get; set; }
}
Hope this saves you some time.
View:
#using (Html.BeginForm("Createuser", "User", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<div class="form-group">
#Html.LabelFor(m => m.city, new { #class = "col-md-2 control-label" })
</div>
<div class="col-md-10">
<table>
<tr>
<td><input type="checkbox" name="city" value="Pune" id="1" />Pune</td>
<td><input type="checkbox" name="city" value="Banglore" id="2" />Banglore</td>
<td><input type="checkbox" name="city" value="Mumbai" id="3" />Mumbai</td>
</tr>
</table>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Create" />
</div>
</div>
}
[HttpPost]
public ActionResult Createuser(user user, string [] city)
{
var UserInfo = new user
{ Email =user.Email,Password=user.Password,Firstname=user.Firstname };
return View();
}
1. First of all, you are generating checkboxes with same name. So how you will be able to retrieve them on server end separately?
So declare some counter that gets incremented and name checkboxes uniquely.
#foreach (var item in Model.BettingOffices)
{
int counter=1;
var checkboxName = "selectedShops" + counter;
<label>#Html.DisplayFor(modelItem => item.OfficeName)</label>
<input type="checkbox" name="#checkboxName" value="#item.OfficeName">
counter++;
}
2. Now on submission of Form in your controller, get checkboxes as -
//Loop through the request.forms
for (var i = 0; i <= Request.Form.Count; i++)
{
var checkboxValue = Request.Form["selectedShops[" + i + "]"];
// Do whatever you want to with this checkbox value
}
For ticked values, you will probably get True value. Debug the retrieved value to write further code accordingly.
Try the following
your View is:
#foreach (var item in Model.BettingOffices)
{
<label>#Html.DisplayFor(modelItem => item.OfficeName)</label>
<input type="checkbox" name="selectedShops" value="#item.OfficeName">
}
Controller
[HttpPost]
public ActionResult Index(FormCollection collection)
{
if(!string.IsNullOrEmpty(collection["selectedShops"]))
{
string strSelectedShops = collection["selectedShops"];
}
}
Hi you can get the selected checkbox value using the bellow code it seem working fine fore me,
<script>
$(document).ready(function()
{
$("input[type=checkbox]").click(function()
{
var categoryVals = [];
categoryVals.push('');
$('#Category_category :checked').each(function() {
categoryVals.push($(this).val());
});
$.ajax({
type:"POST",
url:"<?php echo $this->createUrl('ads/searchresult'); ?>", //url of the action page
data:{'category': categoryVals},
success : function(response){
//code to do somethng if its success
}
});
}
}
</script>