简体   繁体   中英

How to iterate over object sent via AJAX JSON

I have the following JavaScript object:

var parameters = { "parameters" :
    [
        {
            "key": "feedbackSource",
            "value": "foo"
        }, {
            "key": "status",
            "value": "foo"
        }, {
            "key": "feedbackType",
            "value": "foo"
        }
    ]
};

console.log(JSON.stringify(parameters)) shows:

{"parameters":[{"key":"feedbackSource","value":"foo"},{"key":"status","value":"foo"},{"key":"feedbackType","value":"foo"}]}

AJAX:

$.ajax({
    type: "POST",
    url: "myPage.aspx/MyMethod",
    data: JSON.stringify(parameters),
    contentType: "application/json; charset=utf-8",
    dataType: "json"
});

Method:

[WebMethod]
public static void MyMethod(object parameters)
{

}

Question: How do I iterate over that object in C# to get the contents?

I have tried:

foreach (var p in (IEnumerable) parameters)
{
    foreach (var x in (IEnumerable) p)
    {
        var test = x;
    }
}

But test on the first iteration is a Key Value pair, with Key = "key" and Value = "feedbackSource" . On the second iteration, Key = "value" and Value = "foo"

And that doesn't seem like the correct way to iterate over the object. I would expect the Key = "feedbackSource" and Value = "foo" .

var parameters =
            {
                "parameters":
                [
                    {"feedbackSource": "foo", "status": "foo", "feedbackType": "foo"}
                ]
            };

create below class

public class mComputedProp
{
    public string feedbackSource { get; set; }
    public string status { get; set; }
    public string feedbackType { get; set; }
}

public class mcomputedprops
    {
        [JsonProperty("parameters")]
        public List<mComputedProp> mprops = new List<mComputedProp>();
    }

Modify your ajax call

$.ajax({
                type: "POST",
                url: '@Url.Action("getComputedProperty", "Home")',
                contentType: "application/json; charset=utf-8",
                async: false,
                dataType: "json",
                data: JSON.stringify({ listjson: JSON.stringify(parameters) })                    
            });


[WebMethod]
    public void getComputedProperty(string listjson)
        {
            mcomputedprops mod = JsonConvert.DeserializeObject<mcomputedprops>(listjson);
            string asdf = mod.mprops[0].feedbackSource.ToString();
        }

"How do I iterate over that object in C# to get the contents"

After a good discussion with @Devlin about this - the following conclusion has been reached:

Current JSON data structure

The JSON string that is being generated (from the page) is a little confusing to say the least.

The existing data structure of

{ "parameters" : [ { "key": "feedbackSource", "value": "foo" }, { "key": "status", "value": "foo" }, { "key": "feedbackType", "value": "foo" } ] };

Was very confusing and obfuscated the data somewhat - making it very hard to traverse and iterate the objects inside.

It appeared to be of key:(key/value) pairs/pairs ( wait, what? )

I proposed to structure a proper key/value pair structure to the JSON firstly (from within the page).

Like so:

{ "parameters" : 
    [ 
        { 
            "feedbackSource" : "foo" 
        }, 
        { 
            "status" : "foo" 
        }, 
        { 
            "feedbackType" : "foo" 
        } 
    ] 
} 

What is the ModelBinder doing?

As per @Devlin's screenshot: 调试屏幕截图

The ModelBinder was cleverly assiging parameter as a Dictionary<string, object> , because it recognised the JSON as key/value pairs - in which the values were yet again key value pairs .

Obviously, every type in C# derives from object , so accepting this was just boxing it in an object .

Thus why other suggestions of casting to a string weren't successful.

ASP.NET has a ModelBinder which is able to detect types of objects passed to methods, to make it easier when getting data out in the method.


Passing in/using the right type

Suggestion 1

Cast the object parameter in the MyMethod signature to a Dictionary<string, string> (do it safely, where possible)

Like so:

var paramsDict = parameters as Dictionary<string, object>;
if (paramsDict != null)
{
    // Iterate over the dictionary in here
}

Suggestion 2

Seeing as we know that the object parameters is already of type Dictionary<string, object> (thanks to some wizardry by the ModelBinder), we could just use this type in the MyMethod signature, instead.

Like this:

[WebMethod]
public static void MyMethod(Dictionary<string, object> parameters)
{
    // Iterate in here
}

Iterating the data

Now that you've got a nice and easy to use Dictionary<string, object> , it is simple to iterate over it and grab the values from there.

Like this:

foreach (var param in paramsDict) // or "... in parameters" if you're using suggestion 2
{
    var key = param.Key;
    var value = param.Value;

    // Manipulate/persist the data
}

It's up to you how you then manipulate/persist the data, but this should give you a starting point of getting the data from your JSON object.

Summary

  • Change your JSON structure to be "proper" key/value pairs
  • Default ModelBinder is able to assign the JSON as a C# Dictionary<string, object>
  • Either change the MyMethod signature to accept Dictionary<string, object> type for parameter , or cast the parameter object to a Dictionary (both should work the same)
  • Iterate each item in the Dictionary . You can then access the Key s and Value s of each item, and then manipulate the data however you wish

Furthermore
Given that your JSON string is passing in key/value pairs of string and string , I suspect that you may safely use Dictionary<string, string> to be picked up by the ModelBinder, or when casting etc. confirmation may be needed on this, however

Hope this helps, and best of luck in your project! :)

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