迁移到ASP.Net Core MVC后,JSON序列化/反序列化不起作用

3
我们正在将一个站点从ASP MVC .Net Framework迁移到.Net Core。在许多情况下,我们会从页面向控制器发出ajax POST请求:

js:

var request = { Name: "bar" };
$.ajax({
    url: "/Home/foo",
    type: "POST",
    data: JSON.stringify(request),
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    success: function (response) {
        console.log();
    }
});

c# 控制器:

[HttpPost]
public async Task<JsonResult> foo(FooRequest request)
{
    //request.Name is empty
    return Json(new { msg = "Success" });
}

c#模型:

public class FooRequest
{
    public string Name { get; set; }
}


这在 .Net Framework 中可以正常工作,但在 Core 中失败了,其中接收对象的所有属性都为 null。
我尝试使用了 AddJsonOptions
services.AddControllersWithViews()
    .AddJsonOptions(option =>
    {
        option.JsonSerializerOptions.PropertyNamingPolicy = null;
        option.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    });

...以及AddNewtonsoftJson

services.AddControllersWithViews()
    .AddNewtonsoftJson(option =>
    {
        option.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
    });

...但是它们都没有起作用。

我需要做什么才能在.Net Core中获得与.Net Framework相同的行为?

更新

我从Postman调用端点时得到了相同的行为(request.Name为空):

POST /home/foo HTTP/1.1
Host: localhost:44393
Content-Type: application/json

{ "Name": "bar" }

我还尝试过对请求进行序列化:

var request = { Name: "bar" };
$.ajax({
    url: "/Home/foo",
    type: "POST",
    data: request,
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    success: function (response) {
        console.log();
    }
});

...但结果相同。


应该更清楚一些,但是接收到的对象的所有属性都是空的。 - wmmhihaa
1
你检查了你要POST的内容吗?为什么要在你要POST的对象上调用JSON.stringify? - mason
因为那是在 .Net Framework 中使其工作的唯一方法。我很乐意进行更改,但是使用 data:request 时我遇到了相同的问题。 - wmmhihaa
1个回答

3
请将 FromBodyAttribute 添加到您的参数中:
[HttpPost]
public async Task<JsonResult> foo([FromBody] FooRequest request)
{
    //request.Name is empty
    return Json(new { msg = "Success" });
}

如果您的控制器使用ApiControllerAttribute进行了装饰,您可以省略此属性。


谢谢...只有一个简短的问题,是否能在Startup.cs中设置这个,因为我有许多这种类型的方法(常驻于我的普通Actions中)? - wmmhihaa
1
很遗憾,唯一的“全局”方法是使用ApiControllers进行Http请求,并使用普通控制器进行视图。因此,如果您在装饰有[ApiController]的控制器内重构api调用,则应该能够省略此步骤。 - Marco
你可以使用一个操作过滤器来完成它。 - Ian Kemp

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