ASP. net mvc 3 upgraded to MVC 5.1: "An item with the same key has been added"

Source: Internet
Author: User

Recently, I uploaded a project from ASP. net mvc 3 upgraded to ASP. net mvc 5.1. After the upgrade, an ajax request Error 500 is found. The detailed exception information recorded in the log is as follows: copy the code System. argumentException: An item with the same key has been added. (An item with the same key has already been added) in System. collections. generic. dictionary '2. insert (TKey key, TValue value, Boolean add) in System. web. mvc. jsonValueProviderFactory. addToBackingStore (EntryLimitedDictionary backingStore, String prefix, Object value) in System. web. mvc. jsonValueProviderFactory. addToBackingStore (EntryLimitedDictionary backingStore, String prefix, Object value) in System. web. Mvc. jsonValueProviderFactory. getValueProvider (ControllerContext controllerContext) in System. web. mvc. valueProviderFactoryCollection. getValueProvider (ControllerContext controllerContext) in System. web. mvc. controllerBase. get_ValueProvider () in System. web. mvc. controllerActionInvoker. getParameterValue (ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) in System. web. mvc. controll ErActionInvoker. getParameterValues (ControllerContext controllerContext, ActionDescriptor actionDescriptor) in System. web. mvc. async. asyncControllerActionInvoker. <> c _ DisplayClass21. <BeginInvokeAction> B _ 19 (AsyncCallback asyncCallback, Object asyncState) in System. web. mvc. async. asyncResultWrapper. wrappedAsyncResultBase '1. begin (AsyncCallback callback, Object state, Int32 timeout) in System. web. mvc. async. AsyncResultWrapper. begin [TResult] (AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate '1 endDelegate, Object tag, Int32 timeout) in System. web. mvc. async. asyncControllerActionInvoker. beginInvokeAction (ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state, after checking the code, I found a javascript code that has existed for a long time. Low-level error: copy the code var pagingBuider = {"PageIndex": 1}; function buildPaging (pageIndex) {pagingBuider. pageIndex = pageIndex; $. ajax ({data: JSON. stringify (pagingBuider), contentType: 'application/json; charset = UTF-8 '});} the code for copying PageIndex is written as pageIndex (1st letters in upper case P are written as lower case p) when values are assigned. In js, opening the first letter in lower case is also a standard writing method, which may be directly written at that time, therefore, this low-level error is justified. /* At this time, you may not be able to ask: Why do you use uppercase letters for the first letter to find something for yourself? Well, I have my own difficulties. This js Code is generated on the server based on the properties of the C # object. The C # specification is to uppercase letters at the beginning */due to such a low-level error, when an ajax request is sent to the server, the json string is changed to the following: {"PageIndex": 1, "pageIndex": 2}. At this moment, the strength of the query is surging, A big question mark is coming soon... Why can ASP. net mvc 3 tolerate this error and get the correct value (PageIndex = 2), but ASP. net mvc 5.1 cannot? Is MVC 5.1 more rigorous or narrow-minded? Driven by curiosity, I tried to find out in the open source code of ASP. NET MVC. Use git to check out the source code of ASP. net mvc -- https://git01.codeplex.com/aspnetwebstack Open the solution with VS2013, and find the exception cause in the AddToBackingStore method in the solution manager. (the last line of code is backingStore. add (prefix, value): copy the code private static void AddToBackingStore (EntryLimitedDictionary backingStore, string prefix, object value) {IDictionary <string, object> d = value as IDictionary <string, object>; if (d! = Null) {foreach (KeyValuePair <string, object> entry in d) {AddToBackingStore (backingStore, MakePropertyKey (prefix, entry. key), entry. value);} return;} IList l = value as IList; if (l! = Null) {for (int I = 0; I <l. count; I ++) {AddToBackingStore (backingStore, MakeArrayKey (prefix, I), l [I]) ;}return ;}// primitive backingStore. add (prefix, value);} copies the code and finds the specific code line that causes the exception: _ innerDictionary. add (key, value); _ the corresponding implementation of innerDictionary at runtime is: new Dictionary <string, object> (StringComparer. ordinalIgnoreCase); StringComparer is used in the Dictionary constructor. ordinalIgnoreCase (that is, keys are case-insensitive). It can be seen that Microsoft programmers have considered "Case-insensitive", but it does not take into account the situation that "both correct and wrong cases occur. When MVC 5.1 receives a json string of {"PageIndex": 1, "pageIndex": 2}, when performing the following operations: _ innerDictionary. add ("PageIndex", 1); _ innerDictionary. add ("pageIndex", 2); detonated an exception: System. argumentException: An item with the same key has been added. (An item with the same key has already been added ). It's easy to fix this problem: copy the Code if (_ innerDictionary. containsKey (key) {_ innerDictionary [key] = value;} else {_ innerDictionary. add (key, value);} is there any special consideration for Microsoft programmers to copy the code? However, after carefully reading the implementation code of JsonValueProviderFactory, the answer is more likely to be the former, for example, the following code: copy the code private static object GetDeserializedObject (ControllerContext controllerContext) {if (! ControllerContext. httpContext. request. contentType. startsWith ("application/json", StringComparison. ordinalIgnoreCase) {// not JSON request return null;} StreamReader reader = new StreamReader (controllerContext. httpContext. request. inputStream); string bodyText = reader. readToEnd (); if (String. isNullOrEmpty (bodyText) {// no JSON data return null;} JavaScriptSerializer serializer = new JavaScript Serializer (); object jsonData = serializer. deserializeObject (bodyText); return jsonData;} copy the code StreadReader without Dispose (such as in using). This is not like a good programmer.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.