Model not binding in View MVC - c#

I have the following View
#using LearningMVCDAL
#using LearningMVCDAL.Classes
#model Employee
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Employee</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Gender)
</div>
<div class="editor-field">
#Html.DropDownList("Gender", new List<SelectListItem>{
new SelectListItem { Text="Male", Value="Male"},
new SelectListItem { Text="Female", Value="Female"}},"Select Gender")
#Html.ValidationMessageFor(model => model.Gender)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
<div class="editor-label">
#Html.Label("Department")
</div>
<div class="editor-field">
#Html.DropDownList("Department", (SelectList)ViewBag.Departments,"Select Department")
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and here is my code in the controller for the POST request.
[HttpPost]
public ActionResult Create(Employee employeeform)
{
if (ModelState.IsValid)
{
Employee employee = new Employee();
employee.Name = employeeform.Name;
employee.Gender = employeeform.Gender;
employee.City = employeeform.City;
employee.Department.ID = employeeform.Department.ID;
objEmployeeBusinessLayer.AddEmployee(employee);
List<Department> departments = new List<Department>();
departments = objDepartmentBusinessLayer.Department;
SelectList departmentList = new SelectList(departments, "ID", "Name");
ViewBag.Departments = departmentList;
}
return View();
}
With the above code I am able to get Name, Gender and City but not Department as it is an class object. Please help me to bind the properties to Department Property Also.

Try to add a property in your Employee class for the DropDownList as selected departmentId, like below:
public class Employee{
public int selectedDepartmentId {get;set;}
// Other properties
}
#Html.DropDownList("selectedDepartmentId",(SelectList)ViewBag.Departments,"Select Department",String.Empty)
Or you can change the DropDownList in your view like below:
#Html.DropDownList("Department.DepartmentId" , (SelectList)ViewBag.Departments,"Select Department",String.Empty)

Change to:
#Html.DropDownList("DepartmentId", (SelectList)ViewBag.Departments,"Select Department")
public class Employee
{
...
public string DepartmentId { get; set; } // now binding
public Department Department { get; set; }
}
Because you can not bind the selected value from a drop-down list to the Custom class.
[HttpPost]
public ActionResult Create(Employee employeeform)
{
if (ModelState.IsValid)
{
...
Employee employee = new Employee();
employee.DepartmentID = employeeform.DepartmentId;
...
}
return View();
}

Related

The ViewData item that has the key 'Attribute' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>' [duplicate]

This question already has answers here:
The ViewData item that has the key 'MY KEY' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'
(9 answers)
Closed 7 years ago.
I'm binding Categories and Genders in Dropdownlist. My Model has two attributes Mapped to the columns in other tables :
[Required(ErrorMessage = "Choose your category")]
public string Category { get; set; }
[ForeignKey("Category")]
[NotMapped]
public virtual Category Category_Name { get; set; }
[Required(ErrorMessage = "Choose your category")]
public string Gender { get; set; }
[ForeignKey("Gender")]
[NotMapped]
public virtual Gender Gender_Name { get; set; }
My ProductsController have a method called "Create" which is used for uploading
public ActionResult Create()
{
ViewBag.Category = new SelectList(
db.Categories.ToList(),
"Category_ID",
"Category_Name")
;
ViewBag.Gender = new SelectList(
db.Genders.ToList(),
"Gender_ID",
"Gender_Name"
);
return View();
}
//
// POST: /Products/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Products products)
{
if (products.Image.ContentLength > (2 * 1024 * 1024))
{
ModelState.AddModelError("CustomError", "The Size of the
Image is 2MB");
return View();
}
if (!(products.Image.ContentType == "image/jpeg" ||
products.Image.ContentType == "image/gif"))
{
ModelState.AddModelError("CustomError", "File type allowed :
jpeg and gif");
return View();
}
byte[] data = new byte[products.Image.ContentLength];
products.Image.InputStream.Read(data, 0,
products.Image.ContentLength);
products.Product_Photo = data;
db.Products.Add(products);
db.SaveChanges();
return View(products);
}
The Corresponding View is :
#model eKart.Models.Products
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create", "Products", FormMethod.Post, new { enctype
= "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Products</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Product_Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Product_Name)
#Html.ValidationMessageFor(model => model.Product_Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Product_Quantity)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Product_Quantity)
#Html.ValidationMessageFor(model => model.Product_Quantity)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Product_Price)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Product_Price)
#Html.ValidationMessageFor(model => model.Product_Price)
</div>
<div>
#Html.LabelFor(model=>model.Product_Photo)
</div>
<div>
#Html.TextBoxFor(model=> model.Image, new{type="file"})
#Html.ValidationMessage("CustomError")
</div>
<div class ="editor-label">
#Html.LabelFor(model => model.Category)
</div>
<div class="editor-field">
#Html.DropDownList("Category",
(SelectList)ViewBag.Category,"Choose Category")
#Html.ValidationMessageFor(model=>model.Category)
</div>
<div class ="editor-label">
#Html.LabelFor(model=>model.Gender)
</div>
<div class ="editor-field">
#Html.DropDownList("Gender",(SelectList)ViewBag.Gender,"Choose
Gender")
#Html.ValidationMessageFor(model=>model.Gender)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
When I Submit the form I hit the error at "Category" which is mentioned above.I checked StackOverFlow but didn't find useful information.I really wanna know what's going on and where I'm doing wrong.Thanks in advance your help
Add a new property in your class:
Model:
[Required(ErrorMessage = "Choose your category")]
public string Category { get; set; }
public List<System.Web.Mvc.SelectListItem> CategoryList { get; set; }
Controller:
public ActionResult Create()
{
var model = new Products();
model.CategoryList = db.Categories.Select(x => new SelectListItem
{
Text = x.CategoryName,
Value = x.CategoryName
}).ToList();
return View(model);
}
EDIT: As StephenMuecke said in his comment you need to reassign the values to your CategoryList Property when ModelState is not valid.
[HttpPost]
public ActionResult Create(Product product)
{
if(ModelState.IsValid)
{
// Code here
}
product.CategoryList = db.Categories.Select(x => new SelectListItem
{
Text = x.CategoryName,
Value = x.CategoryName
}).ToList();
return View(product);
}
View:
<div class ="editor-label">
#Html.LabelFor(model => model.Category)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Category, Model.CategoryList, "Choose category")
#Html.ValidationMessageFor(model=>model.Category)
</div>
Do the same in 'Gender'

field is not created or edited

Field is not created or edited in views Create and Edit (C# MVC4 CodeFirst).
The rest of the field with the data types string or integer created and edited properly and correctly.
In Model Requirement:
...
public int RequirementId { get; set; }
//[StringLength(500, MinimumLength = 500)]
public string Definition { get; set; }
public string Rationale { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime CreatedOn { get; set; }
public virtual Users CreatedBy { get; set; }
public virtual Users Responsible { get; set; }
public virtual ICollection<Users> InterestedPersons { get; set; }
public string CurentVersion { get; set; }
public StateEnum State { get; set; }
public PriorityEnum Priority { get; set; }
public StabilityEnum Stability { get; set; }
public TypeEnum Type { get; set; }
public virtual BusinessRule Source { get; set; }
public virtual ICollection<TestCase> TestCase { get; set; }
public string UserPart { get; set; }
...
Controller RequirementController (in method Create):
public ActionResult Create()
{
RequirementViewModel reqVM = new RequirementViewModel();
AutoMapper.Mapper.CreateMap<RequirementViewModel, Requirement>();
reqVM.UserList = new SelectList(db.Users, "UsersId", "Surname");
reqVM.BusinessRuleList = new SelectList(db.BusinessRule, "BusinessRuleId", "Definition");
reqVM.TestCaseList = new SelectList(db.TestCase, "TestCaseId", "Title");
Requirement requirement = AutoMapper.Mapper.Map<RequirementViewModel, Requirement>(reqVM);
return View();
}
//
// POST: /Requirement/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Requirement requirement)
{
try
{
AutoMapper.Mapper.CreateMap<RequirementViewModel, Requirement>();
reqVM.UserList = new SelectList(db.Users, "UsersId", "Surname");
reqVM.BusinessRuleList = new SelectList(db.BusinessRule, "BusinessRuleId", "Definition");
reqVM.TestCaseList = new SelectList(db.TestCase, "TestCaseId", "Title");
Requirement requirement = AutoMapper.Mapper.Map<RequirementViewModel, Requirement>(reqVM);
if (ModelState.IsValid)
{
db.Requirement.Add(requirement);
db.SaveChanges();
return RedirectToAction("Index"); //, new { id = requirement.InterestedPersons }
}
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name after DataException and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View();
}
View Create:
...
#model OpenSoft.AgileAnalytics.EF.Models.Requirement
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Requirement</legend>
#*#Html.EditorForModel()*#
<div class="editor-label">
#Html.LabelFor(model => model.Definition)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Definition)
#Html.ValidationMessageFor(model => model.Definition)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Rationale)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Rationale)
#Html.ValidationMessageFor(model => model.Rationale)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CreatedOn)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CreatedOn)
#Html.ValidationMessageFor(model => model.CreatedOn)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CreatedBy)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CreatedBy, Model.UserList, "-Select-") //error
#Html.ValidationMessageFor(model => model.CreatedBy)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Responsible)
</div>
<div class="editor-field">
#Html.DropDownListFor(model=>model.Responsible, Model.UserList, "-Select-") //error
#Html.ValidationMessageFor(model => model.Responsible)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.InterestedPersons)
</div>
<div class="editor-field">
#Html.ListBoxFor(model=>model.InterestedPersons, Model.UserList) //error
#Html.ValidationMessageFor(model => model.InterestedPersons)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CurentVersion)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CurentVersion)
#Html.ValidationMessageFor(model => model.CurentVersion)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserPart)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserPart)
#Html.ValidationMessageFor(model => model.UserPart)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.State)
</div>
<div class="editor-field">
#*#Html.EnumDropDownList(model => model.StateEnum)*#
#Html.DropDownListFor(m => m.State, new SelectList(Enum.GetValues(typeof(OpenSoft.AgileAnalytics.EF.Models.StateEnum))))
#Html.ValidationMessageFor(model => model.State)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Priority)
</div>
<div class="editor-field">
#Html.DropDownListFor(m => m.Priority, new SelectList(Enum.GetValues(typeof(OpenSoft.AgileAnalytics.EF.Models.PriorityEnum))))
#Html.ValidationMessageFor(model => model.Priority)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Stability)
</div>
<div class="editor-field">
#Html.DropDownListFor(m => m.Stability, new SelectList(Enum.GetValues(typeof(OpenSoft.AgileAnalytics.EF.Models.StabilityEnum))))
#Html.ValidationMessageFor(model => model.Stability)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Type)
</div>
<div class="editor-field">
#Html.DropDownListFor(m => m.Type, new SelectList(Enum.GetValues(typeof(OpenSoft.AgileAnalytics.EF.Models.TypeEnum))))
#Html.ValidationMessageFor(model => model.Type)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Source)
</div>
<div class="editor-field">
#Html.DropDownList("BusinessRuleId", "-Select-")
#Html.ValidationMessageFor(model => model.Source)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TestCase)
</div>
<div class="editor-field">
#Html.DropDownList("TestCaseId", "-Select-")
#Html.ValidationMessageFor(model => model.TestCase)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
...
In the drop-down lists the elements of the right.
Help please with the work with these fields model:)
Your properties CreatedBy, Responsible and InterestedPersons are complex objects. A <select> only posts back a single value (or array of values in the case of multiple). In addition the name of your dropdowns are all UsersId but your model does not contain a property named UsersId so nothing is bound.
Create a view model to represent the data you want to edit.
public class RequirementVM
{
public int RequirementId { get; set; }
public string Definition { get; set; }
.... // other properties of Requirement that you want to edit
[Required]
[Display(Name="Created by")]
public int? CreatedBy { get; set; }
[Required]
public int? Responsible { get; set; }
public int[] InterestedPersons { get; set; }
public SelectList UserList { get; set; }
}
Controller
public ActionResult Create()
{
RequirementVM model = new MyViewModel();
model.UserList = new SelectList(db.Users, "UsersId", "Surname");
return View(model);
}
[HttpPost]
public ActionResult Create(RequirementVM model)
{
...
}
View
#model RequirementVM
....
#Html.LabelFor(model => model.Definition)
#Html.EditorFor(model => model.Definition)
#Html.ValidationMessageFor(model => model.Definition)
... other properties of RequirementVM to edit
#Html.LabelFor(m => m.CreatedBy)
#Html.DropDownListFor(m => m.CreatedBy, Model.UserList, "-Select-")
#Html.ValidationMessageFor(m => m.CreatedBy)
#Html.LabelFor(m => m.Responsible)
#Html.DropDownListFor(m => m.Responsible, Model.UserList, "-Select-")
#Html.ValidationMessageFor(m => m.Responsible)
#Html.LabelFor(m => m.InterestedPersons)
#Html.ListBoxFor(m => m.InterestedPersons, Model.UserList)
#Html.ValidationMessageFor(m => m.InterestedPersons)

Passing model data from view to controller is resulting in an error

I am new to MVC 4.
I am receiving the following error:
Object reference not set to an instance of an object. Line 47:#Html.ActionLink("Back to List", "Index", new { id = Model.RestaurantId })
Here is my view that is causing the error (please see the last couple of lines):
#model OdeToFood.Models.RestaurantReview
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>New Review</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Rating)
#Html.ValidationMessageFor(model => model.Rating)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Body)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Body)
#Html.ValidationMessageFor(model => model.Body)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ReviewerName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ReviewerName)
#Html.ValidationMessageFor(model => model.ReviewerName)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index", new { id = Model.RestaurantId })
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller action that is being called when the Back To List link is clicked:
public ActionResult Index([Bind(Prefix="id")]int restaurantId)
{
var restaurant = _db.Restaurants.Find(restaurantId);
if (restaurant != null) {
return View(restaurant);
}
return HttpNotFound();
}
And here is the RestaurantReview model that is being strongly-typed in the view:
public class RestaurantReview
{
public int Id { get; set; }
public int Rating { get; set; }
public string Body { get; set; }
public string ReviewerName { get; set; }
public int RestaurantId { get; set; }
}
Any help would be muchly appreciated.
Cheers!
In your code you are showing the Create view, and the Index controller. Check if in the Create controller you are passing the Model, or check if it needs model.

What is the proper way to submit data from Parent form with partial view MVC 4?

The Main Controller
public class TestPartialController : Controller
{
//
// GET: /TestPartial/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Main model)
{
HttpContext.Items.Add("MainModel", model);
return View();
}
public ActionResult PartialA()
{
return PartialView();
}
[HttpPost]
public ActionResult PartialA(PartialA a)
{
if (HttpContext.Items["MainModel"] != null)
{
Main model =(Main) HttpContext.Items["MainModel"];
model.PA = a;
}
return PartialView();
}
public ActionResult PartialB()
{
return PartialView();
}
[HttpPost]
public ActionResult PartialB(PartialB b)
{
if (HttpContext.Items["MainModel"] != null)
{
Main model = (Main)HttpContext.Items["MainModel"];
model.PB = b;
}
SubmitDatatoDB();
return PartialView();
}
public void SubmitDatatoDB()
{
if (HttpContext.Items["MainModel"] != null)
{
Main model = (Main)HttpContext.Items["MainModel"];
//SubmitDatatoDB
}
}
}
Models:-
namespace TestingMVC4.Models
{
public class Main
{
public string Main1 { get; set; }
public string Main2 { get; set; }
public virtual PartialA PA { get; set; }
public virtual PartialB PB { get; set; }
}
public class PartialA
{
public string UserName { get; set; }
public string UserID { get; set; }
}
public class PartialB
{
public string UserNameB { get; set; }
public string UserIDB { get; set; }
}
}
View :-
#model TestingMVC4.Models.Main
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Main</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Main1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Main1)
#Html.ValidationMessageFor(model => model.Main1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Main2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Main2)
#Html.ValidationMessageFor(model => model.Main2)
</div>
<div>
#Html.Action("PartialA","TestPartial")
</div>
<div>
#Html.Action("PartialB","TestPartial")
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
#model TestingMVC4.Models.PartialA
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>PartialA</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserID)
#Html.ValidationMessageFor(model => model.UserID)
</div>
</fieldset>
}
Mine Question is if doing like this, the Index of HTTPPOST of main view will fire first. than follow by Partial view A and Partial View B. In this case I need to store the data in HttpContext.Items and call the submit to Database in the last Partial view B.
What I want is fire the Partial view A and B first, and store the data into Main View's model and call the SubmitDatatoDB function in Main View's POST Action.
Figure out 2 method to achieve mine goal
1) Passing the main model to each partial view, sample of partial view :-
#model TestingMVC4.Models.Main
//#model TestingMVC4.Models.PartialA
<fieldset>
<legend>PartialA</legend>
<div class="editor-label">
#Html.LabelFor(model => model.PA.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PA.UserName)
#Html.ValidationMessageFor(model => model.PA.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PA.UserID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PA.UserID)
#Html.ValidationMessageFor(model => model.PA.UserID)
</div>
</fieldset>
disadvantages of this method is the partial view is tight to other view.
2) convert all partial view to become templates helpers :- reference from http://lostechies.com/jimmybogard/2011/09/07/building-forms-for-deep-view-model-graphs-in-asp-net-mvc/
this second method is reuse able because it used it own model binding rather than model from parent, for example :-
#model TestingMVC4.Models.ProductEditModel
#{
ViewBag.Title = "Index";
}
<p>
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
</p>
#Html.EditorFor(m => m.Price)
#model TestingMVC4.Models.PriceEditModel
<p>
#Html.LabelFor(m => m.Currency)
#Html.TextBoxFor(m => m.Currency)
</p>
<p>
#Html.LabelFor(m => m.Value)
#Html.TextBoxFor(m => m.Value)
</p>
You need to change your binds to get PartialModelA to populate MainModel and ensure that Partial View A is posting back to and action on the Main Controller
Something like this:
#using (Html.BeginForm("MainAction", "MainController")) {
<fieldset>
<legend>PartialA</legend>
<div class="editor-label">
#Html.Label("UserName", model.UserName)
</div>
<input type="submit" />
</fieldset>
}
Notice the Action and Controller added to the form and the change of LabelFor to use just Label.

Model not Binding to Action passing Null as value

I don't know why, the Model is not binding to the Create Action:
ViewModel:
public class AddressContactViewModel
{
// Primary properties
public int Id { get; set; }
public string Contact { get; set; }
// Navigation properties
[Display(ResourceType = typeof(HeelpResources), Name = "AddressContactViewModelNameLabel")]
[Required(ErrorMessageResourceName = "ErrorMsgRequiredField", ErrorMessageResourceType = typeof(HeelpResources))]
public int ContactType_Id { get; set; }
public int Address_Id { get; set; }
// ViewModel dropdownlists
public IEnumerable<SelectListItem> ContactTypeList { get; set; }
}
View:
#model Heelp.ViewModels.AddressContactViewModel
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Address_Id)
<fieldset>
<legend>AddressContactViewModel</legend>
<div id="year">
#Html.DisplayNameFor(m => m.ContactType_Id)
#Html.DropDownListFor(m => m.ContactType_Id, Model.ContactTypeList, HeelpResources.AddressContactViewModelContactTypesListDropDownFirstRecord)
#Html.ValidationMessageFor(m => m.ContactType_Id)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Contact)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Contact)
#Html.ValidationMessageFor(m => m.Contact)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Action Post:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ContactCreate(AddressContactViewModel contact)
{
var contactDto = Mapper.Map<AddressContactViewModel, AddressContactDto>(contact);
_addressContactService.Create(contactDto);
return RedirectToAction(MVC.Address.ContactList());
}
EDIT: Get:
public virtual ActionResult ContactCreate(int addressId)
{
var model = new AddressContactViewModel
{
Address_Id = addressId,
ContactTypeList = ContactTypeDropDownList()
};
return View(model);
}
When I submit the Form, I receive "null" in the contact parameter of the ContactCreate action, why is this happening?
Thanks
Unbelievable, I found the problem, the parameter of the action has the same name of a field in the ViewModel, a change of the parameter name and everything works find:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ContactCreate(AddressContactViewModel addressContact) // HERE I CHANGE FROM contact TO addressContact AND THE PROBLEM GET SOLVED
{
var contactDto = Mapper.Map<AddressContactViewModel, AddressContactDto>(addressContact);
_addressContactService.Create(contactDto);
return RedirectToAction(MVC.Address.ContactList(addressContact.Address_Id));
}
I ran into this same problem on my last app. try encompassing the button and the field you want to submit into the same div:
#model Heelp.ViewModels.AddressContactViewModel
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Address_Id)
<fieldset>
<legend>AddressContactViewModel</legend>
<div id="year">
#Html.DisplayNameFor(m => m.ContactType_Id)
#Html.DropDownListFor(m => m.ContactType_Id, Model.ContactTypeList, HeelpResources.AddressContactViewModelContactTypesListDropDownFirstRecord)
#Html.ValidationMessageFor(m => m.ContactType_Id)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Contact)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Contact)
#Html.ValidationMessageFor(m => m.Contact)
<input type="submit" value="Create" />
</div>
</fieldset>
}

Categories

Resources