最近將一個項目從ASP.NET MVC 3升級至剛剛發布的ASP.NET MVC 5.1,升級後發現一個ajax請求出現了500錯誤,日志中記錄的詳細異常信息如下:
System.ArgumentException: 已添加了具有相同鍵的項。(An item with the same key has already been added) 在 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) 在 System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) 在 System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) 在 System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) 在 System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) 在 System.Web.Mvc.ControllerBase.get_ValueProvider() 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) 在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) 在 System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state)
雖然問題是由於升級至MVC 5.1引起的,但本著“遇到問題,先懷疑自己”的原則,檢查了一下代碼,竟然在js代碼中發現了一個存在已久的低級錯誤:
var pagingBuider = { "PageIndex": 1 }; function buildPaging(pageIndex) { pagingBuider.pageIndex = pageIndex; $.ajax({ data: JSON.stringify(pagingBuider), contentType: 'application/json; charset=utf-8' }); }
PageIndex在賦值時寫成了pageIndex(第1個字母大寫P寫成了小寫p),在js中開頭字母小寫也是規范寫法,當時可能是直覺性地寫出來的,所以這個低級錯誤情有可原。
/*這時你可能不禁要問:為什麼自己給自己找事,開頭字母用大寫呢?哎,我也有我的苦衷,這段js代碼是在服務端根據C#對象的屬性生成的,C#的規范是開頭字母大寫*/
由於這樣一個低級錯誤,在ajax請求時發送給服務端的json字符串變成了這樣:
{"PageIndex":1,"pageIndex":2}
這時找茬的勁頭一湧而出,一個大大的問號浮現在眼前。。。