【问题标题】:Sending JSON data in API via Ajax error and JSON data traversing problem通过 Ajax 错误和 JSON 数据遍历问题在 API 中发送 JSON 数据
【发布时间】:2020-02-12 17:56:36
【问题描述】:
var data = {
        "ApplicationName": "Zadmin",
        "KanMainGroupList":
            [{
                "MainGroupName": "Settings",
                "KanSubGroupList": [{
                    "SubGroupName": "Signatures",
                    "SubGroupURL": "Common/HHALevelSettings.aspx",
                    "SubGroupQueryString": "HHA_ID=$HHA_ID$&HHAName=$HHA_Name$",
                    "KanFeatureSetList":
                        [{
                            "FeatureName": "Client Sign pop-up",
                            "Keywords": "Client,sign"
                        }],
                    "KanNanoGroupList": [{
                        "NanoGroupName": "Nano1",
                        "NanoGroupURL": "URL1",
                        "NanoGroupQueryString": "",
                        "KanFeatureSetList": [
                            {
                                "FeatureName": "",
                                "KeyWords": ""
                            }
                        ]
                    }]
                }
                ]
            }

            ]
    };

我有一个包含上述 JSON 数据的 mongo 文档。现在,当我尝试通过 jquery ajax 发送这些数据时,它会抛出错误“输入格式无效”或一些语法错误。 ajax cal如下:

$.ajax({
            url: 'api/HelpAPI',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(data),               
            success: function (data) {
                console.log(data);
                console.log("success");
            },
            error: function () {
                console.log("error");
            }
        }).done(function () {

        })

控制器如下:

    [HttpPost]
    public void Post([FromBody] string value)
    {

          //i tried to use FromForm in place or FromBody
          //i tried to use object datatype for value and  dynamic as well but in object the data 
               //doesn't come and in dynamic it is very difficult to work upon.
    }

最后使用下面的方法我可以在value中正确获取数据。

    [HttpPost]
    public void Post([FromBody] KanFeatureHelp value)
    { 
        List<KanMainGroup> mainGrp = new List<KanMainGroup>();
        List<KanSubGroup> subgrp = new List<KanSubGroup>();
        List<KanNanoGroup> nanogrp = new List<KanNanoGroup>();
        List<KanFeatureSet> SubGrpfeatureset = new List<KanFeatureSet>();
        List<KanFeatureSet> NanoGrpfeatureset = new List<KanFeatureSet>();

        //mainGrp = value.KanMainGroupList;
        //subgrp = value.KanMainGroupList;

        mainGrp = value.KanMainGroupList;
        foreach(var i in mainGrp)
        {
            subgrp = i.KanSubGroupList;
            foreach (var j in subgrp)
            {
                nanogrp = j.KanNanoGroupList;
                SubGrpfeatureset = j.KanFeatureSetList;
                foreach (var k in nanogrp)
                {
                    NanoGrpfeatureset = k.KanFeatureSetList;

                }
            }
        }
    }

KanFeatureHelp 的结构如下:

namespace WebApplication5.Models
{
    public class KanFeatureHelp
    {
        public string ApplicationName { get; set; }
        public List<KanMainGroup> KanMainGroupList { get; set; }

    }

    public class KanMainGroup
    {
        public string MainGroupName { get; set; }
        public List<KanSubGroup> KanSubGroupList { get; set; }
    }

    public class KanSubGroup
    {
        public string SubGroupName { get; set; }
        public string SubGroupURL { get; set; }
        public string SubGroupQueryString { get; set; }
        public List<KanFeatureSet> KanFeatureSetList { get; set; }
        public List<KanNanoGroup> KanNanoGroupList { get; set; }
    }

    public class KanNanoGroup
    {
        public string NanoGroupName { get; set; }
        public string NanoGroupURL { get; set; }
        public string NanoGroupQueryString { get; set; }
        public List<KanFeatureSet> KanFeatureSetList { get; set; }
    }

    public class KanFeatureSet
    {
        public string FeatureName { get; set; }
        public string Keywords { get; set; }
    }
}

问题:

  1. 我的 API 调用有什么问题?一个人如何真正知道设置内容类型/数据操作以正确发送数据?如果有人想发送动态数据/对象怎么办?那么如何发送一些字符串数据呢?

  2. 是否可以将数据作为字符串发送,然后在 c# 代码中反序列化?

  3. 当前目标是在当前 Jsondata 中添加或删除任何 MainGroup / SubGroup / NanoGroup/ FeatureName,我认为这将需要遍历数据。如果我能得到一些关于如何做到这一点的指导,那将是非常有帮助的。

  4. 在当前工作场景下,我可以访问数据的唯一级别是 value.KanMainGroupList。此后它不显示任何子组列表或其他数据。执行错误吗?我应该改变什么吗?

非常感谢您的时间和精力。非常感谢。

【问题讨论】:

  • 在您的 ajax 调用中请设置 dataType: "json", 并重试。还可以尝试将 post 调用放在 try/catch bock 中,以查看是否有任何未处理的异常。如果你发现了,请分享。
  • @Searching jQuery Ajax 调用中的dataType 参数是预期的response 数据类型,只有在服务器发送不正确的Content-Type 标头时才需要设置它.它不是指您发送的数据类型 - 这就是 contentType 的用途。

标签: json ajax asp.net-core-webapi


【解决方案1】:

我的 API 调用出了什么问题

正如您已经发现的那样,这是因为服务器需要application/json 的有效负载。您需要在请求中包含这样的标头。

如何真正了解如何设置内容类型/数据操作以正确发送数据

如您所知,最常用的类型是:

  • application/x-www-form-urlencoded:提交表单时的初始默认类型。这也是大多数 ajax 客户端的默认类型(例如 XMLHttpRequest/axios/fetch/...)
  • multipart/formdata:当您要提交包含文件的表单时使用此类型。此外,如果您使用的是FormData api,则应使用内容类型。
  • application/json:随着 JSON 成为 REST 的事实上的标准负载,application/json 非常流行。

ASP.NET Core 可以从多个位置绑定数据。普通的 ASP.NET Core 控制器(而不是 [ApiController])将从路由/查询字符串/表单数据接收参数,除非您指定 [FromBody]。但是,与普通的 Controller 不同,[ApiController] 将隐式绑定来自正文 ([FromBody]) 的数据。总之,

  • 如果您需要 json 有效负载,请在服务器上添加 [FromBody]。另外不要忘记在您的请求中添加Content-Type: application/json
  • 如果您需要一个表单,application/x-www-form-urlencodedmultipart/formdata,您可以在服务器上添加一个 [FromForm],然后在您的请求中添加相关的 Content-Type。

如果有人想发送动态数据/对象怎么办

虽然我不认为接收动态数据是个好主意,但如果你愿意,你可以使用dynamic

那么如何发送一些字符串数据呢?

如果我可以将数据作为字符串发送,然后在 c# 代码中反序列化回来,是否有可能

是的。最简单的方法是使用application/x-www-form-urlencoded 发送像value=the-encoded-json-string 这样的有效负载。

或者,如果您想通过application/json 发送字符串,请参阅my thread here 了解更多详情。

当前目标是在当前 Jsondata 中添加或删除任何 MainGroup/SubGroup/NanoGroup/FeatureName,我认为这将需要遍历数据。

在当前工作场景下,我可以访问数据的唯一级别是 value.KanMainGroupList。

我相信遍历或使用 LINQ 都可以。但由于我们不了解场景,所以无法提供任何详细的建议。

您的实施没有问题。我最好的猜测是你想要一个流畅的 API 来访问子列表?如果是这种情况,请使用[SelectMany()](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.selectmany?view=netframework-4.8) 来展平子组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2015-02-13
    • 2016-04-20
    • 2016-11-06
    相关资源
    最近更新 更多