Arunprasanth K V
Arunprasanth K V

Reputation: 21921

Display List return from a controller to a table in view ASP.NET MVC4

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

Answers (3)

user3559349
user3559349

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:

  1. Remove the parameters from the GET method. Apart from the fact you don't use them so they are pointless, even if you were to try and pass those objects to the method, binding would fail and the collections would be null (and if you were to construct the correct query string to make it work, it would be so long it would almost certainly throw an exception)
  2. You need to initialize a new 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)
  3. There is no need to pass the model as a 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:

  1. A label element if for associating the element with a control. Your usage generates <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
  2. Use @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 pointless
  3. The html helpers generate an id attribute. There is rarely a need to overwrite it. Stop polluting your markup with behavior and learn to use Unobtrusive Javascript
  4. Your form did not contain a submit button

Upvotes: 3

Jenish Rabadiya
Jenish Rabadiya

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

Ehsan Sajjad
Ehsan Sajjad

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

Related Questions