【问题标题】:ajax call to "asp.net core WebApi" returns a strange/weird value对“asp.net core WebApi”的 ajax 调用返回一个奇怪/奇怪的值
【发布时间】:2021-11-13 09:53:20
【问题描述】:

我有一个 api 控制器,它返回一个包含两个对象列表的对象。

我希望当我使用 ajax 调用这个 api 时我会得到这个结果:
一个包含长值的对象和两个对象列表:

{
"userId":26000000000000228,
"paidInvoices":
[{"id":13060000000000039,"total":10},
{"id":13060000000000040,"total":20},
{"id":13060000000000041,"total":30}],
"unPaidInvoices":
[{"id":15060000000000039,"total":10},
{"id":15060000000000040,"total":20},
{"id":15060000000000041,"total":30}]
}

但我得到了意想不到的重复 ids(都以 40 结尾):

{
"userId":26000000000000228,
"paidInvoices":
[{"id":13060000000000040,"total":10},
{"id":13060000000000040,"total":20},
{"id":13060000000000040,"total":30}],
"unPaidInvoices":
[{"id":15060000000000040,"total":10},
{"id":15060000000000040,"total":20},
{"id":15060000000000040,"total":30}]
}

代码:

public class Invoice
{
    public long Id { get; set; }
    public decimal Total { get; set; }
}

public class Invoices
{
    public long UserId { get; set; }
    public List<Invoice> PaidInvoices { get; set; }
    public List<Invoice> UnPaidInvoices { get; set; }
}

[Route("NetApi/[controller]")]
[ApiController]
public class PurchasePaymentController : ControllerBase
{
    [HttpGet("Search/{id}")]
    public Task<Invoices> Search(long id)
    {
        var paid = new List<Invoice>
        {
            new Invoice {Id = 13060000000000039, Total = 10},
            new Invoice {Id = 13060000000000040, Total = 20},
            new Invoice {Id = 13060000000000041, Total = 30}
        };
        var unPaid = new List<Invoice>
        {
            new Invoice {Id = 15060000000000039, Total = 10},
            new Invoice {Id = 15060000000000040, Total = 20},
            new Invoice {Id = 15060000000000041, Total = 30}
        };
        return Task.FromResult(new Invoices {UserId = id, PaidInvoices = paid, UnPaidInvoices = unPaid});
    }
}

我已经尝试返回 JsonResult,它没有任何区别。
我从这个不使用任何布局的 razorPage 调用它:

@page
@model MyWebSite.Pages.Test.IndexModel
@{
    Layout = null;
}
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1>Welcome</h1>
<div id="result"></div>
<script>

    // if I use $.ajax or $.get , the result is the same (weird/unexpected result) 
    $(function () {
        $.ajax({
            type: "GET",
            url: "@Url.RouteUrl("NetApi", new {controller = "PurchasePayment", action = "Search", id = 26000000000000228})",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: getCallback
        });
    });

    $(function() {
        debugger;
        $.get("@Url.RouteUrl("NetApi", new {controller = "PurchasePayment", action = "Search", id = 26000000000000228})",
            getCallback, "json");
    });

    function getCallback(response) {
        console.log(JSON.stringify(response));
        debugger;
    }


    // but this load method works fine

    $(function() {
        $("#result").load("@Url.RouteUrl("NetApi", new {controller = "PurchasePayment", action = "Search", id = 26000000000000228})");
    });


</script>
</body>
</html>

在我的 Startup.cs 中

// ConfigureServices
services.AddMvc().AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            );

// Configure
app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapControllerRoute(
             name: "api",
             pattern: "api/{controller}/{action}/{id?}",
             defaults: new { controller = "login", action = "Index" });

            endpoints.MapControllerRoute(
                name: "NetApi",
                pattern: "NetApi/{controller}/{action}/{id?}");
            endpoints.MapRazorPages();
        });

【问题讨论】:

  • 是的,我已经尝试过了。 @格雷格

标签: c# jquery ajax asp.net-core asp.net-web-api


【解决方案1】:

我使用 Postman 测试了您的 Api,一切正常。所以问题是Javascript。如果您在 Id long 数字中删除了一个零,那么在 javascript 中也一切正常。

15060000000000039 这个值实际上并没有超过 JavaScript 中的最大数值,但是,这个值超出了“整数精度”的范围,有时也被称为整数精度大小,即 2 pow 53。发送了错误的数字:相反,文字 15060000000000039 和 13060000000000041 只能精确表示为 13060000000000040,因此 JavaScript 中从来没有正确的数值。 (积分范围约为 +/- 253。)问题在于 javascript 对大整数进行四舍五入的方式。

因此,如果您仍要使用 javascript,我可以提供的解决方法是将这些长数字作为字符串发送。或者,如果您需要处理数字,则有很多 javascript BigInt 库。但似乎您不需要它,因为它们只是发票号码。所以把你的班级改成这个

public class Invoice
{
    public string Id { get; set; }
    public decimal Total { get; set; }
}

和数据

var paid = new List<Invoice>
        {
            new Invoice {Id = "13060000000000039", Total = 10},
            new Invoice {Id = "13060000000000040", Total = 20},
     .... and so on

或者也许使用这个,你不需要改变任何东西

public class Invoice
{
        [JsonIgnore]
        public long Id { get; set; }
        public string InvoiceId { get { return Id.ToString(); } }
        public decimal Total { get; set; }
}

【讨论】:

    猜你喜欢
    • 2016-09-22
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多