【问题标题】:How to iterate over object sent via AJAX JSON如何遍历通过 AJAX JSON 发送的对象
【发布时间】:2016-07-16 06:46:55
【问题描述】:

我有以下 JavaScript 对象:

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

console.log(JSON.stringify(parameters)) 显示:

{"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"
});

方法:

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

}

问题:如何在 C# 中迭代​​该对象以获取内容?

我试过了:

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

但第一次迭代中的test 是一个键值对,有Key = "key"Value = "feedbackSource"。在第二次迭代中,Key = "value"Value = "foo"

这似乎不是迭代对象的正确方法。我希望Key = "feedbackSource"Value = "foo"

【问题讨论】:

  • 你在服务器上使用什么框架?它是一个 ASMX WebService 吗?
  • @MartinHN - 这是 ASP.NET v 3.5

标签: javascript c# json


【解决方案1】:

“如何在 C# 中迭代​​该对象以获取内容”

在与@Devlin 就此进行了良好讨论后 - 得出了以下结论:

当前 JSON 数据结构

至少可以说,正在生成的 JSON 字符串(从页面)有点令人困惑。

现有的数据结构

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

非常令人困惑并且在某种程度上混淆了数据 - 使得遍历和迭代内部对象非常困难。

它似乎是键:(键/值)对/对(等等,什么?

我建议首先(从页面内)为 JSON 构建一个适当的键/值对结构。

像这样:

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

ModelBinder 在做什么?

根据@Devlin 的截图:

ModelBinder 巧妙地parameter 指定为Dictionary<string, object>,因为它将 JSON 识别为键/值对——其中的值又是键值对 em>。

显然,C# 中的每种类型都派生自 object,因此接受它只是将其装箱到 object 中。

因此,为什么其他投射到 string 的建议没有成功。

ASP.NET 有一个 ModelBinder,它能够检测传递给方法的对象类型,以便在方法中获取数据时更容易。


传入/使用正确的类型

建议一

MyMethod 签名中的object parameter 转换为Dictionary<string, string>(尽可能安全地进行)

像这样:

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

建议二

既然我们知道object parameters 已经是Dictionary&lt;string, object&gt; 类型(感谢ModelBinder 的一些魔法),我们可以只在MyMethod 签名中使用这种类型。

像这样:

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

迭代数据

现在您已经有了一个很好用且易于使用的Dictionary&lt;string, object&gt;,可以很简单地对其进行迭代并从中获取值。

像这样:

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
}

然后由您决定如何操作/保存数据,但这应该为您提供从 JSON 对象获取数据的起点。

总结

  • 将您的 JSON 结构更改为“正确的”键/值对
  • 默认 ModelBinder 能够将 JSON 分配为 C# Dictionary&lt;string, object&gt;
  • 要么将MyMethod 签名更改为接受parameterDictionary&lt;string, object&gt; 类型,要么将parameter 对象转换为Dictionary(两者应该工作相同)
  • 迭代Dictionary 中的每个项目。然后,您可以访问每个项目的 Keys 和 Values,然后根据需要操作数据

此外
鉴于您的 JSON 字符串正在传递 stringstring 的键/值对,我怀疑您可以安全地使用 Dictionary&lt;string, string&gt; 被 ModelBinder 拾取,或者在投射等时。确认可能是然而,这需要

希望这对您有所帮助,并祝您的项目好运! :)

【讨论】:

  • if (paramsString != null) 为假。换句话说,paramString 为空。为什么?
  • 如果parameters object 不是(出于某种原因)字符串,这是一个安全的转换检查。使用parameters as string 进行转换不会抛出异常(如(string)parameters 转换),而是会创建一个null string - 因此null 检查。
  • 当我将参数转换为字符串时,它为空。这是我在调试中看到的:imgur.com/0NUtqzf
  • 那么这可以解释为什么当您将方法签名更改为 string parameters 时绑定无法正常工作 - 从外观上看,您的活页夹可能已经实际上意识到它已经是 IEnumerable&lt;KeyValuePair&lt;string, string&gt;&gt; 类型
  • 如果上述情况属实,那么您可以简单地将 parameters 转换为该类型,并以与上述类似的方式对其进行迭代:foreach (var param in paramsKVPs) { key = param.Key; value = param.Value; ... }
【解决方案2】:
var parameters =
            {
                "parameters":
                [
                    {"feedbackSource": "foo", "status": "foo", "feedbackType": "foo"}
                ]
            };

在类下创建

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>();
    }

修改你的 ajax 调用

$.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();
        }

【讨论】:

  • 如果可能的话,我想避免这种情况。我想发送一个对象。
  • 根据您的评论修改了答案
  • 进入 MyMethod 后如何枚举data
  • data.feedbackSource, data.status, data.feedbackType
  • 所有的值都是空的? var test = data.feedbackSource; 显示test is null
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多