2015-05-07 4 views
3

Я переношу форму WCF Data Service в Web API odata v4. Службы WCF Data сделали serilize длинных значений в кавычках:WebApi odata: Сериализовать long как строка

{ 
    "value":[{ 
    "ID":"4527895973896126465" 
    },{ 
    "ID":"4527895973896126466" 
    }] 
} 

Web API OData не:

{ 
    "value":[{ 
    "ID":4527895973896126465 
    },{ 
    "ID":4527895973896126466 
    }] 
} 

Это означает, что я освобождаю точность числа 64-битного во JSON.parse в JavaScript, так как JavaScript цифры всего 53 бит.

Имеет ли WebApi механизм сборки для обработки длинных значений в виде значений строк? Я думаю об элементе заголовка IEEE754Compatible. Но это не влияет на сгенерированный отклик. Я что-то пропускаю?

Альтернативным решением было бы deserilaize 64-битные номера в виде строковых значений во время JSON.parse на стороне клиента. Это возможно?

ответ

1

Наконец я получил это работать. OdataLib действительно поддерживает это с помощью параметра IEEE754Compatible. Он проверяет ответ заголовка Content-Type, чтобы увидеть, присутствует ли этот параметр.

Вещь ist, что значение заголовка автоматически не распространяется на заголовок ответа с помощью web-инфраструктуры 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", ... 
1

Хотя я мало знаю об ASP.net, я могу дать вам rexeg, который можно использовать для добавления кавычек вокруг больших чисел в JSON. Здесь я устанавливаю его на любое число из 16 цифр или более.

http://jsfiddle.net/yryk70qz/1/
value.replace(/:\s*(\d{16,})(\s*[,\}])/g, ':"$1"$2');

Вы можете сделать это со всеми числами независимо от их длины с:
value.replace(/:\s*(\d+)(\s*[,\}])/g, ':"$1"$2');

(inpired по этому вопросу: Convert all the integer value to string in JSON)

+1

Спасибо за это. Я мог бы использовать это как «последнее средство», но мне интересно, возможно ли это (или нечто подобное) во время JSON.parse (для лучшей производительности). Лучше всего было бы получить старое поведение, которое у меня было с службами данных wcf на стороне сервера. – Jeldrik