views:

84

answers:

1

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.

+1  A: 

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

adrift
Thank you! It will take me an hour or so to confirm this is the problem but I'll report back either way.
Glenn
When I look at references inside VisualStudio I see
Glenn
Path: C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 2\Assemblies\System.Web.Mvc.dll
Glenn
When you browse to that file, right-click on it and select Properties, go to the Details tab and see if the File version is 2.0.50217.0.
adrift
But more importantly, try to check the version of the file on your server. Hope this helps.
adrift
"Version" shows 2.0.0.0 and "Runtime Version" shows v2.0.50727 I also downloaded the hard to find RTM dll here http://aspnet.codeplex.com/releases/view/41742#DownloadId=110348 and when I checked it it showed the same thing. I had the MVC dll reference property "copy local" set to true in the error case above so I think the server should have been using the same dll.
Glenn
The Runtime Version on my machine also shows v2.0.50727, but that is the version of the .NET runtime that it was compiled against, not the file version of the System.Web.Mvc.dll file itself. If find the actual dll and look at the properties, you should be able to confirm whether it is 2.0.50129 or 50217.
adrift
Sorry about the confusion. The version checks out and I was on RTM when I got the errors so I don't think I fixed it.
Glenn
If you do find that the file version of System.Web.Mvc.dll on your machine is RTM (50217), I would still check the file on the server if that is possible on the off chance that an RC version was copied there at some time in the past and never updated.
adrift
And finally, if the version on your server definitely is the RTM version, then (sadly) it looks like the bug was not completely resolved and you are now running into it.
adrift
You are right. The Server is on an older version 2.0.41211.0. I had "copy local" set to true, but I guess I can't rely on that? Its our dedicated box so we can change it but I'm a bit cautious about fiddling with the mvc upgrade because several sites on the server could be impacted.
Glenn
That is actually good news! Now it's just a matter of updating it, unfortunately, this is beyond my experience and I wouldn't feel right telling you how to upgrade the dll on a production server. But I bet there are people on SO who have the experience and can give you better advice, and that would be a more common experience so if you post another question on SO about your situation now and how to upgrade, you'll get a better response. Good luck!
adrift
I'll give it a shot. Thank you!
Glenn