An item with the same key has already been added.

Topics: Core, Writing modules
Jun 26, 2013 at 3:26 PM
I'm getting the error below each time I do call a HttpPost controller action.

I tried attaching to the w3wp process but no code is even hit. It just throws the execption as below: I'm using orchard 1.6 version.

An item with the same key has already been added.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: An item with the same key has already been added.

Source Error:


Line 160: public void EndProcessRequest(IAsyncResult result) {
Line 161: try {
Line 162: _httpAsyncHandler.EndProcessRequest(result);
Line 163: }
Line 164: finally {


Source File: d:\dev2013\Orchard.1.6\Orchard.Source\src\Orchard\Mvc\Routes\ShellRoute.cs Line: 162

StackTrace:
[ArgumentException: An item with the same key has already been added.]
System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) +14174516
System.Linq.Enumerable.ToDictionary(IEnumerable
1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) +267
System.Linq.Enumerable.ToDictionary(IEnumerable
1 source, Func2 keySelector, IEqualityComparer1 comparer) +125
System.Web.Mvc.ModelBindingContext.get_PropertyMetadata() +173
System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +240
System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +283
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +675
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +484
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +153
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +854224
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__19() +40
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +15
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +65
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +51
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +51
Orchard.Mvc.Routes.HttpAsyncHandler.EndProcessRequest(IAsyncResult result) in d:\dev2013\Orchard.1.6\Orchard.Source\src\Orchard\Mvc\Routes\ShellRoute.cs:162
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
Developer
Jun 26, 2013 at 5:30 PM
Does this happen with any controller, or a specific one? What URL are you posting to?
Developer
Jun 26, 2013 at 7:37 PM
As the stack trace says - there is a duplicate key when model binding happens.
Seems like you're binding your form post values to a dictionary and provided the same key twice. Can't tell more without seeing the erroneous piece of code.
Jun 27, 2013 at 9:04 AM
Edited Jun 27, 2013 at 9:06 AM
here is my controller
   [HttpPost]
        [AllowAnonymous]
        public ActionResult AuthenticateCustomer(LoginModel user)
        {
            if (string.IsNullOrEmpty(user.UserName))
                ModelState.AddModelError("", "Invalid User Name.");
            if (string.IsNullOrEmpty(user.Password))
                ModelState.AddModelError("", "Invalid User Password.");
            //code that executed authentication
            return View("Index", user);
        }

@using (Html.BeginForm("AuthenticateCustomer", "Home", FormMethod.Post, new { ReturnUrl = ViewBag.ReturnUrl }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        @if(Model==null || Model.CompanyID==0){
        <legend>Customer Account Login</legend>
        <ul style="list-style:none">
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName, new {@placeholder="email@company.com"})
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password,new {@placeholder="password"})
            </li>
            <li>
                <div style="position:relative">
                @Html.CheckBoxFor(m => m.RememberMe, new {@onclick="javascript:rememberme();" })
                @Html.LabelFor(m => m.RememberMe, new { @class = "absolutepos-checkbox" })
                </div>
            </li>
        </ul>
        <div class="validation-summary-errors" id="required_field_section" style="display:none">
            <ul id="required-field-message" style="list-style:circle">
                
            </ul>
        </div>
        <input id="userloginbutton" type="submit" value="Log in" class="button-black-label" style="margin-left:237px" onclick="return validateCustomerLogin();" /><br />
            <p style="margin-top:15px;">
        @Html.ActionLink("Register", "Register") if you don't have an account.
    </p>
        }else{
            <div>Name: @Model.name</div>
            <div>Email: @Model.Note</div>
            <div>Phone: @Model.phone</div>
            <label>Provisioned Apps</label>
            <ul>
                <li><a href="javascript:window.location='dev.unitrak.com.au/client/jobs.aspx?cid=@Model.CompanyID'">View Unitrak Jobs</a></li>
            </ul>
            
        }
    </fieldset>
    
}
and the validation js:
 function validateCustomerLogin() {
        user.uid = $('#UserName').val();
        user.pwd = $('#Password').val();
        if (execValidation(user.uid, '#UserName', 'User name is required.', true) == false)
            return false;
        if (user.autologin != true) {
            if (execValidation(user.pwd, '#Password', 'Password is required.') == false) {
                return false;
            }
        }
        return true;
}
what throws me off is that it doesn't even hit my controller before the error is thrown.
Developer
Jun 27, 2013 at 10:59 AM
what throws me off is that it doesn't even hit my controller before the error is thrown.
It makes sense because model binding happens before your action is invoked.

How does your LoginModel class look like?
Jun 28, 2013 at 3:01 AM
Edited Jun 28, 2013 at 3:16 AM
Thanks guys. Your for the responses was a big help.

The problem was:

My LoginModel was inheriting from a class generated by EF. It has a field called password, and my model had a field called Password. After I have removed the Password field, it goes back to work like magic ;)