ListBox elements rearranged with JavaScript causing event validation error on postback

醉酒当歌 提交于 2019-12-04 07:20:47

The problem is that the saved view state of the list and the data received on postback do not match. The event validation issue is most likely just one of the possible problems that might appear because of this approach. The architecture of webforms does not allow this kind of uses and, most likely, there will be more problems with this approach, even if you succeed to avoid the event validation issue. You have several alternatives:

1) The simplest is to do the swapping logic on server instead of using javascript. This way the view state will be preserved between postbacks and the added overhead of multiple round trips to the server might not be an issue.

2) If the multiple round trips to server is an issue, write a server control that handles it's own view state. This is of course a much engaging approach.

3) A middle ground approach could be to use two simple html lists (just write the html tags without using the asp.net controls) and maintain on the client side from javascript a list of id's in a hidden field. On post back just parse the hidden field and extract the id's ignoring the html lists.

I would go with 1 if there aren't SERIOUS arguments against it.

A few possible options:

  • If possible, disable ViewState on the two lists. Without ViewState, the server won't know what the original values were and hence will not error. With this approach, you will need to repopulate the lists (due to lack of ViewState) and may need to track the selection manually - or will need to populate the lists during OnInit phase.

  • Turn off event validation (if you can)

  • Populate both lists fully on the server side and use client side script (javascript) to remove entries from the two lists as required.

The first option will bring considerable overhead. I have defined my own custom listbox control derived from the listbox class and performed an override of the loadpostback data:

public class CustomListBox : ListBox
{
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        return true;
    }
}

Using this instead of the regular listbox in my user control solved the problem, however are there any risks associated with my approach?

By chance, did you try this already? Do this whenever you muck with the list in any way.

document.getElementById("listbox").selectedIndex = -1;

It's complaining because the selected item in a list was not present in the list when it was rendered. Consider using PageMethods via AJAX to get your data back to your form instead of PostBack. Or use a non-input controls to hold the data -- like unordered lists that you move list elements back and forth between. You can put the GUIDs in hidden spans inside the list element where you can get at them if need be.

Alternatively, you can use a server-side HtmlSelect in place of a ListBox to work around the event validation issue. Best of all, you may be able to leave much of your code-behind intact (ie. list population logic is the same as ListBox).

<select runat="server" id="myList" multiple="true" />

You could override the Render event to register all possible listbox items with both listboxes. That way no matter what items are moved where, the validation is expecting them.

protected override void Render(HtmlTextWriter writer)
{
  foreach (DictionaryEntry entry in ColumnConfig) {          
    Page.ClientScript.RegisterForEventValidation(lstbxColumnsToExport.UniqueID,(string)entry.Key);
    Page.ClientScript.RegisterForEventValidation(lstbxNonExportColumns.UniqueID,(string)entry.Key);
  }
  base.Render(writer);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!