最近在工作中遇到了非常奇怪的問題,在真正找到原因之前覺得不可解釋,非常奇怪。在這裡分享給大家,希望碰到類似的情況時,這篇文章給你一個提醒。
產生錯誤的背景
本人在View中寫了一段大約10-20行的代碼來動態產生WebGrid的column, 根據客戶的意見,要將這段代碼移到一個獨立的c#代碼中去。於是加了一個Class library, 把這段代碼全部移過去了。把調用的代碼寫好,一運行,發現報錯。這個錯從來沒有見過,仔細看了一下代碼,認為沒有問題,但是不明白為什麼出問題。就稍微改了一下代碼,運行又出另外一個奇怪的錯誤。看了代碼還是覺得沒有問題,還是不明白為什麼出問題。下面是詳細情況。
錯誤1:Entry point was not found.
這是主要代碼, 這段c#代碼已經全部移到這個c#類。運行以後,View拋出一個Exception: Entry point was not found, 而且指向的是@grid.GetHtml這一行。
using System;using System.Collections.Generic;using System.Web.Mvc;using System.Web.Helpers;namespace ClassLibrary1{ public static class myGrid { public static List<WebGridColumn> GenerateGridColumn(WebViewPage page) { var list = new List<WebGridColumn>(); var gridColumn = new WebGridColumn(); gridColumn.ColumnName = "test"; gridColumn.Header = " test header"; list.Add(gridColumn); var gridColumn1 = new WebGridColumn(); gridColumn.Format = item => page.Html.Raw("<a href=\"test\"></a>"); list.Add(gridColumn1); return list; } }}
myGrid.cs
@model List<Class1>@using ClassLibrary1;@{ ViewBag.Title = "Index";}<h2>Index</h2>@{ WebGrid grid = new WebGrid(source:Model); var list = myGrid.GenerateGridColumn(this);}@grid.GetHtml(columns: list)
View的代碼
看了好多遍代碼,也進行了調試,看不出問題來。在調試過程中注意到一個怪現象,myGrid.GenerateGridColumn返回的應該是一個List<WebGridColumn>,試圖在Watch視窗查看其值時卻出了一個莫明其妙的錯誤: Unable to evaluate the expression. Operation not supported. Unknown error: 0x8004f0ed. 這樣就帶來了很大的問題。調試也看不出問題。究竟問題在哪裡呢。雖然沒有明顯的證據,本人看到有一個Html在這段代碼中,懷疑這個Html.Raw引起的問題。本人覺得這個Html.Raw可能必須得在View中才能正常工作。於是就試著將包含Html.Raw的那段代碼移出c#類代碼,還是放到View中。代碼就成了這樣:
using System;using System.Collections.Generic;using System.Web.Helpers;namespace ClassLibrary1{ public static class myGrid { public static List<WebGridColumn> GenerateGridColumn() { var list = new List<WebGridColumn>(); var gridColumn = new WebGridColumn(); gridColumn.ColumnName = "test"; gridColumn.Header = " test header"; list.Add(gridColumn); return list; } }}
改過了的myGrid.cs
@model List<Class1>@using ClassLibrary1;@{ ViewBag.Title = "Index";}<h2>Index</h2>@{ WebGrid grid = new WebGrid(source:Model); var list = myGrid.GenerateGridColumn(); var gridColumn1 = new WebGridColumn(); gridColumn1.Format = item => Html.Raw("<a href=\"test\"></a>"); list.Add(gridColumn1);}@grid.GetHtml(columns: list)
改過了的View代碼
這樣的話,List的一部分Item就在myGrid中加入的,另一部分就在View中加入的。但是這樣的還是會出問題: 錯誤資訊如下:
錯誤2: Attempted to access an element as a type incompatible with the array
看了這個錯誤資訊後也是查看代碼,調試了半天,始終是認為代碼沒有問題,但是就是不明白為什麼會出這個問題。而且調試的時候,這個List<WebGridColumn>類型的list還是一樣不能在Watch視窗查看,錯誤資訊還是一樣的:Unable to evaluate the expression. Operation not supported. Unknown error: 0x8004f0ed,對比了MyGrid.cs的代碼和View的代碼, 明明都是往List中加入WebGridColumn類型的元素,應該是同樣的元素,不可能報這個錯誤的。想不透。
於是網上搜尋,網上有人提到可能是Web.config檔案中引用錯的版本的System.Web.Helpers.dll, 本人到Web.config中一看, Web.config沒有問題。然後還繼續找問題。找了兩天,還是沒有找到問題的根源。後來檢查了每一個工程的References, 突然有一個令人眼前一亮的發現:這個ClassLibrary的竟然引用的是1.0版本的System.Web.Helpers.dll。這可能就是問題所在。於是把1.0換成2.0的Reference, 然後所有這些錯誤就都消失了。心中欣喜了一番。
經驗談
asp.net mvc有很多名稱一樣但是版本不一樣的dll, 我們從老版本升級到新版本,或者構造一個新版本的asp.net mvc應用程式,在Web.config中,還有每一個工程的reference中都得確保我們引用了正確版本的dll。不然到時我們掉到哪個陷阱裡都不知道。
出錯的代碼下載: http://dl.vmall.com/c0wdxad9am 為了給那些看了文字還是不太明白的同學準備的。
如果覺得此文值得推薦,請幫忙點推薦。