WebUIValidation.js在某些IE無法Render出來的解法!

  • 5534
  • 0
  • IIS
  • 2009-10-31

客戶有台電腦用IE 7.0,使用我們ASP.NET 1.1的程式時,發現驗証都無法使用。查不出原因,給他上到IE 8.0還是一樣, 昏倒! 真想叫User重裝OS,後來使用IE 8的Debug一步一步找出問題所在....

前言

客戶有台電腦用IE 7.0,使用我們ASP.NET 1.1的程式時,發現驗証都無法使用。查不出原因,給他上到IE 8.0還是一樣, 昏倒! 真想叫User重裝OS..

研究

後來在客戶那直接用IE 8給他Debug下去,發現沒有Page_ClientValidate這個function,檢視原始檔,居然沒有沒有WebUIValidation.js。

  • 解法1:

如果它沒有下WebUIValidation.js那就手動加到網頁裡吧!

<script language="javascript" type="text/javascript" src="/aspnet_client/system_web/1_1_4322/WebUIValidation.js"></script>

這時雖然有Page_ClientValidate這個function了,但是會死在這個functoin裡,所以就再改WebUIValidation.js裡的Page_ClientValidate function,以避免JS錯誤!


    try{
        var i;
    for (i = 0; i < Page_Validators.length; i++) {
        ValidatorValidate(Page_Validators[i]);
    }
    ValidatorUpdateIsValid();    
    ValidationSummaryOnSubmit();
    }catch(ex){
        Page_IsValid = true;
  }
  Page_BlockSubmit = !Page_IsValid;
  return Page_IsValid;
}
  • 解法2:

解法1的方式雖然讓Client端有了Page_ClientValidate function,但是Client端的驗証還是無效的,因為我們不知要Render出那驗証做為Page_Validators的Array。最好還是要讓ASP.NET可以自動Render而不是手動。

想了一下,可以反組譯System.dll呀! 先找到System.Web.UI.WebControls裡的RequiredFieldValidator,再找到BaseValidator。然後再看BaseValidator的OnPreRender事件中,它是依DetermineRenderUplevel()決定要不要把驗証給Render到Client端。RegisterValidatorCommonScript就是Render那些驗証的函式。

即然發現是DetermineRenderUplevel再看一下裡面在做那些事呢? 原來是去判斷是否允許Script及IE的版本為何。

於是我就寫個程式用那個Client測試一下。


Response.Write("IsNothing(page.Request):" & IsNothing(Page.Request) & "<BR>")
Response.Write("EnableClientScript:" & Me.RequiredFieldValidator1.EnableClientScript & "<br>")
Response.Write("page.Request.Browser.MSDomVersion.Major:" & Page.Request.Browser.MSDomVersion.Major & "<br>")
Response.Write("page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1, 2)):" & Page.Request.Browser.EcmaScriptVersion.CompareTo(New Version(1, 2)) & "<br>")

結果如下,

IsNothing(page.Request):False
EnableClientScript:True
page.Request.Browser.MSDomVersion.Major:0
page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1, 2)):-1

果然是有問題呀! 連到http://www.cyscape.com/showbrow.aspx?bhcp=1 是可以查的出來的說!

拿IIS Log的中Client的User Agent到http://user-agent-string.info/ Parse也是可以Check的出來說!

clip_image002 

後來再依MSDomVersion Keyword到網路上去找,找到了關於browserCaps(在C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config),看了該區段的內容,想說用暴力法,如果Asp.NET parse不到的,就一律把它設定成可以符合的版本,這樣起碼Client Validator是可以Work的。

<browserCaps>
            <result type="System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
            <use var="HTTP_USER_AGENT"/>

            browser=Unknown
            version=0.0
            majorversion=0
            minorversion=0
            frames=false
            tables=false
            cookies=false
            backgroundsounds=false
            vbscript=false
            javascript=false
            javaapplets=false
            activexcontrols=false
            win16=false
            win32=false
            beta=false
            ak=false
            sk=false
            aol=false
            crawler=false
            cdf=false
            gold=false
            authenticodeupdate=false
            tagwriter=System.Web.UI.Html32TextWriter
            ecmascriptversion=0.0
            msdomversion=0.0
            w3cdomversion=0.0
            platform=Unknown
            css1=false
            css2=false
            xml=false

            mobileDeviceManufacturer = "Unknown"
            mobileDeviceModel = "Unknown"

            gatewayVersion = "None"
            gatewayMajorVersion = "0"
            gatewayMinorVersion = "0"

            preferredRenderingType = "html32"
            preferredRenderingMime = "text/html"
            preferredImageMime = "image/gif"

            defaultScreenCharactersWidth = "12"
            defaultScreenCharactersHeight = "6"
            defaultScreenPixelsWidth = "96"
            defaultScreenPixelsHeight = "72"
            defaultCharacterWidth = "8"
            defaultCharacterHeight = "12"
            screenBitDepth = "1"
            isColor = "false"
            inputType = "telephoneKeypad"

            numberOfSoftkeys = "0"
            maximumSoftkeyLabelLength = "5"

            canInitiateVoiceCall = "false"

把以上browser=Unknown中的上面紅色3行改成以下,這樣就可以了!

           ecmascriptversion=1.2
            msdomversion=4.0
            w3cdomversion=1.0

 

結論

原本有開問題問MS,後來有解就沒有再問MS為何會如此了。如果其他人有任何想法或解法,煩請回應哦!  謝謝!

呵! 還好是.NET,起碼可以知道要去改那裡! 也還好有IE8.0,可以直接在Client端對Javascript做Debug,才會發現是少了WebUIValidation.js。後來反組譯後才發現是什麼原因導致,但又不知如何去修正Client的電腦,後來找到「Client-Side Validation in Downlevel Browsers」及「A Look at ASP.NET's Adaptive Rendering」才去看machine.config裡的browserCaps內容,也才想到用暴力法去解這個問題。

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^