Cascading dropdown in MVC4 with Knockout.js, JSON returns valid JSON according to validator but Jscript Invalid character error

StackOverflow https://stackoverflow.com/questions/17089095

Question

I have an MVC4 website which needs cascading dropdowns with highly dynamic data. I used the tutorials online and many of the stack exchange questions to build the query and javascript functions.

The versions I'm working with are VisualStudio 2012, jquery 2.0.1, knockout 2.2.1, dot net 4.5.

Request headers accept application/json and response content-type returns application/json. Content length of the response matches the number of characters in the content string returned.

What I have now is returning a JSON string that JSONLint validates as valid, but when I alert the same string, I get an invalid character. My child dropdown populates with the correct number of options, but the options are blank.

Relevant Code: Cascader.js

        function CascadingViewModel() {
        this.DataID = ko.observableArray([]);
    }

var objVM = new CascadingViewModel();
ko.applyBindings(objVM);

function FetchData() {

    var selStepKindID = $("#StepKindID").val();
    $.getJSON("/TestStep/GetDataList/" + selStepKindID, null, function (data) {
        objVM.DataID(data);
        alert($.parseJSON(data));
    });

}

(Copied and modified for my variables from the dotnet Expert Guide tutorial)

Controller routine returning the Json:

public ActionResult GetDataList(int id)
{
    var dataView = ViewToUse(Convert.ToInt32(id));
    var test = this.Json(dataView, JsonRequestBehavior.AllowGet);
    return this.Json(new { DataID = dataView }, JsonRequestBehavior.AllowGet);
}

(again, copied from the dotnet Expert Guide and modified for my variables)

Samples of the JSON returned and validated through JSONLint:

{"DataID":[{"Selected":false,"Text":"","Value":""},{"Selected":false,"Text":"1","Value":"txtUserName"},{"Selected":false,"Text":"2","Value":"txtPassword"},{"Selected":false,"Text":"3","Value":"txtClientCode"},{"Selected":false,"Text":"4","Value":"cmdLogon"},{"Selected":false,"Text":"5","Value":"cmdCancel"},{"Selected":false,"Text":"6","Value":"ForgotPassword"},{"Selected":false,"Text":"7","Value":"btnLogout"},{"Selected":false,"Text":"8","Value":"btnSearch"},{"Selected":false,"Text":"9","Value":"searchId"},{"Selected":false,"Text":"10","Value":"searchName"},{"Selected":false,"Text":"11","Value":"/reports/default.asp"},{"Selected":false,"Text":"12","Value":"You are not authorized to view this page"},{"Selected":false,"Text":"13","Value":"testFieldName"}]}

{"DataID":[{"Selected":false,"Text":"1","Value":"aname, xyzzzzzzzzz123, avalue, Supervisor"},{"Selected":false,"Text":"2","Value":"admin51, sadfgwagha51, avalue, External admin"}]}        

(from two separate calls)

The child dropdown:

        <select id="DataID" name="DataID" data-bind="options: DataID, optionsText: 'Text', optionsValue: 'Value', optionsCaption: ' -- Please select a test step kind -- '">
        </select>

What am I doing wrong and how do I fix it? I've spent two days trying to track this down and I'm at a total loss.

Was it helpful?

Solution

Based on your sample JSONs the data variable in your $.getJSON callback does not directly contain your array but it is wrapped within an object where the "DataID" property contains your actual array of elements.

So in your $.getJSON use data.DataID instead of data:

$.getJSON("/TestStep/GetDataList/" + selStepKindID, null, function (data) {
        objVM.DataID(data.DataID);
    }); 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top