javascript - WebApi odata: แปลงเลขยาวเป็นสตริง
ฉันกำลังย้ายจาก WCF Data Service ไปยัง Web API odata v4 WCF Data Service ทำการแปลงค่า long เป็นสตริงในเครื่องหมายคำพูด:
{
"value":[{
"ID":"4527895973896126465"
},{
"ID":"4527895973896126466"
}]
}
Web API odata ไม่:
{
"value":[{
"ID":4527895973896126465
},{
"ID":4527895973896126466
}]
}
นี่หมายความว่าฉันสูญเสียความแม่นยำของตัวเลข 64 บิทระหว่างการทำ JSON.parse ใน JavaScript เนื่องจากตัวเลขใน JavaScript มีเพียง 53 บิทเท่านั้น
WebApi มีกลไกในตัวเพื่อจัดการค่าตัวเลขยาวเป็นค่าสตริงหรือไม่? ฉันกำลังคิดถึงส่วนหัว IEEE754Compatible แต่ส่วนหัวนี้ไม่มีผลต่อการตอบกลับที่สร้างขึ้น ฉันพลาดอะไรไปหรือเปล่า?
วิธีแก้ปัญหาอีกวิธีหนึ่งคือการถอดรหัสตัวเลข 64 บิตเป็นค่าสตริงในระหว่างการทำ JSON.parse ทางฝั่งลูกค้า ทำได้ไหม?
คำตอบ #1
ในที่สุดฉันก็ทำให้สิ่งนี้ใช้งานได้ OdataLib แท้จริงแล้วรองรับสิ่งนี้โดยพารามิเตอร์ IEEE754Compatible มันจะตรวจสอบส่วนหัว Content-Type ของการตอบสนองเพื่อดูว่าพารามิเตอร์นั้นมีอยู่หรือไม่
เรื่องคือ ค่าหัวเรื่องนั้นจะไม่ถูกส่งต่อไปยังหัวเรื่องของการตอบกลับโดยอัตโนมัติโดยเฟรมเวิร์กเว็บ API คุณจะต้องทำเอง ฉันได้สร้างคลาสที่สืบทอดจาก ODataController ซึ่งแก้ไขพารามิเตอร์ IEEE754Compatible ลงในหัวข้อ Content-Type ของการตอบกลับดังนี้:
public abstract class ODataControllerIEEE754Compatible : ODataController
{
private void PatchResponse(HttpResponseMessage responseMessage)
{
if (responseMessage != null && responseMessage.Content != null)
{
if (this.Request.Content.Headers.GetValues("Content-Type").Any(
h => h.Contains("IEEE754Compatible=true")))
{
responseMessage.Content.Headers.TryAddWithoutValidation(
"Content-Type", "IEEE754Compatible=true");
}
}
}
public override Task<HttpResponseMessage> ExecuteAsync(
HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
var response = base.ExecuteAsync(
controllerContext, cancellationToken);
response.Wait(cancellationToken);
PatchResponse(response.Result);
return response;
}
}
ตอนนี้โดยการส่งพารามิเตอร์ IEEE754Compatible=true ในหัวข้อ Content-Type ฉันจะได้รับค่าตัวเลขยาวทั้งหมดที่ถูกแปลงเป็นสตริง JSON:
GET http://localhost/some/url HTTP/1.1
OData-Version: 4.0;
Content-Type: application/json;odata.metadata=minimal;IEEE754Compatible=true;charset=utf-8
Cache-Control: no-cache
HTTP/1.1 200 OK
Content-Type: application/json;odata.metadata=minimal;IEEE754Compatible=true
Server: Microsoft-HTTPAPI/2.0
OData-Version: 4.0
{
"@odata.context":"http://localhost/some/url","value":[
{
"ID":"4527895973896126465", ...
คำตอบ #2
แม้ว่าฉันจะไม่รู้เกี่ยวกับ ASP.net มากนัก แต่ฉันสามารถให้ regex ที่สามารถใช้เพิ่มเครื่องหมายอัญประกาศรอบตัวเลขขนาดใหญ่ใน JSON ได้ ที่นี่ฉันตั้งค่าให้เป็นตัวเลขที่มี 16 หลักขึ้นไป
http://jsfiddle.net/yryk70qz/1/
value.replace(/:\s*(\d{16,})(\s*[,\}])/g, ':"$1"$2');
คุณสามารถทำได้กับตัวเลขทั้งหมดโดยไม่คำนึงถึงความยาวของพวกมันด้วย:
value.replace(/:\s*(\d+)(\s*[,\}])/g, ':"$1"$2');
(ได้รับแรงบันดาลใจจากคำถามนี้: แปลงค่าจำนวนเต็มทั้งหมดเป็นสตริงใน JSON)
