get additional value from form - asp.net-mvc

my form and controller below. basically I'm trying to obtain the form value mode in the controller, the cmd value is always set but my mode isn't set and i don't know how to obtain the value, can anyone tell me how to get it?
or how to get it using the same method as the cmd string?
Thanks
using (Ajax.BeginForm("AddEditRecord", "Equipment", new AjaxOptions { HttpMethod = "POST",OnSuccess = "onSuccess()", LoadingElementId = "dvLoading" }))
{
#Html.ValidationSummary(true)
<div id="equipmentDialog">
#Html.Hidden("hidMode", Request.QueryString["mode"].ToString())
<fieldset>
<legend>Product</legend>
#if (ViewBag.IsUpdate == true)
{
#Html.HiddenFor(model => model.ID)
}
<div class="editor-label">
#Html.LabelFor(model => model.MachineName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MachineName)
#Html.ValidationMessageFor(model => model.MachineName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AssetNo)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.AssetNo)
#Html.ValidationMessageFor(model => model.AssetNo)
</div>
<p>
#if (ViewBag.IsUpdate == true)
{
<input type="submit" value="Update" id="btnUpdate" name="cmd" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" />
}
else
{
<input type="submit" value="Add" id="btnSave" name="cmd" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" />
}
<input type="button" value="Cancel" id="btncancel" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" />
</p>
</fieldset>
</div>
}
my addedit controller is this
public ActionResult AddEditRecord(tblEquipment Equipment, string cmd, string mode)
{
if (ModelState.IsValid)
{
switch (cmd)
{
case "Add":
try
{
db.tblEquipments.Add(Equipment);
db.SaveChanges();
return RedirectToAction(mode);
}
catch { }
break;
case "Update":
try
{
tblEquipment Item = db.tblEquipments.Where(m => m.ID == Equipment.ID).FirstOrDefault();
if (Item != null)
{
Item.AssetNo = Equipment.AssetNo;
Item.MachineName = Equipment.MachineName;
db.SaveChanges();
}
return RedirectToAction(mode);
}
catch { }
break;
}
}
if (Request.IsAjaxRequest())
{
return PartialView("_AddEdit", Equipment);
}
else
{
return View("AddEdit", Equipment);
}
}

Error is here:
#Html.Hidden("hidMode", Request.QueryString["mode"].ToString())
You give name hidMode to hidden field and expect it as cmd in your controller. So either rename hidden field or rename input parameter in a controller action

Related

ASP .Net MVC: Razor view ignores or skips validation ViewBag

I am trying to have validation for my Search option field, which is inside Index.cshtml :
When I enter name it works fine and displays all matching results inside DetailsBySurname.cshtml :
This is DetailsBySurname.cshtml
This Razor view supposed to show Validation Success or Error messages depending on whats inside the ViewBag, but when it redirects from Controller IActionResult to my Razor View with Error Messages inside ViewBag it skips(i think) the block of code with if statement and goes directly to foreach loop which is supposed to be activated only when there are NO Error messages. Then i get this error:
Here is Code for the Razor view DetailsBySurname.cshtml:
#model IEnumerable<codeRed_Capstone.Models.Employee>
#{
ViewData["Title"] = "DetailsBySurname";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#if (ViewBag.Message != null)
{
<p class="alert-#(ViewBag.Error != null ? "danger" : "success")">#(ViewBag.Message)</p>
if (ViewBag.Error != null)
{
<ul>
#foreach (Exception e in ViewBag.Exception.ValidationExceptions)
{
<li class="alert-danger">#(e.Message)</li>
}
</ul>
}
}
<h1>Details</h1>
<div>
<h4>Employee</h4>
<hr />
#foreach (var item in Model)
{
<dl class="row">
<dt class="col-sm-2">
#Html.DisplayNameFor(item => item.FirstName)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(modelItem => item.FirstName)
</dd>
<dt class="col-sm-2">
#Html.DisplayNameFor(model => item.LastName)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(modelItem => item.LastName)
</dd>
</dl>
}
</div>
This is block of code from Controller for the IAction result DetailsBySurname:
public async Task<IActionResult> DetailsBySurname(string lastName)
{
if (Request.Query.Count > 0)
{
try
{
ValidationException exception = new ValidationException();
lastName = !string.IsNullOrWhiteSpace(lastName) ? lastName.Trim() : null;
using (CompanyContext context = new CompanyContext())
{
if (string.IsNullOrWhiteSpace(lastName))
{
exception.ValidationExceptions.Add(new Exception("Last Name Not Provided"));
}
// Category ID fails parse.
// Common validation points (5) and (5a).
int n;
bool isNumeric = int.TryParse(lastName, out n);
if (isNumeric)
{
exception.ValidationExceptions.Add(new Exception("ID Not Valid string"));
}
else
{
// Category ID exists.
// Common validation point (7).
if (!context.Employees.Any(x => x.LastName == lastName))
{
exception.ValidationExceptions.Add(new Exception("Last Name Does Not Exist"));
}
}
if (exception.ValidationExceptions.Count > 0)
{
throw exception;
}
}
var employees = _context.Employees.Where(m => m.LastName == lastName);
ViewBag.Message = $"Successfully Found {lastName}!";
return View(employees);
}
// Catch ONLY ValidationException here.
catch (ValidationException e)
{
ViewBag.LastName = lastName;
ViewBag.Message = "There exist problem(s) with your submission, see below.";
ViewBag.Exception = e;
ViewBag.Error = true;
return View(e);
}
}
return View();
}
finally here is code for the search field inside Index.cshtml view:
#model IEnumerable<codeRed_Capstone.Models.Employee>
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
</li>
<li class="nav-item dropdown">
<form action="/Employee/Index" method="get">
<lable for="filter"> Show Laid of Staff</lable>
<input type="checkbox" id="filter" name="filter" value="laidoff" />
<input class="btn btn-outline-success my-2 my-sm-0" type="submit" value="Go!" />
</form>
</li>
</ul>
<form action="/Employee/DetailsByEmail" method="get" class="form-inline my-2 my-lg-0">
<input id="email" name="email" data-val="true" data-val-required="Email is required" class="form-control mr-sm-2" type="search" placeholder="Search by Email" aria-label="Search">
<span class="field-validation-valid" data-valmsg-for="email" data-valmsg-replace="true"></span>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
<form action="/Employee/DetailsBySurname" method="get" class="form-inline my-2 my-lg-0">
<input id="lastName" name="lastName" data-val="true" data-val-required="Last Name is required" class="form-control mr-sm-2" type="search" placeholder="Search by Last Name" aria-label="Search">
<span class="field-validation-valid" data-valmsg-for="lastName" data-valmsg-replace="true"></span>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
I watched debugging it works as expected goes all the way till the end, only when it jumps to Razor View it gives me this error that i mentioned above.
I also have Class created to handle all Validation exceptions but its working fine. I'm sure problem is some where here between Controller and Razor view. Or maybe problem somewhere else, i'm new to ASP .Net MVC, any suggestions?
I fixed it with a different validation approach.
For the DetailsBySurname i removed if(ViewBag... and added different if(ViewData... - statement to check if returned result is null then don't run foreach loop). To catch error messages use another if statement #if(!ViewData.ModelState.IsValid) like this:
#model IEnumerable<codeRed_Capstone.Models.Employee>
#{
ViewData["Title"] = "DetailsBySurname";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Details</h1>
<div>
#if (ViewData.ModelState.IsValid)
{
<h4>Employee</h4>
<hr />
#foreach (var item in Model)
{
<dl class="row">
<dt class="col-sm-2">
#Html.DisplayNameFor(item => item.FirstName)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(modelItem => item.FirstName)
</dd>
<dt class="col-sm-2">
#Html.DisplayNameFor(item => item.LastName)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(modelItem => item.LastName)
</dl>
}
}
</div>
<div class="form-row">
<div class="form-group col-md-2">
#if (!ViewData.ModelState.IsValid)
{
<span class="field-validation-error">#ViewData.ModelState["LastName"].Errors[0].ErrorMessage</span>
}
</div>
</div>
Then inside Controller for the IAction result DetailsBySurname I changed validation method to built-in validation which looks something like this:
public async Task<IActionResult> DetailsBySurname(string lastName)
{
lastName = !string.IsNullOrWhiteSpace(lastName) ? lastName.Trim() : null;
if (string.IsNullOrWhiteSpace(lastName))
{
ModelState.AddModelError("LastName", "Last Name not Provided");
//exception.ValidationExceptions.Add(new Exception("Last Name Not Provided"));
}
bool exists;
if (!(exists = _context.Employees.Any(m => m.LastName == lastName)))
{
//return NotFound(new Exception("Email not found"));
ModelState.AddModelError("LastName", "Last Name not found");
}
if (!ModelState.IsValid)
{
return View();
}
else
{
var employee = _context.Employees.Where(m => m.LastName == lastName);
return View(employee);
}
}

Change modal form depending on the button clicked

I have a table showing the information of the users, with an edit button for each one.
I want to show a modal form with the details for the user I want to edit, but I don't know how to get the details from the list, and passing them to the modal as a model.
Here is my View:
#model MyApp.Models.User
#{
ViewBag.Title = "Users";
var roles = new List<string> { "Manager", "Admin" };
var userRoles = (List<string>)ViewData["userRoles"];
}
<h2>#ViewBag.Title</h2>
#if (userRoles.Any(u => roles.Contains(u)))
{
using (Html.BeginForm("Update", "Admin", FormMethod.Post, new { id = "update-form", value = "" }))
{
<div class="modal fade" id="user-editor" >
<div class="modal-header">
<a class="close" data-dismiss="modal"><h3>×</h3></a>
<h3 id="modal-title">Edit User</h3>
</div>
<div class="modal-body">
<div class="form-group">
#Html.Label("Name", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.Label("Age", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Age, new { #class = "form-control" })
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn" data-dismiss="modal">Close</a>
<input type="submit" class="btn btn-primary" value="Save Changes" />
</div>
</div>
}
}
<table class="table-bordered table-hover" id="tbusers">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
#if (userRoles.Any(u => roles.Contains(u)))
{
<th>Edit</th>
}
</tr>
</thead>
<tbody>
#foreach (var u in users)
{
<tr id="#u.Id">
<td>#u.Name</td>
<td>#u.Age</td>
#if (userRoles.Any(u => roles.Contains(u)))
{
<td><a type="button" class="btn edit-btn" href="#user-editor" data-toggle="modal">Edit</a></td>
}
</tr>
}
</tbody>
</table>
I've created a testing sample which will help you understand how can you achieve this.
Index.cshtml which will show a list of employees
#model IEnumerable<MvcApplication1.Models.Employee>
#using MvcApplication1.Models;
<h2>Index</h2>
<table>
#foreach (Employee item in Model)
{
<tr>
<td>#Html.ActionLink(#item.EmployeeName, "Name", new { id = item.ID })</td>
<td>
<button type="button" data-id='#item.ID' class="anchorDetail btn btn-info btn-sm" data-toggle="modal"
data-target="#myModal">
Open Large Modal</button></td>
</tr>
}
</table>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
At the same page, reference the following scripts
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
JQuery AJAX call for getting/setting the data of individual employee from ActionMethod at the same page
<script>
$(document).ready(function () {
var TeamDetailPostBackURL = '/Employee/Details';
$(document).on('click', '.anchorDetail', function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: TeamDetailPostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
debugger;
$('.modal-body').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
$("#closbtn").click(function () {
$('#myModal').modal('hide');
});
});
Now Create a class of Employee(because i'm not using EF)
public class Employee
{
public int ID { get; set; }
public string EmployeeName { get; set; }
}
Create controller named Employee and 2 ActionMethods like these:
public ActionResult Index()
{
return View(emp);//sends a List of employees to Index View
}
public ActionResult Details(int Id)
{
return PartialView("Details",
emp.Where(x=>x.ID==Convert.ToInt32(Id)).FirstOrDefault());
}
I'm returning PartialView because I need to load a page within a page.
Details.cshtml
#model MvcApplication1.Models.Employee
<fieldset>
<legend>Employee</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.ID)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.ID)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.EmployeeName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.EmployeeName)
</div>
</fieldset>
<p>#Html.ActionLink("Back to List", "Index")</p>
When you execute and visit the Index page of Employee, you'll see screen like this:
And the Modal Dialog with results will be shown like this:
Note: You need to add reference of jquery and Bootstrap and you can further design/customize it according to your needs
Hope it helps!

mvc No data in ActionResult method after submit

I have an Index page on which there is a section to write a project name and select from a dropdownlist a project type.
Below that I have a submit button that directs to the ActionResult method Create in the Projects controller.
Code:
[UPDATE]
index.cshtml:
#using reqcoll.ViewModels
#model myViewModel
#{
ViewBag.Title = "ReqColl - project";
}
#* First half *#
#using (Html.BeginForm("CreateProject", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
#RenderTopHalf(Model.modelProject)
</div>
}
#* Second half *#
#using (Html.BeginForm("CreateRequirement", "Projects"))
{
#Html.AntiForgeryToken()
<div class="form-group" id="pnSecondHalf">
#* Requirements list *#
<div class=" col-md-6 col-lg-6 col-sm-12">
#RenderBottomLeftHalf(Model.modelRequirement)
</div>
#* New/Edit requirements panel *#
<div class="col-md-6 col-lg-6 col-sm-12">
#RenderBottomRightHalf(Model.modelRequirement)
</div>
</div>
}
#* ================================================================================= ============= *#
#* Helpers *#
#helper RenderTopHalf(reqcoll.Models.Project project)
{
<div class=" well">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
#Html.LabelFor(model => project.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => project.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => project.projectName)
</div>
</div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row row-spacing">
#Html.LabelFor(model => project.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => project.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
project.projectType), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => project.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
}
#helper RenderBottomLeftHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
<table class="table">
<tr>
<th>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
#Html.DisplayNameFor(model => model.modelProject.Requirements[0].shortDesc)
}
}
else
{
<label class="label label-primary col-sm-12 col-md-6 col-lg-6">No requirements available</label>
}
</th>
<th></th>
</tr>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
foreach (var item in Model.modelProject.Requirements)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.shortDesc)
</td>
<td>
#* buttons here*#
#*#Html.ActionLink("E", "Edit", new { id = item.requirementID }) |
#Html.ActionLink("D", "Delete", new { id = item.requirementID })*#
</td>
</tr>
}
}
}
</table>
</div>
}
#helper RenderBottomRightHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => requirement.shortDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#Html.TextBoxFor(model => requirement.shortDesc, htmlAttributes: new { #class = "RequirementShortDesc" })
#Html.ValidationMessageFor(model => requirement.shortDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.longDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12 RequirementLongDesc">
#Html.EditorFor(model => requirement.longDesc)
#Html.ValidationMessageFor(model => requirement.longDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.priorityCode, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#foreach (var value in Enum.GetValues(requirement.priorityCode.GetType()))
{
<div class="control-label col-sm-5 col-md-5 col-lg-5">
#Html.RadioButtonFor(m => requirement.priorityCode, value)
#Html.Label(value.ToString())
</div>
}
#Html.ValidationMessageFor(model => requirement.priorityCode)
</div>
</div>
<input type="hidden" value="" id="hdRequirementID" />
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnReqCreate" class=" col-sm-12 col-md-6 col-lg-6">
#* submit button here *#
#*#Html.ActionLink("Add", "Add", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
<div id="pnReqEdit" class=" col-sm-12 col-md-6 col-lg-6">
#* submit buttons here *#
#*#Html.ActionLink("Edit", "Edit", "Requirement", new { #class = "btn btn-default btnSize" })
#Html.ActionLink("Delete", "Delete", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
</div>
</div>
}
#section Scripts {
<script>
$(function () {
var pID = $('#hdProjectID').val();
if (pID != null) {
if (pID.length > 0) {
$('#pnEdit').show();
$('#pnCreate').hide();
$('#pnSecondHalf').show();
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
var rID = $('#hdRequirementID').val();
if (rID != null) {
if (rID.length > 0) {
$('#pnReqEdit').show();
$('#pnReqCreate').hide();
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
});
</script>
#Scripts.Render("~/bundles/jqueryval")
}
ViewModel:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project modelProject;
public Requirement modelRequirement;
}
}
Controller:
using System.Web.Mvc;
using reqcoll.Models;
using reqcoll.ViewModels;
namespace reqcoll.Controllers
{
public class ProjectsController : Controller
{
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
var vm = new myViewModel()
{
modelProject = new Project() { projectName = "test", projectType = 1 },
modelRequirement = new Requirement() { requirementID = -1 },
};
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateProject(myViewModel vm)
{
if (vm != null)
{
var ab = Request.Form;
// key 1: __RequestVerificationToken
// key 2: project.projectName
// key 3: project.projectType
if (ModelState.IsValid)
{
Project project = vm.modelProject;
// db.Project.Add(project.Item1);
// db.SaveChanges();
// return RedirectToAction("Index");
}
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
[ORIGINAL]
#using (Html.BeginForm("Create", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => model.Item1.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => model.Item1.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => model.Item1.projectName)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => model.Item1.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => model.Item1.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
0), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => model.Item1.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
</div>
}
ProjectsController:
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
return View(new Tuple<Project, Requirement, Priority>(new Project(), new Requirement(), new Priority()));
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "projectName,projectType")] Project project)
{
if (ModelState.IsValid)
{
db.Project.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
So when the submit button is clicked, the ActionResult Create is called, but the ModelState is not valid and does not have the information enterd by the user.
What am I doing wrong?
Your model is looking like complex object as you are using model.Item1.projectName and model.Item1.projectType, but in action method you are trying to get values directly which is wrong.
[Updated code]
With the new code posted, this quick correction to your model will allow it to bind correctly from your view:
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project project;
public Requirement requirement;
}
}
[Original]
Despite the fact of using a Tuple<> type instead of defining a class that would encapsulate the data to pass to the view. You can still achieve what you want by creating a helper in your view.
#helper RenderMyProject(Project project) {
...
#Html.TextBoxFor(x=> project.projectType)
...
}
Then, you will call this helper
#RenderMyProject(model.Item1)
Whats the difference?
The name of the input will change. Instead of posting [Item1.projectType] Inside the response object to your controller, it will look like [project.projectType] which will be mapped to your project parameter automatically.
Found the problem.
I added {get; set;} in the myViewModel to both the models and then it worked.
so:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project Project { get; set; }
public Requirement Requirement { get; set; }
}
}

Displaying Invalid user name or password using MVC Validation

I am using MVC validation to check if use name and password exit in database or not. ModelState.IsValid is true always even when I did not find any matching user.
if (objModel != null)
{
if (ModelState.IsValid && Membership.ValidateUser(objUsersModel.UserName, objUsersModel.Password))
{
Profile.Initialize(objUsersModel.UserName.Trim(), true);
FormsAuthentication.SetAuthCookie(objUsersModel.UserName, false);
return RedirectToAction("Index", "Home");
}
}
How can I set this to false and set the values for error message in mvc view. Here is my MVC view .
<form role="form">
<div class="form-group">
<label for="exampleInputEmail1">User Name </label>
<i class="fa fa-user"></i>
#Html.TextBoxFor(m => m.UserName, new { maxlength = 50, #class = "form-control" })
#Html.ValidationMessageFor(u => u.UserName)
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<i class="fa fa-lock"></i>
#Html.PasswordFor(m => m.Password, new { maxlength = 50, #class = "form-control" })
#Html.ValidationMessageFor(u => u.Password)
</div>
<div class="form-actions">
<label class="checkbox"> <input type="checkbox" class="uniform" value=""> Remember me</label>
<button type="submit" class="btn btn-danger">Submit</button>
</div>
</form>
You need to add a ModelState error and return the view if the user name and password are not valid
if (!ModelState.IsValid)
{
return View(yourModel);
}
if (!Membership.ValidateUser(objUsersModel.UserName, objUsersModel.Password)
{
ModelState.AddModelError(string.Empty, "The user name or password is incorrect");
return View(yourModel);
}
....
return RedirectToAction("Index", "Home");
and in the view, include
#Html.ValidationSummary(true)
to display the message

Radio button and checkbox values get null on submit in asp.net MVC

Model is list here while clicking on submit button Radio button and checkbox values get null
#foreach (var item in Model)
{
#Html.HiddenFor(m => m[Countid].ActivityType)
<div class=" ">
<div class="clear">
</div>
#Html.Label("Group Name", "Group Name", new { #class = "control-label col-md-2", #style = "font-weight:700" })
<label class="control-label col-md-2"> : #item.PfpActivityGroup.ActivityGroupName</label>
</div>
<div class="">
#Html.Label("Activity Type", "Activity Type", new { #class = "control-label col-md-2", #style = "font-weight:700" })
<label class="control-label col-md-2"> : #item.ActivityType</label>
<div class="clear">
</div>
</div>
if (item.PfpQsnCreationMasters != null)
{
<div class=" ">
<label for="ActivityType" class="field-label">
Question Description
</label>
<label class="control-label col-md-2"> : #item.PfpQsnCreationMasters.SurveyDesc</label>
<div class="clear">
</div>
#Html.HiddenFor(m => m[Countid].PfpQsnCreationMasters.SurveyDesc)
#Html.DropDownList("NoOfOptions", ViewData["NoOfOptions"] as SelectList, new { #class = "hide" })
#Html.DropDownListFor(m => #item.PfpQsnCreationMasters.QuestionType, ViewData["QuestionType"] as SelectList, new { #class = "hide" })
#if (item.Type == "TextBox")
{
<div id="divTextBox">
#Html.TextBoxFor(x => item.txtQsnDesc);
#Html.HiddenFor(x => item.txtQsnDesc)
<div class="clear">
</div>
</div>
}
#if (item.Type == "RedioButton")
{
<div >
#if (item.option1 != null)
{
#Html.RadioButtonFor(x => item.RadioOptionSelected, #item.option1)
<label class="control-label col-md-2"> #item.option1</label>
<div class="clear">
</div>
}
#if (item.option2 != null)
{
#Html.RadioButtonFor(x => item.RadioOptionSelected, #item.option2)
<label class="control-label col-md-2"> #item.option2</label>
<div class="clear">
</div>
}
#if (item.option3 != null)
{
#Html.RadioButtonFor(x => item.RadioOptionSelected, #item.option3)
<label class="control-label col-md-2"> #item.option3</label>
<div class="clear">
</div>
}
#if (item.option4 != null)
{
#Html.RadioButtonFor(x => item.RadioOptionSelected, #item.option4)
<label class="control-label col-md-2"> #item.option4</label>
<div class="clear">
</div>
}
#Html.HiddenFor(x => item.RadioOptionSelected)
</div>
}
#if (item.Type == "CheckBox")
{
<div id="divCheckBox">
#if (item.ListTextBox1 != null)
{
#Html.CheckBoxFor(x => item.IsOption1Selected) <label class="control-label col-md-2"> #item.ListTextBox1</label>
#Html.HiddenFor(x => item.IsOption1Selected)
<div class="clear">
</div>
}
#if (item.ListTextBox2 != null)
{
#Html.CheckBoxFor(x => item.IsOption2Selected) <label class="control-label col-md-2"> #item.ListTextBox2</label>
#Html.HiddenFor(x => item.IsOption2Selected)
<div class="clear">
</div>
}
#if (item.ListTextBox3 != null)
{
#Html.CheckBoxFor(x => item.IsOption3Selected) <label class="control-label col-md-2"> #item.ListTextBox3</label>
#Html.HiddenFor(x => item.IsOption3Selected)
<div class="clear">
</div>
}
#if (item.ListTextBox4 != null)
{
#Html.CheckBoxFor(x => item.IsOption4Selected) <label class="control-label col-md-2"> #item.ListTextBox4</label>
#Html.HiddenFor(x => item.IsOption4Selected)
<div class="clear">
</div>
}
</div>
}
</div>
}
<div class="clear">
</div>
<br />
Countid = Countid + 1;
}
I would ordinarily add this as a comment but I lack the +50 rep
Try putting this on the Model value of the checkbox:
public class mymodel {
[DisplayFormat(ConvertEmptyStringToNull = false)]
public bool mycheckboxvalue { get; set; }
}

Resources