将JSON数据传递给ASP.Net Core 2 Web API

3

我知道这个问题已经被问了很多次,但之前的解决方案都没能帮助我解决我的问题(其实这似乎是一个非常简单的问题)。 我只想向我在控制器类中创建的Post方法发送一个Json对象。 以下是我控制器类的有趣部分:

[Route("api/[controller]")]
public class CodeController : Controller
{
    [HttpPost]
    public void Post([FromBody] InfoNegozio value)
    {
       return;
    }
}

我会很简单地设置数值,以下是InfoNegozio类:

public class InfoNegozio
    {
        public int IdNegozio { get; set; }
        public string NomeNegozio { get; set; }
        public int AttesaStimata { get; set; }
        public DateTime UltimoAggiornamento { get; set; }
    }

这是用于向该API发送数据的代码:
var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
    $.ajax({
        url: "api/Code",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify(myData)
});

JQuery代码只调用WebAPI控制器,value字段是非空的InfoNegozio对象,但字段IdNegozioAttesaStimata始终为0。

我使用Razor页面项目中的控制器,必须在Startup.Configure方法中添加此代码行才能使其正常工作(使用“它”表示其他WebAPI GET方法)。

app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

有什么想法吗?

编辑过的

使用Postman,我弄清楚了正常调用和不正常调用之间的区别。通过Postman发布以下json是有效的:

{
    "IdNegozio": 1,
    "AttesaStimata": 36
}

很遗憾,使用jQuery和JSON.stringify时,我得到了这个结果(请注意值上的双引号):
 {
     "IdNegozio": "1",
     "AttesaStimata": "36"
 }

这个不起作用!Json stringify与.NET Core Web Api不兼容吗?可能没有一种干净的方法使这两个库协同工作吗?

编辑2

最终我手动构建了json,强制jquery发送“我的版本”,所以我的js代码现在看起来是这样的:

var myData = '{ "IdNegozio": '+idNegozio+', "AttesaStimata": '+tempoAttesa+' }';
    $.ajax({
        url: "api/Code",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: myData
});

无论如何,我不喜欢这个解决方案,因为它似乎没有使用正确的方式来构建JSON对象,所以任何更聪明的解决方案都将不胜感激。


只是确认这是一个服务器端问题,您是否尝试使用Postman之类的工具POST JSON?如果您遇到相同的问题,那么至少您可以确定它是服务器端的问题,而不是您的jQuery出现了奇怪的问题。如果您POST字符串和DateTime字段,它们也是null/empty吗? - Bryan Lewis
@jandrew:客户端正在访问正确的端点。通过Postman,我发现问题在于JSON的序列化。请查看EDIT标题后的部分,我展示了两个略有不同的JSON。一个是手动使用Postman创建的,它可以工作,另一个来自jQuery调用,但无法工作。在无法工作的情况下,对象已初始化,但两个感兴趣的属性都设置为0,尽管在JSON有效负载中存在值。请注意,这两个属性都是int类型,没有涉及字符串。 - themarcuz
刚刚重新阅读了您的编辑内容,我想我知道问题出在哪里了。您正在使用哪个JSON序列化框架?除非您使用的是.NET Core 3,否则我会认为默认使用的是Newtonsoft JSON,除非您手动更改了设置。问题可能出现在.NET Core应用程序的某些序列化设置中。这很可能就是为什么您的Postman请求在整数值周围没有引号时能够正常工作的原因。 - jdewerth
@jandrew:我正在使用 .net core 3.1,我没有更改序列化引擎,也没有进行任何有关 JSON 序列化的配置。有什么地方可以让我查看吗? - themarcuz
请查看我的答案帖子。我相信你的一些问题可能是由于你设置控制器的方式引起的。你需要将其设置为API控制器,以便正确配置处理JSON请求。 - jdewerth
显示剩余5条评论
2个回答

0
如果您想像您提供的第一种方式那样编写,可以使用parseInt来确保传递int类型数据。
尝试这段代码:
      var myData = { "IdNegozio": parseInt(idNegozio), "AttesaStimata": parseInt(tempoAttesa) };
        $.ajax({
            url: "api/Code",
            type: "POST",
            contentType: "application/json",
            dataType: "json",
           data: JSON.stringify(myData) 
        });

如果您使用的是Core 3.x版本,还有另一种选择:

  • 安装Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.x

  • 在startup.cs的ConfigureServices中添加services.AddControllersWithViews().AddNewtonsoftJson();

完成这两个步骤后,您可以使用最初使用的json格式。

var myData = { "IdNegozio": idNegozio, "AttesaStimata": tempoAttesa };
                        $.ajax({
                            url: "api/ApiCode",
                            type: "POST",
                            contentType: "application/json",
                            dataType: "json",
                           data: JSON.stringify(myData)

                        });

0
创建一个答案,以便我们不必在您的帖子上有数百万条评论。这是一个 ASP.NET Core 3.1 Web API 项目,对吗?如果是这样,请尝试进行以下几个更改,看看是否可以解决问题。
从 ControllerBase 继承而不是完整的 Controller 类。还要将 [ApiController] 属性添加到 CodeController 类中。然后,在您的 Post 操作中,从 InfoNegozio 参数中删除 [FromBody] 属性。像这样:
[Route("api/[controller]")]
[ApiController]
public class CodeController : ControllerBase
{
    [HttpPost]
    public IActionResult Post(InfoNegozio value)
    {
       return Ok(value);
    }
}

看看是否有任何修复。在模型绑定期间出现了一些问题,这让我相信您的JSON序列化配置出了问题。如果您可以发布您的Startup.cs,那么我们就可以看看是否可能存在配置错误。我刚刚打开了一个.NET Core 3.1 Web API项目并测试了我的控制器,它按预期工作。所以试试看,也许可以解决问题。这些项目将影响控制器的配置,因此,如果它是API控制器,处理标准API请求(application/json),则应进行配置。您可以在ASP.NET Core 3.1文档中阅读具体信息,但是正确设置为API Controller将确保正确序列化您的JSON请求。现在,您已将其设置为MVC控制器,这很可能是您遇到问题的原因。

编辑:此外,请考虑从控制器操作返回IActionResult。这可能会使测试更容易,因为您实际上可以接收有助于找到错误的响应。然后只需将return;更改为return Ok();更新代码示例以反映此更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接