現象:
昨天在處理PBS系統問題的時候意外發現兩個js錯誤(而同樣的代碼在同事機器上都沒有問題),如下圖。
圖1
圖2
圖3
原因分析:
初步看起來是因為頁面上沒有id為'form1'的form和id為‘MainContent_rblIsAdProduct_0’的radiobutton,那它實際生成的id是什么呢?為了確認,我查看頁面的源代碼,發現生成的id如下圖。
圖4
masterpage中的id為'form1',生成HTML后變成了'aspnetForm'。
圖5
內容頁中的id為'MainContent_rblIsAdProduct_0'加了前綴'ctl00_'。
通過源代碼的分析,看起來像asp.net 3.5或更早版本的行為(給服務器端控件生成唯一客戶端ID),因為從asp.net 4.0版本開始已經默認不加前綴了,而我本機的.net framework就是4.0版本的,項目站點指定的也是.net framework 4.0,那為什么看起來還是asp.net 3.5的效果呢?
首先查看項目(PackageFH.Offline.Site)使用的.net framework框架版本,發現使用的是.net framework 4的版本,所以項目使用的.net framework版本沒有問題,也就排除了項目使用框架版本不正常的懷疑。
聯想到在同事的開發機器上瀏覽起來都正常,唯獨在我的機器上報錯,所以很有可能是某個地方的配置不對,首先我想到會不會是IISExpress的配置問題,為了快速驗證,我拿同事機器上IISExpress的配置文件過來替換,再次運行錯誤果然不見了,所以驗證了是因為IISExpress的配置導致了這個問題。
既然確定了是因為IISExpress的配置導致的,那就要確定到底是那一個點導致的,經過反復比對和驗證,最后發現是由applicationhost.config中site節點下根目錄('/')的配置導致的,因為我的機器根目錄指向的是一個使用asp.net 3.5框架的站點,如圖6,而這個站點下的web.config指定了controlRenderingCompatibilityVersion屬性使用asp.net 3.5版本,如圖7。
圖6
圖7
解決方案:
既然找到了問題的根本原因,那么解決方法就很簡單了。將IISExpress下site的根目錄指定為%IIS_SITES_HOME%或一個已存在的目錄(如果目錄中存在web.config,需要去掉controlRenderingCompatibilityVersion和clientIDMode),使用asp.net 4.0框架默認配置既可,如圖8。
圖8
注:site節點的根目錄相當於IIS中的站點根目錄,而application相當於應用程序(也可以是虛擬目錄),如果站點根目錄下有web.config文件,那么整個站點都會應用這個配置,所以site的根目錄最好不要有web.config文件。
參考文章:
1,StackOverFlow中的解釋:http://stackoverflow.com/questions/4437717/asp-net-2-5-prefixing-ctl00-and-asp-net-4-not-prefixing-ctl00