简体   繁体   中英

Copy Local != true System.Web.MVC - Asp.net MVC 2 Dictionary Error in Controller Before Action

I am getting an odd error in an ASP.NET MVC (mvc dll version 2.0.0.0) project after the server is under load (50 to 100 requests per second) for a few hours and cache is approaching its memory limit. If I am reading the error log right (we use elmah) the MVC action parameter parser is failing before it gets to my controller's action.

From the error report (below), it seems like the model binder that fills in the action parameters is involved. I checked the url & query string, they work fine in all my tests, and there is nothing odd there to differentiate them from other requests that worked. All the parameters are present and contain valid values.

I looked for dictionary calls and one candidate is the filter I am applying at the Controller Level (as opposed to the Action Level). However, I don't see that filter in the error report.

Is this a MVC 2 bug? If it's not an MVC bug, how would you investigate further?

**Code - renamed & simplified but parameters are the same types**
[OutputCache(Duration = 1000000, VaryByParam = "*", Location=OutputCacheLocation.Any)]
public class MyController : Controller
{
   public ActionResult MyAction(Int32 one, Int32 two, Int32 three,string a, string b, string b)
    {
         var modelData= FetchModelData(one,two,three,a,b,c);//load model data
         return View(modelData);
    }

}

        **Error**        
System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptor.TypeDescriptorCache.GetAssociatedMetadataType(Type type)
at System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptor..ctor(ICustomTypeDescriptor parent, Type type)
at System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptionProvider.GetTypeDescriptor(Type objectType, Object instance)
at System.Web.Mvc.TypeDescriptorHelper.<GetTypeDescriptorFactory>b__0(Type type)
at System.Web.Mvc.ModelBinders.GetBinderFromAttributes(Type type, Func`1 errorMessageAccessor)
at System.Web.Mvc.ModelBinderDictionary.GetBinder(Type modelType, IModelBinder fallbackBinder)
at System.Web.Mvc.ControllerActionInvoker.GetModelBinder(ParameterDescriptor parameterDescriptor)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

---------------------------------EDIT------------------------------

The problem was a MVC threading bug in RC that was later fixed in the RTM.
The trouble is I was ALREADY using MVC RTM in my project and setting copy local = true!

Why can't I set "Copy Local = true" for references to System.Web.MVC?

Here is the answer

First, I needed to prove to myself that the wrong version of MVC is running on the server I used this article and code here to test the MVC dll version and got the error I expected:

Mismatched or outdated versions of ASP.NET MVC and ASP.NET MVC Futures are loaded.

Loaded version of ASP.NET MVC is: ASP.NET MVC 2 RC 1 (2.0.41211.0) Loaded version of ASP.NET MVC Futures is: ASP.NET MVC 2 RTM Futures (2.0.50217.0) Download ASP.NET MVC 2 RC 1 Futures from http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37423#DownloadId=97581.aspx?ReleaseId=37423#DownloadId=97581 .

Why does this happen?

Here is a SO question that suggests VS and the server silently ignore my command . Locally, I had some trouble getting MVC 2 RC out of the GAC in the upgrade to RTM. So, In my Visual Studio projects I made sure to set "copy local" = true for System.Web.MVC thinking that would keep me from worrying about the different versions of System.Web.MVC on various servers.

How Can I Fix It?

Apparently, every server with MVC RC in the GAC will silently ignore "copy local" instructions for system.web.mvc and the only solution to upgrade to RTM on each server.

I found this link , which shows the same exception and stack trace. It suggests that this was a bug in RC, but was fixed in RTM. Is it possible you still have a pre-release version of the assembly?

The file version of System.Web.Mvc.dll that I have is 2.0.50217.0 (assembly version is 2.0.0.0).

I'm not an ASP.NET MVC 2 expert, so this is all I can offer (sorry). If this doesn't help you resolve the error, then I would suggest offering a rep bounty on it.

Good luck!

Edit

Adding this link to a SO question about System.Web.Mvc.dll versions: How to be sure that my MVC project is running on the correct version after upgrade to vs2010?

From the comments in that question:

Check the version number. RC 2 is 2.0.50129.0. Release is 50217

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM