1

I have a nested repeater with a delete button in it. This button deletes a student from a group. but when I press the delete button it just goes through the nested repeater again and I get:

Invalid postback or callback argument.

Stack Trace:

[ArgumentException: Invalid postback or callback argument.  Event validation is enabled     using <pages enableEventValidation="true"/> in configuration or <%@ Page    EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies     that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or  callback data for validation.]
System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument) +9714590
System.Web.UI.Control.ValidateEvent(String uniqueID, String eventArgument) +111
System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument) +29
  System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724

my asp.net file:

<!-- Begin modal -->
<asp:Repeater ID="RepeaterModal" OnItemDataBound="RepeaterModal_ItemDataBound" runat="server">
    <HeaderTemplate>
    <div id="modal">
    </HeaderTemplate>
    <ItemTemplate> 
        <div id="dialog<asp:Literal ID='ltlModalNumber' runat='server' />" class="window">
            <div class="contents">
                <h3>Students in group <asp:Literal ID="ltlModalGroup" runat="server" /></h3>
                <ul>
                <asp:Repeater ID="repeaterModalStudentList" Runat="server">
                    <ItemTemplate>
                        <li class="modalStudent"><%# Eval("Name") %></li>
                        <li class="modalStudentClassDelete">
                            <asp:ImageButton ID="imgDeleteStudent" runat="server" ImageUrl="styles/img/icons/2.png" CommandName="deleteStudent" OnClick="btnDeleteStudent_Click" ToolTip="Delete this student" />
                        </li>
                    </ItemTemplate>
                </asp:Repeater>
                </ul>                       

                <a href="#" class="close">Close</a>
            </div>
        </div>
    </ItemTemplate> 
    <FooterTemplate>
    </div>
    </FooterTemplate>

</asp:Repeater>
<!-- End modal -->

In my code behind file I do:

//A field 
int r = 0;

//Populates the table with the list of groups.
RepeaterModal.DataSource = listOfGroups;
RepeaterModal.DataBind();

listOfGroups contains a list with Group objects that contain a group_Id, name, code, Students object with strings for the name of the students.

//Repeater methode to put the values in the correct labels of the modal window
public void RepeaterModal_ItemDataBound(Object Sender, RepeaterItemEventArgs e) {
    //Execute the following logic for Items and Alternating Items.
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
        ((Literal)e.Item.FindControl("ltlModalNumber")).Text = ((Groups)e.Item.DataItem).Group_Id.ToString();
        ((Literal)e.Item.FindControl("ltlModalGroup")).Text = ((Groups)e.Item.DataItem).Code.ToString();    

        //Fill the repeater inside the repeater with the students name
        Repeater repeaterModalStudentList = ((Repeater)e.Item.FindControl("repeaterModalStudentList"));
        repeaterModalStudentList.DataSource = ((Groups)e.Item.DataItem).Students;
        repeaterModalStudentList.DataBind();

        ImageButton imgDeleteStudent = repeaterModalStudentList.Items[0].FindControl("imgDeleteStudent") as ImageButton;

        if (imgDeleteStudent != null) {
                imgDeleteStudent.CommandArgument = ((Groups)e.Item.DataItem).Students[r].Student_Id.ToString();
                r++;
        }
    }
}

protected void btnDeleteStudent_Click(object sender, EventArgs e) {     
    ImageButton b = (ImageButton)sender;
    string value = b.CommandArgument;

    Students student = new Students();
    student.DeleteStudent(int.Parse(value));

    Response.Redirect(Request.RawUrl);
}

What am I missing or doing wrong that I keep getting that error? adding EnableEventValidation is not the solution. It's something with the commandArgument.

Edit

Lol, Added if(!IsPostBack), ain't getting the error anymore. But there isn't a value in the CommandArgument.

reaper_unique
  • 2,916
  • 3
  • 28
  • 48
  • Does the group id have any funky characters? By funky, I'm referring to any character that would trip the postback validation. – Jeremy May 21 '12 at 19:03
  • Nop, it's just an int, e.g. 1, 2, 9, etc. Ow I forgot if(!IsPostBack) in my On_Load method. That's why it repeats it. But still getting the error and the imgDeleteStudent is only found twice, while it should be found 5 times. – reaper_unique May 21 '12 at 19:06
  • Correct that, I'm not getting the error again. But still doesn't work. The value added to the commandargument is empty. – reaper_unique May 21 '12 at 19:13

1 Answers1

2

You are assigning the CommandArgument, but your method is btnDeleteStudent_Click

Update:

//Repeater methode to put the values in the correct labels of the modal window 
public void RepeaterModal_ItemDataBound(Object Sender, RepeaterItemEventArgs e) { 
    //Execute the following logic for Items and Alternating Items. 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { 
        ((Literal)e.Item.FindControl("ltlModalNumber")).Text = ((Groups)e.Item.DataItem).Group_Id.ToString(); 
        ((Literal)e.Item.FindControl("ltlModalGroup")).Text = ((Groups)e.Item.DataItem).Code.ToString();     

        //Fill the repeater inside the repeater with the students name 
        Repeater repeaterModalStudentList = ((Repeater)e.Item.FindControl("repeaterModalStudentList")); 
        repeaterModalStudentList.DataSource = ((Groups)e.Item.DataItem).Students; 
        repeaterModalStudentList.DataBind(); 
        repeaterModalStudentList.ItemDataBound += repeaterModalStudentList_ItemDataBound; 
    } 
} 

//Repeater methode to put the values in the correct labels of the modal window 
public void repeaterModalStudentList_ItemDataBound(Object Sender, RepeaterItemEventArgs e) { 
    //Execute the following logic for Items and Alternating Items. 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {       

        ImageButton imgDeleteStudent = repeaterModalStudentList.Items[0].FindControl("imgDeleteStudent") as ImageButton; 

        if (imgDeleteStudent != null) { 
            imgDeleteStudent.CommandArgument = ((Student)e.Item.DataItem).Student_Id.ToString(); 
        } 
    } 
} 


protected void btnDeleteStudent_Click(object sender, EventArgs e) {  
    ImageButton btn = (ImageButton)sender; 
    int studentId = (int)btn.CommandArgument; 

    Students student = new Students(); 
    student.DeleteStudent(studentId); 

    Response.Redirect(Request.RawUrl); 
} 
Win
  • 61,100
  • 13
  • 102
  • 181
  • I think what you mean to say is that he should subscribe to ItemCommand, as opposed to btnDeleteStudent_Click? – Jeremy May 21 '12 at 19:16
  • You are right but that is just a naming convention thing since my attribute OnClick has the same name. – reaper_unique May 21 '12 at 19:17
  • I updated the code. You can attach to btnDeleteStudent_Command either from aspx page or code behind (like the above code). – Win May 21 '12 at 19:18
  • It must be CommandEventArgs; otherwise, argument won't match. – Win May 21 '12 at 19:19
  • No no, click is correct, since, as I mentioned I use Onclick attribute. the main problem is that not all my imagebuttons are adding a value to the CommandArgument. – reaper_unique May 21 '12 at 19:22
  • Could you post the partial aspx page so that I can see how you attach the click event? – Win May 21 '12 at 19:28
  • According to your code, you are assigning GroudID as imgDeleteStudent.CommandArgument = Group_Id, and retrievning StudentId as string value = b.CommandArgument;. – Win May 21 '12 at 19:37
  • Yes that is an inconsistency I adjusted. Group_Id is stupid since my Group object also contains Student objects. I'll adjust my code to represent what I have now. Done, but as mentioned I notice that it only finds imgDeleteStudent twice instead of 4 times (4 students in database). – reaper_unique May 21 '12 at 19:37
  • Why do you have ImageButton imgbtn = (ImageButton)sender; and ImageButton b = (ImageButton)sender; – Win May 21 '12 at 19:39
  • I see what happened. You need repeaterModalStudentList_ItemDataBound, and move ****ImageButton imgDeleteStudent = repeaterModalStudentList.Items[0].FindControl("imgDeleteStudent") as ImageButton; if (imgDeleteStudent != null) { imgDeleteStudent.CommandArgument = ((Groups)e.Item.DataItem).Group_Id.ToString(); } **** inside it. – Win May 21 '12 at 19:42
  • 1
    @Win Yes, you are correct! How stupid of me, I should have realized that but of course I didn't because of what I found online about nested repeaters. Like this one:http://www.codeproject.com/Articles/6140/A-quick-guide-to-using-nested-repeaters-in-ASP-NET But that just talks about databinding a dataSource not how to add own extra code with onItemDataBound. Thank you, that is an accepted answer from you my friend. – reaper_unique May 21 '12 at 19:59