Mono 为 .NET 应用程序部署在 Linux 系统上提供了可能,但是这毕竟不是微软自家的东西,还是有许多 Bug 的。

刚刚部署了一个自己写的网站,就马上遇到了问题:CheckBoxList 控件在 AutoPostBack 为 true 的情况下出现选中状态自动取消

 

具体情况是这样的:无论原本 CheckBoxListItem 是否被选中,只要改变了任何一个 Item 的选中状态,全部的 Item 都会变成未选中的状态,而且就算将它选中,它还是会自动取消。

 

查了很多资料,最后知道了是因为 Mono 下的 CheckBoxList 的 Bug,CheckBoxList 无法记住 State,所以每次都会被取消…

Mono 的 CheckBoxList 的 Bug 存在很长时间了,至少我找到了 2010 年的 issue,而且还标注为“已修复”。或许 Mono 团队修复了 CheckBoxList 在其他情况下的 Bug,但是这个 Bug 依旧没有被修复。这里是 Mono 的 Github 上的相关内容。

同时,值得庆幸的是,我找到了一个解决方案,原站点的域名已经停止解析了,只有 stackoverflow 的地址

以下是 VB.NET 代码

Public Shared Sub setCheckBoxStates(ByVal cbl As CheckBoxList)
	If HttpContext.Current.Request.HttpMethod = "POST" AndAlso Type.GetType("Mono.Runtime") IsNot Nothing Then
		Dim cblFormID As String = cbl.ClientID.Replace("_", "$")
		Dim i As Integer = 0
		For Each item In cbl.Items
			Dim itemSelected As String = HttpContext.Current.Request.Form((cblFormID & Convert.ToString("$")) + i.ToString)
			If itemSelected IsNot Nothing AndAlso itemSelected <> [String].Empty Then
				DirectCast(item, ListItem).Selected = True
			End If
			i += 1
		Next
	End If
End Sub

以下是 C# 代码

public static void setCheckBoxStates(CheckBoxList cbl)
{
    if (HttpContext.Current.Request.HttpMethod == "POST" && Type.GetType("Mono.Runtime") != null)
    {
        string cblFormID = cbl.ClientID.Replace("_", "$");
        int i = 0;
        foreach (var item in cbl.Items)
        {
            string itemSelected = HttpContext.Current.Request.Form[cblFormID + "$" + i];
            if (itemSelected != null && itemSelected != String.Empty)
                ((ListItem)item).Selected = true;
            i++;
        }
    }
}

 

只要在 Page_Load 里加上 setCheckBoxStates([CheckBoxList]); 就可以了,不要经过 IsPostBack 的判断,每次回发都需要去判断。

博主上传到 CentOS 上测试,一切正常,VB.NET 和 C# 都能正常工作。


原创文章,转载请以链接形式注明出处:https://blog.ttionya.com/article-1086.html