【问题标题】:ASP.NET Core Razor ajax POST request data object is emptyASP.NET Core Razor ajax POST 请求数据对象为空
【发布时间】:2021-05-24 19:08:51
【问题描述】:

有一个简单的 ajax POST 请求必须stringify 一个简单的类并在 POST 请求的正文中传递它,但是服务器端的 Person 参数有空(默认)值

// javascript
var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": "31" };
$.ajax({
    type: "POST",
    url: "/UpdatePostBody?handler=Abc",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: JSON.stringify(person),
    headers: {
        RequestVerificationToken:
            $('input:hidden[name="__RequestVerificationToken"]').val()
    },
})
    .done(function (result) {
        console.log(result);
});

C# code
public IActionResult OnPostAbc(Person person)
{
    return new JsonResult("my result");
}

在服务器端,有一个简单的 ASP.NET Core Razor 页面,其中有一个方法会被命中并返回结果,但 person 参数成员没有值。

【问题讨论】:

    标签: ajax asp.net-core razor-pages


    【解决方案1】:

    你的 Pesron 数据为 null 是因为你在 Person 类中的 Ageint 类型。而你在 { "FirstName": "Andrew", "LastName": "Lock", "Age": "31" } 中的人是 string 类型,所以你无法获取它。另外,当您将 json 数据从 ajax 传递到处理程序时,您需要在处理程序中添加[FromBody]。这是一个演示:

    cshtml:

    <button onclick="postdata()">Abc</button>
    function postdata() {
            //change Age type to int
            var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": 31 };
            $.ajax({
                type: "POST",
                url: "/UpdatePostBody?handler=Abc",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                data: JSON.stringify(person),
                headers: {
                    RequestVerificationToken:
                        $('input:hidden[name="__RequestVerificationToken"]').val()
                },
            })
                .done(function (result) {
                    console.log(result);
                });
        }
    

    cshtml.cs:

    public IActionResult OnPostAbc([FromBody]Person person)
            {
                return new JsonResult("my result");
            }
    

    结果:

    【讨论】:

    • [FromBody] 当然被使用了,真正的问题是使用“31”字符串而不是 int 值,只是没有观察到拼写错误
    【解决方案2】:

    从POST body中读取数据解决

    public async Task<IActionResult> OnPostAbc()
    {
        var buffer = new byte[1024];
        using (var ms = new MemoryStream())
        {
            var read = 0;
            while ((read = await Request.Body.ReadAsync(buffer, 0, buffer.Length)) != 0)
            {
                ms.Write(buffer, 0, read);
            }
            ms.Seek(0, SeekOrigin.Begin);
            var person = 
                JsonConvert.DeserializeObject<Person>(Encoding.UTF8.GetString(ms.GetBuffer()));
            return new JsonResult($"my result: {person.FirstName} {person.LastName}");
        }
    }
    

    【讨论】:

      【解决方案3】:

      如您所见,JSON 是作为请求正文的一部分发送的。您可以(就像您在自己的回答中所做的那样)读取输入流并手动反序列化它,但是有一种更简单的方法是使用处理程序参数上的 [FromBody] 属性:

      public IActionResult OnPostAbc([FromBody] Person person)
      {
          return new JsonResult($"my result: {person.FirstName} {person.LastName}");
      }
      

      但是,如果您从 person 对象中的数字中删除引号,这仅适用于使用默认序列化程序 (System.Text.Json) 的 3.1:

      var person = { "FirstName": "Andrew", "LastName": "Lock", "Age": 31 };
      

      或者如果你add your own type converter

      之前的序列化程序 JSON.Net 对任一版本都很满意。并引用数字are supported in ASP.NET Core 5

      【讨论】:

      • 谢谢,但是这个方法不起作用:)(我试过了),可能是因为 Razor 页面?
      • 我已经更新了我的答案,加入了关于引用数字的注释
      猜你喜欢
      • 2021-06-20
      • 2018-03-30
      • 1970-01-01
      • 2017-08-18
      • 2019-04-01
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      相关资源
      最近更新 更多