I am new to C# and MVC so please forgive any naiveness/stupidity. I have seen multiple posts dealing with the error I have and I have tried all the solutions but they dont seem to work in my case. Please guide me to the right way to solve this problem.
Background: I have 2 models tblPrograms and tblReports. I am trying to build a simple form where the user can create a new tblReport. Part of the process of creating a new tblReport is to select one tblProgram from a list.
Code Overview:
Controller:
// GET: /Reports/
public ViewResult New()
{
ProgramListModel progList = new ProgramListModel();
tblReports2 report = new tblReports2();
ExistingReportViewModel ervm = new ExistingReportViewModel(report,progList);
return View(ervm);
}
[HttpPost]
public ActionResult GenerateSQL(ExistingReportViewModel evrm)
{
evrm.Report.ProgramName = evrm.progList.selectedProgram;
return View(evrm);
}
View Model:
public class ExistingReportViewModel
{
public tblReports2 Report { get; set; }
public ProgramListModel progList { get; set; }
//public ExistingReportViewModel() { }
public ExistingReportViewModel(tblReports2 report, ProgramListModel progList)
{
this.Report = report;
this.progList = progList;
}
}
Models:
public class tblReports2
{
[Key]
public string ProgramName { get; set; }
public string ReportDesc { get; set; }
....
}
public class ProgramListModel
{
public SelectList progList;
public string selectedProgram;
public ProgramListModel() {
ReportHelper helper = new ReportHelper();
this.progList = helper.getProgramList();
}
}
Helper Method:
public SelectList getProgramList()
{
var programs = from p in this.DB.tblProgramsSet
select p;
programs = programs.Where(s => s.ProgramType.Equals("RPT"));
SelectList list = new SelectList(programs, "ProgramName", "ProgramDescription");
return list;
}
View:
@model ReportsSetup.Models.ExistingReportViewModel
@{
ViewBag.Title = "New";
}
New
@using (Html.BeginForm("GenerateSQL", "Reports"))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>ExistingReportViewModel</legend>
@Html.DropDownListFor(model=>model.progList.selectedProgram, Model.progList.progList)
<div class="editor-label">
@Html.LabelFor(model => model.Report.ReportDesc)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Report.ReportDesc)
@Html.ValidationMessageFor(model => model.Report.ReportDesc)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Report.Formerly)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Report.Formerly)
@Html.ValidationMessageFor(model => model.Report.Formerly)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Report.ExtendedDesc)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Report.ExtendedDesc)
@Html.ValidationMessageFor(model => model.Report.ExtendedDesc)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Report.ReportCode)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Report.ReportCode)
@Html.ValidationMessageFor(model => model.Report.ReportCode)
</div>
...
<input type="submit" value="Create" />
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Error:
![Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.][1]
http://i.stack.imgur.com/GHJpG.jpg
Attempted Solutions:
Refactored the code to use IEnumerable <tblPrograms> instead of SelectList in ProgramListModel and converting to IEnumerable in View using a function similar to sample below:
public static IEnumerable<SelectListItem> ToSelectListItems(
this IEnumerable<Album> albums, int selectedId)
{
return
albums.OrderBy(album => album.Name)
.Select(album =>
new SelectListItem
{
Selected = (album.ID == selectedId),
Text = album.Name,
Value = album.ID.ToString()
});
}
Refactored the code to use IEnumerable<SelectListItem> instead of SelectList in ProgramListModel
Many Thanks in Advance!!
No, you can't do that:
public ActionResult GenerateSQL(ExistingReportViewModel evrm)
if your ExistingReportViewModel
doesn't have a parameterless constructor. The default model binder doesn't know how to instantiate this class if it doesn't have a default constructor.
So you have 2 possibilities:
Define a parametrless constructor to this class:
public class ExistingReportViewModel
{
public ExistingReportViewModel()
{ }
... some other stuff of course
}
Write a custom model binder
Definitely go for 1. unless you need something very special. If you need something very special then please define it precisely, so that we can help you with 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With