ASP NET MVC 5 SeletList DropDownList - asp.net-mvc

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.

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.

how can I pass the context from both the class in the MODEL to one view without this error?

In a MODEL, I have two class - ContentDetails and CompetencyDetails which contains its properties
namespace CompetencyAssessmentServices.ServiceModel
{
public class ContentDetails
{
public int CaseStudyId { get; set; }
public string CaseStudy { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
public bool ReviewStatus { get; set; }
public string SolutionDescription { get; set; }
public int CompetencyID { get; set; }
public string CompetencyName { get; set; }
public List<string> SolutionId { get; set; }
}
public class CompetencyDetails
{
public int CompID { get; set; }
public string CompName { get; set; }
}
}
Controller :
Action CaseStudy is retrieving the list of CompetencyDetails from database which is working fine.
namespace CompetencyAssessment.Controllers
{
public class ContentManagementController : Controller
{
// GET: ContentManagement
IContentManagementRepository repo = new ContentManagementRepository();
[HttpGet]
public ActionResult CaseStudy()
{
List<CompetencyDetails> complst = repo.GetCompetencyDetails();
ViewBag.list = complst;
return View(ViewBag.list);
}
[HttpPost]
public ActionResult CaseStudy(ContentDetails cd)
{
ContentDetails ctd = repo.CaseStudyCreationDetails(cd);
return View();
}
}
}
While loading the View, I am getting below error
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[CompetencyAssessmentServices.ServiceModel.CompetencyDetails]', but this dictionary requires a model item of type 'CompetencyAssessmentServices.ServiceModel.ContentDetails'.
View is
#model CompetencyAssessmentServices.ServiceModel.ContentDetails
#{
ViewBag.Title = "CASE-STUDY Contenet Creation (By SME)";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>CASE-STUDY Contenet Creation (By SME)</title>
</head>
<body>
#using (Html.BeginForm())
{
<h4>ContentDetails</h4>
<hr />
<div class="form-group">
#Html.LabelFor(model => model.CaseStudy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.CaseStudy, new { htmlAttributes = new { #class = "form-control", style = "rows=20,columns=400" } })
#Html.ValidationMessageFor(model => model.CaseStudy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsActive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
Solution 1: #Html.TextBox("Sol1") #Html.DropDownList("CompetencyDetails", new SelectList(ViewBag.list, "CompID", "CompName"), "Select Competency")
Solution 2: #Html.TextBox("Sol2") #Html.DropDownList("CompetencyDetails", new SelectList(ViewBag.list, "CompID", "CompName"), "Select Competency")
Solution 3: #Html.TextBox("Sol3") #Html.DropDownList("CompetencyDetails", new SelectList(ViewBag.list, "CompID", "CompName"), "Select Competency")
Solution 4: #Html.TextBox("Sol4") #Html.DropDownList("CompetencyDetails", new SelectList(ViewBag.list, "CompID", "CompName"), "Select Competency")
<div class="form-group">
#Html.LabelFor(model => model.SolutionId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SolutionId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SolutionId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SolutionDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SolutionDescription, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SolutionDescription, "", 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>
}
</body>
</html>
The reason, I am getting this error because my view contains the reference from both class CompetencyDetails and ContentDetails
Can someone please help on how can I pass the context from both the class in the MODEL without this error ?
PS: This is my first MVC project so would appreciate any various approaches to achieve this
you can create new class having both the model class like example given below
public class Combine
{
public List<ContentDetails> ContentDetailsList { get; set; }
public ContentDetails ContentDetailsData { get; set; }
public List<CompetencyDetails> CompetencyDetailsInfoList { get; set; }
public CompetencyDetails CompetencyDetailsData { get; set; }
}
then in MVC controller
[HttpGet]
public ActionResult CaseStudy()
{
var caseStudy = new SupplierDTO()
{
ContentDetailsList = db.ContentDetails.ToList(),
CompetencyDetailsInfoList = db.CompetencyDetails.ToList(),
};
return View(caseStudy);
}
then MVC View
#model CompetencyAssessmentServices.Models.Combine
<div class="form-group">
#Html.LabelFor(model => model.ContentDetailsData.CaseStudy, htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#Html.EditorFor(model => model.ContentDetailsData.CaseStudy, new { htmlAttributes = new { #class = "form-control"} })
#Html.ValidationMessageFor(model => model.ContentDetailsData .CaseStudy, "", new { #class = "text-danger"})
</div>
</div>

Not able to retain original values after edit in mvc

i m not able to solve one issue that is , there are two files one is uploaded at the form filled up for the first time and the other file will be uploaded when the form willl be edited , but the issue is that, when the first uploaded file is shown in edit and no changes be made, that files gets blank , i used exclude as well but that does not made any effect.
My Controller methods:
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FileDetails fileDetails = db.FileUpload.Find(id);
if (fileDetails == null)
{
return HttpNotFound();
}
return View(fileDetails);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Exclude= "FileBeforeTour,FileBeforeTourName")] FileDetails fileDetails)
{
if (ModelState.IsValid)
{
string uploadedfilename = Path.GetFileName(fileDetails.fileaftertourupload.FileName);
if (!string.IsNullOrEmpty(uploadedfilename))
{
string filenamewithoutextension = Path.GetFileNameWithoutExtension(fileDetails.fileaftertourupload.FileName);
string extension = Path.GetExtension(fileDetails.fileaftertourupload.FileName);
string filename = filenamewithoutextension + DateTime.Now.ToString("yymmssfff") + extension;
fileDetails.FileAfterTourName = filename;
fileDetails.FileAfterTour = "~/Content/Files/" + filename;
filename = Path.Combine(Server.MapPath("~/Content/Files"), filename);
fileDetails.fileaftertourupload.SaveAs(filename);
db.Entry(fileDetails).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetails);
}
My Edit View:
#model OnlineStationaryRegister.Models.FileDetails
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Edit", "File", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FileDetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.FileId)
<div class="form-group">
#Html.LabelFor(model => model.Officername, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Officername, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Officername, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Designation, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Designation, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Designation, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FileBeforeTour, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
View File
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FileAfterTour, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="fileaftertourupload" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<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")
}
My FileDetails model:
namespace OnlineStationaryRegister.Models
{
public class FileDetails
{
[Key]
public int FileId { get; set; }
public string Officername { get; set; }
public string Designation { get; set; }
public string FileBeforeTour { get; set; }
public string FileAfterTour { get; set; }
public string FileBeforeTourName { get; set; }
public string FileAfterTourName { get; set; }
public int status { get; set; } = 1;
[NotMapped]
public HttpPostedFileBase filebeforetourupload { get; set; }
[NotMapped]
public HttpPostedFileBase fileaftertourupload { get; set; }
}
}
It can be solved in many ways. One of the simplest ways as follows:
db.Entry(fileDetails).State = EntityState.Modified;
db.Entry(fileDetails).Property(x => x.FileBeforeTourName).IsModified = false; //<-- Here it is
db.Entry(fileDetails).Property(x => x.FileBeforeTour).IsModified = false; //<-- Here it is
db.SaveChanges();

Only defualt values passed to database

I'm pretty new to programming and I'm strugling with quite simple "Create" controller and view.
In the view user is declaring values, which should be passed to database. Here's the model:
public class Expense
{
public int ExpenseID { get; set; }
[DisplayName("Data")]
[Column(TypeName = "DateTime2")]
public DateTime Date { get; set; }
[DisplayName("Wartość")]
public decimal Amount { get; set; }
[DisplayName("Opis")]
public string Details { get; set; }
[DisplayName("Rodzaj")]
public int CategoryID { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
public string Name { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
}
In the same view I want to include partial view for managing the categories (adding, removing).
To have this working I've implemented ViewModel:
public class ExpenseCreateViewModel
{
public Expense ExpenseCreate { get; set; }
public Category CategoryCreate { get; set; }
}
And here's the code for my View:
#model Wydatki2._0.Models.ExpenseCreateViewModel
#{
ViewBag.Title = "Create";
}
<h2>Dodaj wydatek</h2>
<table class="table">
<tr>
<th>
<div>
#using (Html.BeginForm("CreateExpense", "ExpenseCreate", FormMethod.Post, new { }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ExpenseCreate.CategoryID, "Rodzaj", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CategoryID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ExpenseCreate.CategoryID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ExpenseCreate.Amount, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ExpenseCreate.Amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ExpenseCreate.Amount, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ExpenseCreate.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ExpenseCreate.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ExpenseCreate.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ExpenseCreate.Details, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ExpenseCreate.Details, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ExpenseCreate.Details, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Dodaj" class="btn btn-default" />
</div>
</div>
</div>
}
</div>
</th>
<th>
<div>
<input type="button" id="btn" class="btn btn-default" value="Dodaj/Usuń Kategorię" />
<p class="error">#ViewBag.Warning</p>
</div>
<div id="Create" style="display:none">
#Html.Partial("CreateCategory", Model.CategoryCreate)
</div>
</th>
</tr>
</table>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/toggle")
}
The problem is that when I submit the form only the CategoryID value is passed correctly. The rest of parameters have just default values. The partial view is working well - I'm able to add or remove categories, which then are passed to the main view.
The code for my Controller:
namespace Wydatki2._0.Controllers
{
public class ExpenseCreateController : Controller
{
private WydatkiContext db = new WydatkiContext();
public ActionResult Create(bool? warn = false)
{
ExpenseCreateViewModel model = new ExpenseCreateViewModel()
{
ExpenseCreate = new Expense(),
CategoryCreate = new Category()
};
var query = from b in db.Categories
where b.CategoryID != 1
select b;
if (warn.GetValueOrDefault())
{
ViewBag.Warning = "Nie możesz usunąć tej kategorii.";
}
ViewBag.CategoryID = new SelectList(query, "CategoryID", "Name");
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateExpense([Bind(Include = "ExpenseID,Date,Amount,Details,CategoryID")] Expense expense)
{
if (ModelState.IsValid)
{
db.Expenses.Add(expense);
db.SaveChanges();
return RedirectToAction("Create");
}
var query = from b in db.Categories
where b.CategoryID != 1
select b;
ViewBag.CategoryID = new SelectList(query, "CategoryID", "Name", expense.CategoryID);
return View(expense);
}
public ActionResult CreateCategory()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateCategory([Bind(Include = "CategoryID,Name")] Category category)
{
if (ModelState.IsValid)
{
Category cat = db.Categories.FirstOrDefault(c => c.Name== category.Name);
if (cat != null)
{
if (cat.CategoryID == 1 || cat.CategoryID ==2)
{
return RedirectToAction("Create", new { warn = true });
}
else
{
db.Categories.Remove(cat);
db.SaveChanges();
return RedirectToAction("Create");
}
}
else
{
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Create");
}
}
return View(category);
}
I'm inclined to believe that the problem is caused by the model, which I'm passing to the view, but I really don't know, how to pass it correctly... Anyone could help with this?
You should use
([Bind(Prefix="prefixhere")]Category category)
I assume your prefix should be CategoryCreate for category, which the extension from your model ExpenseCreateViewModel, same for your CreateExpense, your prefix should be ExpenseCreate, this way you tell your controller to expect your input names after this prefix, so it will look for CategoryID and Name in create category action after the prefix you passed.
Something Like this
([Bind(Prefix="CategoryCreate")]Category category)
([Bind(Prefix="ExpenseCreate")]Expense expense)

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