SventoryMang
SventoryMang

Reputation: 10479

Knockout AJAX post: Operation is not valid due to the current state of the object

I've got a knockout model being posted to AJAX for loading data when a drop down value changes. When I try and get that data I get this error:

System.InvalidOperationException: Operation is not valid due to the current state of the object. Generated: Thu, 06 Jun 2013 21:56:30 GMT

System.InvalidOperationException: Operation is not valid due to the current state of the object. at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth) at

I have tried both of these settings in the web.config:

<appSettings>
   <add key="aspnet:MaxHttpCollectionKeys" value="20000" />
   <add key="aspnet:MaxJsonDeserializerMembers" value="20000" />
</appSettings>

at super high numbers. That did not fix the problem. I am not sure what the problem is. Here is my view for the dropdownlist:

 @Html.DropDownListFor(x => x.ParentUser, new SelectList(Model.ParentUsers, "Id", "DisplayName"), "--Select a " + @Model.ParentRole.DisplayName + "--")

And my Action:

[HttpPost]
    public JsonResult GetAssignedUsers(KeyValueModel assigneeRole, KeyValueModel parentRole, Guid parentUser)
    {
        Role assignee = _roleService.GetOne(x => x.Id == assigneeRole.Id);
        Role parent = _roleService.GetOne(x => x.Id == parentRole.Id);
        User parentUsr = _userService.GetOne(x => x.Id == parentUser);
        List<KeyValueModel> assignedUsers = _roleAssignmentService.GetAssignedUsers(parent, assignee,parentUsr)
                                                                  .Select(
                                                                      x => new KeyValueModel(x.Id, x.DisplayName))
                                                                  .ToList();

        return Json(assignedUsers);
    }

And the Jquery code:

$(function() {
        $('#ParentUser').change(function() {

            mappedModel.changedParentUser = true;
            mappedModel.ParentUser($(this).val());

            $.ajax({
                url: '@Url.Action("GetAssignedUsers", "RoleAssignments")',
                type: 'POST',
                data: ko.toJSON(mappedModel),
                contentType: 'application/json; charset=utf-8',
                success: function(data) {
                    mappedModel.AssignedUsers(data);
                }
            });

        });
    });

This code works when I run it locally no problems, it only has the error when I try and run it on production. Please help.

EDIT:

Trying the below solution of making my AJAX action only have one parameter did not work:

Here is the model I am passing:

public class AssignModel : ActionModel
{
    public bool CanAssignAll { get; set; }
    public KeyValueModel ParentRole { get; set; }
    public Guid? ParentUser { get; set; }
    public KeyValueModel AssigneeRole { get; set; }

    public List<KeyValueModel> AssignedUsers { get; set; }

    public List<KeyValueModel> ParentUsers { get; set; }
    public List<KeyValueModel> AssigneeUsers { get; set; }
}

 public class ActionModel
{
    public bool ActionSuccess { get; set; }
    public string ActionMessage { get; set; }
    public bool CanEdit { get; set; }
    public bool CanCreate { get; set; }
}

public class KeyValueModel
{
    public Guid Id { get; set; }
    public string DisplayName { get; set; }
}

Those are the models that are being used. The stacktrace sure looks like a problem with Deserializing, but using trying to update the JsonValueFactoryProvider as outlined below doesn't work either.

EDIT AGAIN: There is something wrong with my model for sure, but I don't know what. I changed my ajax method to the original 3 parameters, and then in the jquery, just posted the data I needed instead of the whole model, and it worked, and the error went away. HOWEVER, then when I saved the object (also using an AJAX method and also passing in the full model as parameter), the same error happened. But there is nothing crazy looking about my model so I don't get it. I even tried changing the Guid? to just a Guid, to see if that would fix it, but nope.

Upvotes: 0

Views: 937

Answers (3)

SventoryMang
SventoryMang

Reputation: 10479

I figured out the problem was with the knockout mapping plugin. I should be using ko.mapping.toJSON() on the ajax POST instead of just ko.toJSON(). When using the mapping plugin your knockout model has a lot of extra properties then. I am not sure exactly what in those extra properties was causing the problem though, because I was doing this for all of my CRUD pages pretty much, but this specific page only had such an error. However, it's a good idea anyway since the POST data is much much smaller and the model is essentially 'POCO-fied'.

Upvotes: 2

RodneyTrotter
RodneyTrotter

Reputation: 1166

I can't be certain, but I think that MVC POST actions that accept JSON as the POST data can/should only accept a single parameter. In your case, your method signature should be something like this:

public JsonResult GetAssignedUsers(GetAssignedUsersModel getAssignedUsersModel)
{
   ...
}

and the model could be something like this:

public class GetAssignedUsersModel
{
    public Guid ParentUser {get;set;}
    etc...
}

NOTE: This works with MVC3 and later, not with MVC 1 and MVC 2. For those earlier versions, the single parameter should be a string and you would use JSON.NET to deserialize the string to your model, as Tomas suggested.

Upvotes: 0

Tomas Kirda
Tomas Kirda

Reputation: 8413

There is an issue while deserializing JSON to object. Use JSON.NET to deserialize objects, it will solve for you many issues down the road. See sample implementation here: https://gist.github.com/DalSoft/1588818

Upvotes: 0

Related Questions