描述
ASP.net 添加了"event validation"的功能, ASP.NET會檢查 POST方法中的所帶的參數,如果認為不合法,就會抛出異常,資訊如下:
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.
這個設計的目的是為了防止惡意使用者利用post 方法發送一些惡意資料.但是有時一些常見的case也會出錯,比如使用用戶端腳本,根據頁面上的其他控件的内容來改變一個dropdown list的内容,最常見的case就是省市縣3級關聯菜單.又比如在頁面上添加一個dropdown list,然後給它添加3個item,再使用用戶端腳本在dropdown list中添加一個item,如果dropdown list的AutoPostBack="True",每次選擇list item都會引起postback, 如果所選的item為dropdown list本來就有的,一切正常.如果所選的item是通過用戶端腳本添加的,就會出現異常.在asp.net render DropDownList 時,會周遊DropDownList的item,并記錄所有可能的postback的值,其算法為
hash(DropDownList’s UniqueID XOR hash(ListItem’s Value property)),計算的結果會被儲存在page中,
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBQKGg9abDQKd9sHMBgKc9s…….." />
這個過程發生在control的Render()方法中當頁面postback時,ASP.NET會根據這個隐藏值檢查postback values,如果找不到對應資訊,就會報錯
解決方法
1. 禁止這個功能, 但同時會失去一些安全保障:
//—-通過web.config <system.web> <pages enableEventValidation="false"/> </system.web> //—-針對某個page <%@ Page EnableEventValidation="false" … %>
2. Register For Event Validation,其原理就是讓asp.net記錄這個postback value.RegisterForEventValidation必須在render時調用:
protected override void Render(HtmlTextWriter writer) { ClientScript.RegisterForEventValidation(_recipeList.UniqueID,"4"); base.Render(writer); }
如果我們自己寫了一個control,需要使用validate events功能,就需要使用SupportsEventValidation attribute,
[SupportsEventValidation] public class DynamicDropDownList : DropDownList { protected override void Render(System.Web.UI.HtmlTextWriter writer) { Page.ClientScript.RegisterForEventValidation(this.UniqueID, "4"); base.Render(writer); } }
3. Form嵌套,一個頁面隻能有一個Form,仔細檢查代碼。