Reputation: 21921
I have a function in my controller class, it return a list of data, I want to display it in table structure in my view page. i have tried the following code but it shows some error
"Class does not contain definition of GetEnumerator"
Controller
public ActionResult data(Message msg,IEnumerable<sample> dept)
{
dbconnection db = new dbconnection();
sample s = new sample();
SqlConnection con = new SqlConnection(db.GetconString());
DataTable dt;
List<examplemvc1.Models.sample> datatable = new List<sample>();
dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
datatable.Add(s);
dept = datatable;
}
ViewBag.tabledata = dept;
return View(dept) ;
}
Model
public class sample
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
public string Location { get; set; }
public string tabledata { get; set; }
}
public class Message
{
public IEnumerable<sample> sampleList { get; set; }
public string MessageText { get; set; }
public string MessageFrom { get; set; }
}
View
@model examplemvc1.Models.sample
@foreach (var data in Model)
{
<table><tr><td>@data.FirstName</td></tr></table>
}
UPDATE this is how my entire view looks like
@model List<examplemvc1.Models.sample>
@{
ViewBag.Title = "Registration Form";
}
<head>
<script type="text/javascript" src="../../Scripts/jquery-1.7.1.min.js"></script>
<link href="../../Style/sample.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/samplescript.js" type="text/javascript"></script>
</head>
<h2>
Registration Form </h2>
<body>
<table>
<tr>
<th>
First Name
</th>
</tr>
@foreach (var data in Model)
{
<tr><td>@data.FirstName</td></tr>
}
</table>
@using (Html.BeginForm())
{
<table id="table1">
<tr>
<td>
@Html.Label("Enter FirstName", new { @class = "standard_label_style" })
</td>
<td>
@Html.TextBoxFor(a => a.FirstName, new { @class = "class1", title = "Enter FirstName", id = "NameBox", placeholder = "Enter name", onkeydown = "return TextField(event)" })
<span class="errorMessage"></span>
@if (!ViewData.ModelState.IsValid)
{
<span class="field-validation-error">
@ViewData.ModelState["FirstName"].Errors[0].ErrorMessage</span>
}
</td>
</tr>
<tr>
<td>
@Html.Label("Enter LastName", new { @class = "standard_label_style" })
</td>
<td>
@Html.TextBoxFor(a => a.LastName, new { @class = "class1", placeholder = "Enter name", id = "LastNameBox", title = "Enter Lastname", onkeydown = "return TextField(event); " })
<span class="errorMessage"></span>
</td>
</tr>
<tr>
<td>
@Html.Label("Enter Address", new { @class = "standard_label_style" })
</td>
<td>
@Html.TextBoxFor(a => a.Address, new { @class = "class1", id = "AddressBox", placeholder = "Enter name", title = "Enter Address" })
<span class="errorMessage"></span>
</td>
</tr>
<tr>
<td>
@Html.Label("Enter PhoneNumber", new { @class = "standard_label_style" })
</td>
<td>
@Html.TextBoxFor(a => a.PhoneNumber, new { @class = "class1", id = "PhoneBox", placeholder = "Enter name", title = "Enter Phonenumber", onkeydown = "return ValidateNumber(event);" })
<span class="errorMessage"></span>
</td>
</tr>
<tr>
<td>
@Html.Label("Enter Location", new { @class = "standard_label_style" })
</td><td>
@Html.TextBoxFor(a => a.Location, new { @class = "class1", id = "LocationBox", placeholder = "Enter name", title = "Enter Location" })
<span class="errorMessage"></span>
</td>
</tr>
</table>
<input type="button" id="btnSave" value="Register"/>
<input type="button" value="Clear"/>
<input type="button" id="Tabledata" value="Tabledata"/>
<div id="div1"></div>
@*@Html.ValidationSummary()*@
<script type="text/javascript">
function ValidateNumber(e) {
var evt = (e) ? e : window.event;
var charCode = (evt.keyCode) ? evt.keyCode : evt.which;
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
};
function TextField(e) {
var evt = (e) ? e : window.event;
var charCode = (evt.keyCode) ? evt.keyCode : evt.which;
if (charCode > 31 && (charCode < 48 || charCode > 56)) {
return true;
}
else if (charCode == 8 || charCode == 9) {
return true;
}
return false
};
</script>
}
</body>
Error is shown in my view code, actually I don't know how to get that values in view page. I am newbie in mvc. Please help me to solve this. Any help will be greatly appreciated.
"Update"
I have solved My problem with the help of Stackoverflow Below is my correctcode
Controller
public ActionResult data()
{
SomeViewModel model = new SomeViewModel();
dbconnection db = new dbconnection();
SqlConnection con = new SqlConnection(db.GetconString());
DataTable dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
sample s = new sample();
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
model.samples.Add(s);
}
return View(model);
}
Model
namespace examplemvc1.Models
{
public class sample
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
public string Location { get; set; }
public string tabledata { get; set; }
}
public class Message
{
public IEnumerable<sample> sampleList { get; set; }
public string MessageText { get; set; }
public string MessageFrom { get; set; }
}
public class SomeViewModel
{
public SomeViewModel()
{
samples = new List<sample>();
sample = new sample();
}
public List<sample> samples { get; set; }
public sample sample { get; set; }
}
}
view
@model examplemvc1.Models.SomeViewModel
//................
@foreach (var data in Model.samples)
{
<tr><td>@data.FirstName</td>
<td>@data.LastName</td>
<td>@data.Address</td>
<td>@data.PhoneNumber</td>
<td>@data.Location</td></tr>
}
</table>
Just look at Stephen Muecke's Answer below he has explained the context very clearly
Upvotes: 1
Views: 25597
Reputation:
You view is displaying both a list of sample
and what appears t be a form for a new sample
. Start by creating a view model to represent what you want to display/edit
public class SampleVM
{
public SampleVM
{
SampleCollection = new List<sample>
}
public List<sample> SampleCollection { get; set; }
public sample NewSample { get; set; }
}
In your controller modify the code to
public ActionResult data()
{
SampleVM model = new SampleVM();
dbconnection db = new dbconnection();
SqlConnection con = new SqlConnection(db.GetconString());
DataTable dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
sample s = new sample();
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
model.SampleCollection.Add(s);
}
return View(model);
}
Notes:
sample
inside the foreach
loop
(your code only initialized one object, and each loop updated its
properties to the current row, so you would end up with multiple
reference of the same object, all matching the values of the last
row in your table)ViewBag
property (its
already passed to the view using return View(model);
And modify your view to
@model SampleVM
....
<table>
@foreach(var sample in Model.SampleCollection)
<tr>
<td>@sample .FirstName</td>
</tr>
}
</table>
@Html.BeginForm())
{
@Html.LabelFor(m => m.NewSample.FirstName, "Enter FirstName", new { @class = "standard_label_style" })
@Html.TextBoxFor(m => m.NewSample.FirstName, @class = "class1", placeholder = "Enter name", title = "Enter Lastname")
@Html.ValidationMessageFor(m => m.NewSample.FirstName)
}
....
<input type="submit" id="btnSave" value="Register"/>
Notes:
<label for="Enter_FirstName">
but you dont have a
control with id="Enter_FirstName"
. Preferable you should have
[Display(Name = "Enter FirstName")]
on the property, but otherwise
use the strongly types helper@Html.ValidationMessageFor()
to render ModelState
errors,
although in your case all you properties are strings and you don't
have any validation attributes so there will never be any errors, so
its a bit pointlessid
attribute. There is rarely a need
to overwrite it. Stop polluting your markup with behavior and learn
to use Unobtrusive JavascriptUpvotes: 3
Reputation: 6766
Here problem is with your model directive.
It should be
@model IEnumerable<examplemvc1.Models.sample>
instead of
@model examplemvc1.Models.sample
Note: You are making assignment few times like dept = datatable;
instead you can update the code like this.
public ActionResult data(Message msg,IEnumerable<sample> dept)
{
dbconnection db = new dbconnection();
sample s = new sample();
SqlConnection con = new SqlConnection(db.GetconString());
DataTable dt;
List <examplemvc1.Models.sample> datatable = new List<sample>();
dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
datatable.Add(s);
//dept = datatable;
}
ViewBag.tabledata = datatable;
return View(datatable) ;
}
Update In such a case you need to create viewmodel first and pass his instance there as model.
public class SomeViewModel
{
public SomeViewModel()
{
samples = new List<sample>();
sample = new sample();
}
public List<sample> samples {get; set;}
public sample sample {get; set;}
}
and in model declaration
@model namespace.SomeViewModel
and then in controller like following.
public ActionResult data(Message msg,IEnumerable<sample> dept)
{
dbconnection db = new dbconnection();
sample s = new sample();
SqlConnection con = new SqlConnection(db.GetconString());
DataTable dt;
List<examplemvc1.Models.sample> datatable = new List<sample>();
dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
datatable.Add(s);
dept = datatable;
}
ViewBag.tabledata = dept;
SomeViewModel vm = new SomeViewModel();
vm.samples = datatable;
vm.sample = //somesample instance here you want to edit.
return View(vm) ;
}
and in view you will get the instance of vm iterate through vm.samples
@foreach (var data in Model.samples)
{
<tr><td>@data.FirstName</td></tr>
}
and in the rest of view do something like this:
@Html.TextBoxFor(a => a.sample.FirstName, new { @class = "class1", title =
"Enter FirstName", id = "NameBox", placeholder = "Enter name", onkeydown =
"return TextField(event)" })
Upvotes: 1
Reputation: 62488
Problem is your model is of Type examplemvc1.Models.sample
while you have to pass object of List<examplemvc1.Models.sample>
to view:
return View(datatable) ;
Your action:
List <examplemvc1.Models.sample> datatable = new List<sample>();
dt = db.BuildDT("select * from MVCsample");
foreach (DataRow row in dt.Rows)
{
s.FirstName = Convert.ToString(row["First Name"]);
s.LastName = Convert.ToString(row["Last Name"]);
s.Address = Convert.ToString(row["Address"]);
s.PhoneNumber = Convert.ToString(row["PhoneNumber"]);
s.Location = Convert.ToString(row["Location"]);
datatable.Add(s);
}
return View(datatable); // passing list to view
and in View set model to List<examplemvc1.Models.sample>
:
@model List<examplemvc1.Models.sample>
and now iterate the way you are doing:
<table>
<thead>
<tr><th>First Name</th></tr>
</thead>
<tbody>
@foreach (var data in Model)
{
<tr><td>@data.FirstName</td></tr>
}
</tbody>
</table>
Upvotes: 1