views:

31

answers:

2

Hello Everyone,

i m using asp.net mvc2 and i m submitting a form through ajax using jquery. in this scenario model binding does not work

Here is my View code

<%using (Html.BeginForm("MeetingTodo", "OA", FormMethod.Post, new { id = "TaskForm" }))
  {%><%=Html.Hidden("id",ViewContext.RouteData.Values["id"]) %>
    <div class="container">
    <%foreach (var val in Model.Distinct())
    { %>
            <div class="grdrow" > 
                 <div class="grdrightcaption" style="width:173px;" ><%=val.setupEmployee.EmployeeName%></div>
                 <div class="grdcells" ><%=Html.TextAreaFor(x => val.Todo, new { maxlength = 200, style="width:300px;" })%> <%=Html.HiddenFor(x => val.EmployeeID)%></div>
                <div class="grdcells" style="width:50px;" ><%=Html.CheckBoxFor(x=>val.Required)%></div>

           </div>

        <%}%>
        </div>
        <br />
        <button type="submit" class="button">save</button>                
<%}%>

below is signature of my action method in the controller

public ActionResult MeetingTodo(IEnumerable<int> EmployeeID,IEnumerable<string> Todo, FormCollection collection, int id)

i find no values in EmployeeID and Todo variables when they are expected to contain list of values from the form. i will appreciate any help and suggestions

Edit one

<FORM id=TaskForm method=post action=/OA.mvc/MeetingTodo jQuery1286197019171="1"><DIV id=tablecontainer>
<DIV class=grdcaption>
<H2>Tasks</H2></DIV>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdtopcaption>Participant</DIV>
<DIV style="WIDTH: 303px" class=grdtopcaption>Todo</DIV>
<DIV style="WIDTH: 50px" class=grdtopcaption>Required</DIV></DIV><INPUT id=id value=110 type=hidden name=id> 
<DIV class=container>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdrightcaption>Muhammad Adeel Zahid</DIV>
<DIV class=grdcells><TEXTAREA style="WIDTH: 300px" rows=2 cols=20 name=[0].Todo maxlength="200">Shahzad</TEXTAREA> <INPUT value=19 type=hidden name=[0].EmployeeID></DIV>
<DIV style="WIDTH: 50px" class=grdcells><INPUT value=true type=checkbox name=[0].Required><INPUT value=false type=hidden name=[0].Required></DIV></DIV>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdrightcaption>Abdul Samad</DIV>
<DIV class=grdcells><TEXTAREA style="WIDTH: 300px" rows=2 cols=20 name=[1].Todo maxlength="200">Syed</TEXTAREA> <INPUT value=21 type=hidden name=[1].EmployeeID></DIV>
<DIV style="WIDTH: 50px" class=grdcells><INPUT value=true CHECKED type=checkbox name=[1].Required><INPUT value=false type=hidden name=[1].Required></DIV></DIV>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdrightcaption>M. Kafayat Ullah</DIV>
<DIV class=grdcells><TEXTAREA style="WIDTH: 300px" rows=2 cols=20 name=[2].Todo maxlength="200"> Mansoor</TEXTAREA> <INPUT value=23 type=hidden name=[2].EmployeeID></DIV>
<DIV style="WIDTH: 50px" class=grdcells><INPUT value=true type=checkbox name=[2].Required><INPUT value=false type=hidden name=[2].Required></DIV></DIV>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdrightcaption>Muhammad Shahzad</DIV>
<DIV class=grdcells><TEXTAREA style="WIDTH: 300px" rows=2 cols=20 name=[3].Todo maxlength="200"> Alioor</TEXTAREA> <INPUT value=26 type=hidden name=[3].EmployeeID></DIV>
<DIV style="WIDTH: 50px" class=grdcells><INPUT value=true type=checkbox name=[3].Required><INPUT value=false type=hidden name=[3].Required></DIV></DIV>
<DIV class=grdrow>
<DIV style="WIDTH: 173px" class=grdrightcaption>Syed Mansoor Ali</DIV>
<DIV class=grdcells><TEXTAREA style="WIDTH: 300px" rows=2 cols=20 name=[4].Todo maxlength="200"> Ali</TEXTAREA> <INPUT value=27 type=hidden name=[4].EmployeeID></DIV>
<DIV style="WIDTH: 50px" class=grdcells><INPUT value=true type=checkbox name=[4].Required><INPUT value=false type=hidden name=[4].Required></DIV></DIV></DIV><BR><BUTTON aria-disabled=false class="button ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role=button type=submit jQuery1286197019171="10"><SPAN class=ui-button-text>save</SPAN></BUTTON> </DIV></FORM>

and my method signature is like

public ActionResult MeetingTodo(IEnumerable<int> EmployeeID,IEnumerable<string> Todo, FormCollection collection, int id)
A: 

I believe the reason you're not getting the correct values is because you're using Html.TextAreaFor the wrong way. The x in your code points to your Page.Model attribute while your val is not related to that attribute in a way that ASP.NET MVC2 can understand.

You could change your code to look something like this:

<%using (Html.BeginForm("MeetingTodo", "OA", FormMethod.Post, new { id = "TaskForm" }))
{%><%=Html.Hidden("id",ViewContext.RouteData.Values["id"]) %>
<div class="container">
var ix = 0;
<%foreach (var val in Model.Distinct())
{ %>
    <div class="grdrow" > 
        <div class="grdrightcaption" style="width:173px;" ><%=val.setupEmployee.EmployeeName%></div>
        <div class="grdcells" ><%=Html.TextArea(String.Format("employee[{0}].Todo", ix), val.Todo, new { maxlength = 200, style="width:300px;" })%>
            <%=Html.Hidden(String.Format("employee[{0}].EmployeeID", ix), val.EmployeeID)%>
        </div>
        <div class="grdcells" style="width:50px;" >
            <%=Html.CheckBox(String.Format("employee[{0}].Required", ix), val.Required)%>
        </div>
    </div>
<% ++ix 
}%>
</div>
<br />
<button type="submit" class="button">save</button>                
<%}%>

And then in your action declaration decorate your parameters as following:

public ActionResult MeetingTodo([Bind(Prefix = "employee")]Employee[] employees)

A better and cleaner way would be to do this though.

<% for (int i = 0; i < Model.Count(); ++i) 
{ %>
<%= Html.HiddenFor(m => m[i].SomeAttribute) %>
<div><%= Html.TextAreaFor(m => m[i].SomeTextAttribute) %></div>
<% } %>
Emil Badh
Thanks for reply Emil. i changed foreach to for. now EmployeeID and Todo collections contain five elements each that is equal to number of controls on the form(correct). but the problem is that entries in these collections are null for Todo and 0 for EmployeeID. m i missing somethings?
Muhammad Adeel Zahid
Could you post how your markup looks now as well as how your action method signature looks? I might be able to help better that way.
Emil Badh
Edited the question to contain markup and signature of actionresult. plz c edit no 1
Muhammad Adeel Zahid
+1  A: 

Is it possible to see what your view code look like?

It should look something like this:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Employee>>" %>
// Other code not in your example
<%using (Html.BeginForm("MeetingTodo", "OA", FormMethod.Post, new { id = "TaskForm" }))
{%>
<%=Html.Hidden("id",ViewContext.RouteData.Values["id"]) %>
<div class="container">
<% for (int i = 0; i < Model.Count(); ++i)
   { %>
   <div class="grdrow" > 
       <div class="grdrightcaption" style="width:173px;" >
           <%= Model[i].setupEmployee.EmployeeName%>
       </div>
       <div class="grdcells" >
           <%= Html.TextAreaFor(x => x[i].Todo, new { maxlength = 200, style="width:300px;" })%> <%= Html.HiddenFor(x => x[i].EmployeeID)%>
       </div>
       <div class="grdcells" style="width:50px;" >
           <%=Html.CheckBoxFor(x =>  x[i].Required) %>
       </div>
   </div>
<% }%>
</div>
<br />
<button type="submit" class="button">save</button>                
<%}%>
// Other code not in your example

And your action method signature should look like this:

public ActionResult MeetingTodo(IEnumerable<Employee> Employees,
    FormCollection collection,
    int id)

I don't remember of the top of my head if you can set the type to IEnumerable<Employee> or if you have to set it to Employee[] in the action method signature, but one or the other should work.

Also note that on the first line you have to make sure you include the namespace in the Inherits attribute as such: System.Web.Mvc.ViewPage<IEnumerable<Namespace1.Namespace2.Namespace3.Employee>> and of course use whatever real name your employee class has.

Hope this helps.

Emil Badh