Solved

Posting Table Data To Controller

Posted on 2015-02-03
11
80 Views
Last Modified: 2015-02-04
Really need help;
I have a staging table which gets populated  from a SQL stored procedure which allows the user to edit the fields and then when completed  they press a button to send the data back to be saved into multiple tables,
but when I post back to the controller it doesn't have any data.
This is part of the table
<td style="width:100px;">

            @Html.DisplayFor(modelItem => item.Agent_Name)

            @Html.HiddenFor(modelItem => item.Agent_Name, new { @class = "hiddenField" })

        </td>

        <td class="hide">

            @Html.HiddenFor(modelItem => item.Agent__)

        </td>

        <td style="width:30em;">

            @Html.DisplayFor(modelItem => item.Agent_2_Name)

            @Html.HiddenFor(modelItem => item.Merchant_ID, new { @class = "hiddenField" })

        </td>

        <td class="hide">

            @Html.HiddenFor(modelItem => item.Agent_2__)

        </td>

        <td style="width:30em;">

            @Html.DisplayFor(modelItem => item.Agent_3_Name)

            @Html.HiddenFor(modelItem => item.Agent_3_Name, new { @class = "hiddenField" })

        </td>

        <td class="hide">

            @Html.HiddenFor(modelItem => item.Agent_3__)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.App_Fee)

            @Html.HiddenFor(modelItem => item.App_Fee, new { @class = "hiddenField" })

        </td>

Open in new window


On top of my viewI have
@model My_Report.ViewModels.ConfirmationViewModel

Open in new window


and in the controller I have
 [HttpPost]

        public ActionResult Confirmation(confirmationViewModel records)

        {

             CWACommissionRepository CWA = new CWACommissionRepository();

            foreach (STAGING_TABLE_Details record in records)

            {

                CWA.SaveNewDetails(record);

            }

            return View();

        }

Open in new window


but every time it says records = null

I know I have probably left something very basic out but just can't see it
0
Comment
Question by:Niall292
  • 6
  • 5
11 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 40587499
What is it that you are using to populate your view?
0
 

Author Comment

by:Niall292
ID: 40587661
I am populating it from a linq to entity query then populating the view by a viewmodel. I hope that answers your question
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 40588158
How is your ViewModel defined? What you bind to will usually influence how you define the data to be passed back to the controller.
0
 

Author Comment

by:Niall292
ID: 40588335
Carl, firstly let me thank you for helping to hopefully get this sorted out.

In my view model I have
public class ConfirmationViewModel
    {
       public List<STAGING_TABLE_Details> getConfirmationData { get; set; }   
    }

Open in new window


It gets populated from
 public ActionResult Confirmation()
        {
            CommissionRepository CWA = new CommissionRepository();
            var vm = new ConfirmationViewModel
            {
                getConfirmationData = CWA.GetStagingTable()
            };               
            return View(vm);

Open in new window


and the query populating it looks like
 public List<STAGING_TABLE_Details> GetStagingTable()
        {
            DateTime lastMonth = DateTime.Today.AddMonths(-1);
            List<STAGING_TABLE_Details> info = null;
            using (CWA_MerchantEntities context = getDataContext())
            {
                info = (from s in context.STAGING_TABLE
                        join a in context._AGENT 
                       on s.Agent_Name equals a.Agent_F_Name + " " + a.Agent_L_Name into ps
                        from a in ps.DefaultIfEmpty() 
                        where s.App_Submit___Date > lastMonth
                        select new STAGING_TABLE_Details
                        {                           
                            Agent_Name = s.Agent_Name,
                            Agent__ = a.Agent_ID.ToString(),
                            Agent_2_Name = s.Agent_2_Name,
                            Agent_2__ = a.Agent_ID.ToString(),
                            Agent_3_Name = s.Agent_3_Name,
                            Agent_3__ = a.Agent_ID.ToString(),                           
                            App_Submit___Date = s.App_Submit___Date
                              }).ToList();
       }
            return info;  
    }                      

Open in new window



Again, Thank you for your help
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 40588460
Are you currently populating your view using a foreach loop by any chance?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:Niall292
ID: 40588464
Yes,
foreach (var item in Model.getConfirmationData)
0
 
LVL 52

Accepted Solution

by:
Carl Tawn earned 500 total points
ID: 40588469
In that case, that is very likely to be your problem.  Because you are rendering a nested collection, you need to use a for loop instead as the view needs an index number in order to be able to rebuild the list when it is posted.

Simplified example based on your code below:
    public class ConfirmationViewModel
    {
        public List<STAGING_TABLE_Details> getConfirmationData { get; set; }
    }

    public class STAGING_TABLE_Details
    {
        public string Agent_Name { get; set; }
        public string Agent__ { get; set; }
        public string Agent_2_Name { get; set; }
        public string Agent_2__ { get; set; }
        public string Agent_3_Name { get; set; }
        public string Agent_3__ { get; set; }
        public DateTime App_Submit__Date { get; set; }
    }

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ConfirmationViewModel vm = new ConfirmationViewModel
            {
                getConfirmationData = new List<STAGING_TABLE_Details> 
                {
                    new STAGING_TABLE_Details { Agent__ = "Agent1", Agent_Name = "Agent1Name", Agent_2__ = "Agent2", Agent_2_Name  = "Agent2Name", Agent_3__ ="Agent3", Agent_3_Name="Agent3Name", App_Submit__Date = DateTime.Today }
                }
            };

            return View(vm);
        }

        [HttpPost]
        public ActionResult Index(ConfirmationViewModel model)
        {
            return View();
        }
}

Open in new window

The view:
@model WebApplication1.Controllers.ConfirmationViewModel

@using (Html.BeginForm())
{
    <table>
        @for (var idx = 0; idx < Model.getConfirmationData.Count; ++idx)
        {
            <tr>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent__)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent_Name)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent_2__)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent_2_Name)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent_3__)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].Agent_3_Name)
                </td>
                <td>
                    @Html.EditorFor(m => Model.getConfirmationData[idx].App_Submit__Date)
                </td>
            </tr>
        }
    </table>
    <input type="submit" value="submit" />

Open in new window

0
 

Author Comment

by:Niall292
ID: 40588503
Carl,
Thanks again your answer was correct. Can you help me understand why it made a difference.
0
 

Author Closing Comment

by:Niall292
ID: 40588512
This answer saved my hair, after 2 days of staring at the screen.
Thank you.

I am still not 100% sure why it made such a difference but it did.
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 40588533
The clue is in the output produced by the two versions. If you look at the output from the for loop, you will see something like:
<input class="text-box single-line" id="getConfirmationData_0__Agent__" name="getConfirmationData[0].Agent__" type="text" value="Agent1" />

Open in new window

Whereas the version with a foreach loop will generate something like:
<input class="text-box single-line" id="item_Agent__" name="item.Agent__" type="text" value="Agent1" />

Open in new window

Notice that there is no numeric indexing in the foreach version.

When the data is posted to the server it is sent in the Form object, the controller has no idea that it was in a HTML table. So, without the index numbers in the IDs the server has no way to figure out that it is being sent a collection of items rather than just a single item.
0
 

Author Comment

by:Niall292
ID: 40588536
OH OK,

Thanks for the answer AND the explanation
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Why Does This Page Not Show Up? 4 22
Problem of RegEx to match the first occurence of 10 35
Host asp.net pages 5 25
Replace &lt; with < 14 55
A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource. Example of web.sitemap file: (CODE) Sample code to add to the page menu: (CODE) Running the application, we wi…
Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now