[Abstract]

I got a wired "Delegate 'System.Action' does not take 1 arguments" error while using Telerik().ScriptRegistrar().OnDocumentReady(@<text>alert("YES");</text>) in my project, but it works fine in the Telerik.Web.Mvc.Examples project on the same box.  After hours of trouble-shooting, I found the root cause, the remaining System.Web.WebPages.dll in the bin folder, which is left by a tracing of MVC source, caused reference conflict.  After removing it, the issue disappeared.

照著程式庫文件說明的範例,在程式中試圖使用Razor語法@<text></text>當作Telerik的參數,卻發生錯誤:

@{ Html.Telerik().ScriptRegistrar().OnDocumentReady(@<text>alert("YES");</text>); }

傳回Compilation Error:

Compiler Error Message: CS1593: Delegate 'System.Action' does not take 1 arguments

透過錯誤畫面的【Show Complete Compilation Source:】鈕檢視Razor View實際轉換的程式碼,原來@<text></text>會被Razor翻譯成item => new new System.Web.WebPages.HelperResult...的寫法:

Line 70:      Html.Telerik().ScriptRegistrar()
Line 71:           .OnDocumentReady(item => 
new System.Web.WebPages.HelperResult(__razor_template_writer => { Line 72: Line 73: Line 74: #line default Line 75: #line hidden Line 76: Line 77: WriteLiteralTo(@__razor_template_writer, "alert(\"YES\");"); Line 78: Line 79: Line 80: Line 81: #line 10 "X:\WorkRoom\MVCWeb\Views\Home\Index.cshtml" Line 82: })); Line 83:

但詭異的是,同樣寫法在Telerik的範例網站中可順利執行無誤,Google爬文也找不到類似個案,比對兩個網站的設定看來也都相同,但就算將範例網站的cshtml移到我的網站也會出錯。經過一番摸索掙扎,決定再鑽深一點,追進Telerik的OnDocumentReady是如何做到支援@<text></text>當成參數,在範例專案中,透過VS2010好用的Go To Definition功能,我找到了它對應的Method:

public virtual ScriptRegistrarBuilder OnDocumentReady(Func<object, object> onDocumentReadyFunc)

換句話說,@<text></text>在Razor View Engine中被轉換成item => new System.Web.WebPages.HelperResult(...),吻合Func<object, object>參數型別而適用此Overloading。這麼說來,在我的專案中是否因型別不吻合套不到Overloading才導致問題? 在我自己的專案裡,試著對cshtml中的OnDocumentReady做Go To Definition,卻傳回"Cannot navigate to function",這印證了我的猜測。於是將範圍縮小,在cshtml寫了一段Func<object, object> x = @<text>AAA</text>做測試,結果:

Compiler Error Message: CS0433: The type 'System.Web.WebPages.HelperResult' exists in both 'c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.WebPages\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.dll' and 'c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\4dd28e84\bd0ec915\assembly\dl3\4f17bd54\d1ab414f_c0f5cb01\System.Web.WebPages.DLL'

哈!! 感覺好像在濃霧瀰漫的草原胡亂摸索了兩個鐘頭,忽然間一轉頭變成陽光普照,一眺千里,這才發現眼前的山頭聚集了滿滿一群羚羊...

想起來了,上週玩了Debug MVC Source Code,後來雖然將Reference改回正式System.Web.Mvc.dll,但bin目錄下卻殘留了System.Web.WebPages.DLL,實際執行時就引用了它而非GAC中的版本,造成參考來源不一致。

一邊在山頭奔跑驅趕,一邊刪除多餘的DLL檔案,羚羊群四處逃竄,錯誤訊息頓時消散,本次的懸疑茶包也終告結案。


Comments

# by thangnv

thank you a lot. it's very nice.

# by haythamforever@gmail.com

Thanks alot ,you saved my life

Post a comment