Bind Checkboxlist to model - asp.net-mvc

I'm working on an app for a cycling team. I have to add riders to a ride. To do this I want the user te select the date of a ride, select a value for the point of this ride an then have a list of the members of the team where the user selects which member participated on the ride.
It works fine until I post the form. when I debug my model in the controler the list of Riders in de model counts 4 riders (which is correct as I have 4 riders in my Db for testing) but the riders are null when I check the list.
Can anyone help me, I dont know what I'm doing wrong.
this are the viewmodels I use:
public class RiderViewModel
{
public string Id { get; set; }
public string FulllName { get; set; }
public bool IsChecked { get; set; }
}
public class RideViewModel
{
public string RideId { get; set; }
[Display(Name = "Datum")]
[DataType(DataType.Date)]
[Required(ErrorMessage = "Datum is verplicht")]
public DateTime Date { get; set; }
[Display(Name = "Aantal punten")]
[Required(ErrorMessage = "Een waarde voor het puntenaantal is verplicht")]
public int Punten { get; set; }
[Display(Name = "Leden")]
public List<RiderViewModel> Riders { get; set; }
}
this is my controler:
//POST Rides/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(RideViewModel model)
{
if (ModelState.IsValid)
{
var db = new ApplicationDbContext();
var riders = new List<ApplicationUser>();
foreach(RiderViewModel r in model.Riders)
{
var user = db.Users.FirstOrDefault(u => u.Id == r.Id);
if(user == null)
{
ModelState.AddModelError(string.Empty, "Er is een Fout opgetreden bij het selecteren van de leden. contacteer de systeembeheerder indien het probleem blijft bestaan");
return View(model);
}
riders.Add(user);
}
var ride = new Ride
{
Date = model.Date,
Punten = model.Punten,
Riders = riders
};
db.Rides.Add(ride);
db.SaveChanges();
return RedirectToAction("Index", "AdminPanel");
}
return View(model);
}
and this is the view:
using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Ride</h4>
<hr />
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Punten, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Punten, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Punten, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("Leden", htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#for (var i = 0; i < Model.Riders.Count(); i++)
{
<div class="col-md-10">
#Html.HiddenFor(model => model.Riders[i])
#Html.CheckBoxFor(model => model.Riders[i].IsChecked)
#Html.LabelFor(model => model.Riders[i].IsChecked, Model.Riders[i].FulllName)
</div>
}
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Thanx a lot.
grtz Jeff

You can use a EditorTemplate for this, just add a new file in the EditorTemplates folder named RiderViewModel :
#model RiderViewModel
<div class="col-md-10">
#Html.HiddenFor(model => model.Id)
#Html.CheckBoxFor(model => model.IsChecked)
#Html.LabelFor(model => model.IsChecked, Model.FulllName)
</div>
Then in the view just call the EditorFor:
#Html.EditorFor(m => m.Riders)

Your usage of
#Html.HiddenFor(model => model.Riders[i])
is creating a hidden input for a complex property which is typeof RiderViewModel. If you inspect the html, it will be something like
<input type="hidden" id="Riders_0_" name="Riders[0]" value="someAssembly.RiderViewModel" />
When you submit, the DefaultModelBinder tries to set model.Riders[0] to the value someAssembly.RiderViewModel which fails and so model.Riders[0] is null
Assuming you want to generate a hidden input for the ID property, change it to
#Html.HiddenFor(model => model.Riders[i].ID)

Related

Can't get a List of objects from a model in Razor CSHTML page

This is my first time posting to Stack Overflow. So forgive me if I am not asking the question properly.
I have created a Razor page (in 4.72) wherein the Employer model has a List of Employee models embedded into the Employer model as well. I have Razor page with the Employer information on top and entries for multiple employees below. When submitting the page to create the employer, and employees, I am passing the Employer model into Action Result . But for some reason the List of Employees doesn't come with the Employer model.
The Employer Model and it's values comes over just fine., but not Employees.
My Razor page:
#model FraudReports.Models.FraudReportEmployer
#{
ViewBag.Title = "CreateEmployee";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.EmployerName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EmployerName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EmployerName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FEIN, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FEIN, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FEIN, "", new { #class = "text-danger" })
</div>
</div>
<!-- More form Employer fields here -->
<!-- Start list of Employees here (Number of Employees could vary, using 5 entries for now. )-->
#{
for (var i = 1; i < 5; i++)
{
<hr />
<div class="form-group">
#Html.LabelFor(model => model.FraudReportEmployees[i].FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FraudReportEmployees[i].FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FraudReportEmployees[i].FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FraudReportEmployees[i].MI, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FraudReportEmployees[i].MI, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FraudReportEmployees[i].MI, "", new { #class = "text-danger" })
</div>
</div>
<!-- More form Employee fields here -->
}
<!-- End list of Employee fields here -->
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
My Action method:
public ActionResult CreateEmployee(FraudReportEmployer fraudReportEmployer)
{
List<FraudReportEmployee> FraudReportEmployees = fraudReportEmployer.FraudReportEmployees;
! There are values in Employer model but not the Employee List inside.
.
.
return View();
}
The Employer Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FraudReports.Models
{
public class FraudReportEmployer
{
public string EmployerName { get; set; }
public string ContactName { get; set; }
public string ContactPhone { get; set; }
public string ContactEmail { get; set; }
....
public List<FraudReportEmployee> FraudReportEmployees { get; set; }
}
}
Employee MOdel:
namespace FraudReports.Models
{
public class FraudReportEmployee
{
public string EmployeeId { get; set; }
public string FirstName { get; set; }
public string MI { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}
The indexing should be started from 0, like
for (var i = 0; i < 5; i++)
When the first element in the collection is missing the MVC can't bind the collection elements properly.

Display name of Identity User who created and last updated record when ID is saved

I must not be searching with the correct phrases. This is a simple concept and I’ve done it in other languages and frameworks with ease.
I’m saving the UserID for the person who created the record and the UserID who last updated the record. Instead of displaying the UserID, I want to display the User.FirstName + ‘ ‘ + User.LastName.
The way I have it currently the LastEditBy and CreateBy is displayed on the page as blank.
Controller: I get the customer model and manually map the model to the customerViewModel then pass it to my partial view.
public ActionResult Edit(int customerId)
{
Customer customer = DbContext.Customers.FirstOrDefault(x => x.CustomerId == customerId);
CustomerViewModel customerViewModel = MapToViewModel(customer);
customerViewModel.UserSelectList = GetUserGroupList();
UserManager<ApplicationUser> _userManager = HttpContext.GetOwinContext().Get<ApplicationUserManager>();
var CreateByUser = _userManager.FindById(customerViewModel.CreateById);
var EditByUser = _userManager.FindById(customerViewModel.LastEditById);
customerViewModel.CreateBy = CreateByUser.FirstName + " " + CreateByUser.LastName;
customerViewModel.LastEditBy = EditByUser.FirstName + " " + EditByUser.LastName;
if (Request.IsAjaxRequest()) {
return PartialView("_CustomerEditPartial", customerViewModel);
}
return View("_CustomerEditPartial", customerViewModel);
}
The CustomerViewModel:
public class CustomerViewModel : DbContext{
public CustomerViewModel(): base("name=CustomerViewModel")
{
}
[Key]
public int CustomerId { get; set; }
[MaxLength(128), ForeignKey("ApplicationUser")]
public string UserId { get; set; }
public SelectList UserSelectList { get; set; }
#region additional Fields
// This overrides default conventions or data annotations
[Required(ErrorMessage = "Please enter your first name.")]
[StringLength(50)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your last name.")]
[StringLength(100)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime CreateDate { get; set; } = DateTime.Now;
public string CreateById { get; set; }
[NotMapped]
public string CreateBy { get; set; }
public string LastEditById { get; set; }
[NotMapped]
public string LastEditBy { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime LastEditDate { get; set; } = DateTime.Now;
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class UserGroupList
{
public string Value { get; set; }
public string Text { get; set; }
}
My partial view page: _CustomerEditPartial.cshtml
#model WOA.ViewModels.CustomerViewModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" daa-dismiss="modal" aria-hidden="True">x</button>
<h4 class="modal-title">Edit Customer</h4>
</div>
#using (Ajax.BeginForm("Edit", "Customers", null, new AjaxOptions { HttpMethod = "Post", OnFailure = "OnFail" }, new { #class = "form-horizontal", role = "form" })) {
<div class="modal-body">
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.CustomerId)
<div class="form-group">
#Html.LabelFor(model => model.UserId, "UserId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.UserId, ViewData.Model.UserSelectList, "Select One", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.UserId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreateDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CreateDate, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreateBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CreateBy, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastEditBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.LastEditBy, new { #readonly = "readonly" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastEditDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.LastEditDate, new { #readonly = "readonly" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save changes" />
</div>
</div>
</div>
<script type="text/javascript">
function OnSuccess() {
alert("success");
}
function OnFail() {
alert("fail");
}
function OnComplete() {
alert("Complete");
}
</script>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I have updated my code, it is working now, however I do not believe it is the proper way to do this.
I believe I should be able to return the additional values I need via Linq on the initial call and not make two more trips to the database for the additional values.
I have not been able to figure out a way to make this work with Linq.
Thank you in advance for your time and effort.

ASP.NET MVC - Null Object in ViewModel on POST

Upon POST of an ActionController I am receiving the great ole' object reference not set to an instance of an object error.
Basically I need the ID of the userRequest to be saved WITH the requestResponse. (Foreign Key here)
Here is the code.
ViewModel:
public class RequestResponseViewModel
{
public Models.Request userRequest { get; set; }
public Models.RequestResponse requestResponse { get; set; }
}
View: In debug here there is value in model.userRequest.ID
#model UserRequests.ViewModels.RequestResponseViewModel
#{
ViewBag.Title = "Create";
}
<h2>Admin Response to Request</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.requestResponse.Response,
htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.requestResponse.Response, new {
#class = "form-control", #rows = 5 })
#Html.ValidationMessageFor(model =>
model.requestResponse.Response, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.userRequest.ID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-2">
#Html.DisplayFor(model => model.userRequest.ID)
#Html.ValidationMessageFor(model => model.userRequest.ID, "", new { #class = "text-danger" })
</div>
#Html.LabelFor(model => model.requestResponse.Author, htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-3">
#Html.EditorFor(model => model.requestResponse.Author, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.requestResponse.Author, "", new { #class = "text-danger" })
</div>
#Html.LabelFor(model => model.requestResponse.CreateDate, htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-3">
<h5>#DateTime.Now</h5>
#Html.ValidationMessageFor(model => model.requestResponse.CreateDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1">
<button type="reset" class="btn btn-default">Cancel</button>
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
<hr />
<h3 class="text-success">Original Request</h3>
<div class="row">
<div class="col-md-10">
<h4>#Html.DisplayFor(model => model.userRequest.Title)</h4>
</div>
</div>
<div class="row">
<div class="col-md-10">
<h4>#Html.DisplayFor(model => model.userRequest.Description)</h4>
</div>
</div>
}
<div>
#Html.ActionLink("Back to Browse", "Browse","Change")
</div>
Get ActionResult:
public ActionResult Create(int id)
{
UserRequestContextDataContext db = new UserRequestContextDataContext();
var request = (from m in db.Requests
where m.ID == id
select new Models.Request()
{
ID = m.ID,
Title = m.Title,
Description = m.Description,
BusinessUnit = m.BusinessUnit,
Author = m.Author,
ModuleName = m.MenuItem,
RequestStatus = 2,
SubmitDate = m.SubmitDate,
Type = m.Type,
UrgencyNum = m.UrgencyLevel
}).FirstOrDefault();
var reqResponse = new Models.RequestResponse();
var viewModel = new RequestResponseViewModel
{
userRequest = request,
requestResponse = reqResponse
};
return View(viewModel);
}
The "viewModel" here has everything I need. It's lost somewhere between the ActionResults..
And Finally the Post ActionResult:
[HttpPost]
public ActionResult Create(RequestResponseViewModel _requestResponseViewModel)
{
try
{
if (ModelState.IsValid)
{
using (UserRequestContextDataContext db = new UserRequestContextDataContext())
{
RequestResponse reqRes = new RequestResponse();
reqRes.Response = _requestResponseViewModel.requestResponse.Response.ToString();
reqRes.RequestID = _requestResponseViewModel.userRequest.ID;
reqRes.Author = _requestResponseViewModel.requestResponse.Author.ToString();
reqRes.CreateDate = DateTime.Now;
db.RequestResponses.InsertOnSubmit(reqRes);
db.SubmitChanges();
}
}
return RedirectToAction("Browse","Change");
}
catch (Exception ex)
{
return View("Error", new HandleErrorInfo(ex, "Change", "Create"));
}
}
Using debug mode the userRequest object is NULL in the view model parameter of the POST method but requestResponse is FINE and populated as should.
Searching on this, it seemed most had issues with the naming convention in the view model but I've made sure there are no discrepancies there.
If there is a more clear way to do this workflow please mention.
#Html.DisplayFor does not create an HTML input element, but a simple string literal (for most types, some exceptions are listed in the docs: https://msdn.microsoft.com/en-us/library/ee407420(v=vs.118).aspx#Anchor_1).
So when you press submit, your browser will not send the ID back to the server because it sends only form data (e.g. data from input, textare, select fields). Using your browsers developer tools (F12) you can examine what is actually send to the server.
You can add a hidden input field using #Html.HiddenFor(model => model.userRequest.ID) or use a custom display template for the ID to automatically add a hidden input field. You could further use UIHint attributes to automatically select a display template. Both approaches are thoroughly documented (e.g. http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm).
Another reason the object could be NULL in the POST is due to forgetting to add the setters { get; set; } in your view model:
public Orders orders; --> missing { get; set; }
public class OrderViewModel
{
public Orders orders { get; set; }
public List<VendorJobTitleView> Jobs { get; set; }
public List<ManagerView> Managers { get; set; }
}

ASP NET MVC 5 SeletList DropDownList

I have some problems with SelectList and DropDownList.
Ich have the two Models (TimeRecord has a navigation-property to Project):
public class Project
{
public int ProjectId { get; set; }
[Required]
public string ProjectName { get; set; }
}
and
public class TimeRecord
{
public int TimeRecordId { get; set; }
public int ProjectId { get; set; }
public string Description { get; set; }
public Project TmRecProject { get; set; }
}
In my Controller in the Create-action method the SelectList is pass by ViewBag to the View (till now all is correct working)
public ActionResult Create()
{
ViewBag.ProjectId = new SelectList(db.Projects, "ProjectId", "ProjectName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TimeRecord timeRecord)
{
if (ModelState.IsValid)
{
db.TimeRecords.Add(timeRecord);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(timeRecord);
}
Here is the View:
#model SelectListDropDownTest.Models.TimeRecord
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TimeRecord</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TmRecProject.ProjectId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProjectId", null, new { #class = "form-control" } )
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
In the Create-View I can select a Project from the DropDownList. My Problem is when I pass the Model "TimeRecord" back to the Controller the Project "TmRecProject" is always null.
What is the best way to solve this Problem?
First of all I am not able to understand how are you able to select value from dropdown list as you have not bind your 'ViewBag.ProjectId' with your drop down list.
Change in your view and your code will start working !!!!
Change:
Bind the drop down list with the model in View.
#Html.DropDownListFor(model => model.TmRecProject.ProjectId, ViewBag.ProjectId as IEnumerable<SelectListItem>, new { #class = "form-control" })
Others are as it is and you will get data on your post method.

ViewModel update failed with error

I am having following ViewModel, and corresponding two models.
I am displaying data from this ViewModel on a view, but when I post data to update, following error occurs
The model item passed into the dictionary is of type 'WebMSM.Models.ComplainDetailsVm', but this dictionary requires a model item of type 'WebMSM.Models.REPAIRING'.
public partial class ComplainDetailsVm
{
public virtual REPAIRING REPAIRINGs { get; set; }
public virtual COMPLAIN COMPLAINs { get; set; }
}
REPAIRING.cs
public partial class REPAIRING
{
[Key]
[DisplayName("JOBSHEET NO")]
public int JOBSHEET_NO { get; set; }
[DisplayName("IN TIME")]
public Nullable<System.DateTime> IN_TIMESTAMP { get; set; }
[DisplayName("CREATE TIME")]
public Nullable<System.DateTime> CREATE_TIMESTAMP { get; set; }
[DisplayName("LAST EDIT TIME")]
public Nullable<System.DateTime> LAST_EDIT_TIMESTAMP { get; set; }
}
COMPLAIN.cs
public partial class COMPLAIN
{
[Key]
[DisplayName("JOBSHEET NO")]
public int JOBSHEET_NO { get; set; }
[Required]
[DisplayName("COMPANY NAME")]
public string COMPANY_NAME { get; set; }
[Required]
[DisplayName("MODEL NAME")]
public string MODEL_NAME { get; set; }
}
CONTROLLER ACTION
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int? id,ComplainDetailsVm model)
{
if (ModelState.IsValid)
{
var r = model.REPAIRINGs;
var c = model.COMPLAINs;
db.Entry(r).State = EntityState.Modified;
db.SaveChanges();
}
return View(model);
}
UPDATE
VIEW
#model WebMSM.Models.ComplainDetailsVm
#{
ViewBag.Title = "EditRepairingComplain";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.REPAIRINGs.JOBSHEET_NO)
#Html.HiddenFor(model => model.COMPLAINs.JOBSHEET_NO)
<div class="form-group">
#Html.LabelFor(model => model.COMPLAINs.COMPANY_NAME,
htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.TextBoxFor(model => model.COMPLAINs.COMPANY_NAME, new { #class = "form-control", #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.COMPLAINs.COMPANY_NAME, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.COMPLAINs.MODEL_NAME, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.TextBoxFor(model => model.COMPLAINs.MODEL_NAME, new { #class = "form-control", #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.COMPLAINs.MODEL_NAME, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.REPAIRINGs.IN_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.REPAIRINGs.IN_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.REPAIRINGs.IN_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.REPAIRINGs.CREATE_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.REPAIRINGs.CREATE_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.REPAIRINGs.CREATE_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.REPAIRINGs.LAST_EDIT_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.REPAIRINGs.LAST_EDIT_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.REPAIRINGs.LAST_EDIT_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-5 col-md-6">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
UPDATE ADDED GET METHOD
// GET: Repairing/Edit/5
public ActionResult Edit(int? id)
{
var vm = new ComplainDetailsVm();
var r = db.REPAIRINGs.Find(id);
var c = db.COMPLAINs.Find(id);
if (r != null)
{
vm.REPAIRINGs = r;
vm.COMPLAINs = c;
}
//ViewData["LIST_ESTIMATE_AMOUNT_OK_FROM_CUSTOMER"] = lstOKNOTOK;
return View("EditRepairingComplain",vm);
}
Thanks.
You can have your Views recognize your ViewModel in two ways: you can have the MVC framework figure that out for you, or you can use strongly typed views
In your case, your view is strongly typed but refers to the wrong object class. This can happen if you copied your view from some other file. You should see the following line on your cshtml file:
#model WebMSM.Models.REPAIRING
replace this with:
#model WebMSM.Models.ComplainDetailsVm
and you should no longer get the error.
Edit:
worth to mention that these lines should be on top of the cshtml file returned by the action methods.

Resources