2013-08-26 5 views
3

Некоторые сериализаторы JSON возвращают null для пустого поля данных строки, например.SuperObject не может обрабатывать пустую строку

{ 
"searchtext": null, 
"moretext": "contains something", 
"bookdate": 1377468000000, 
"empid": 12345, 
"listtype": 1 
} 

Я использую надобъект создать ISuperObject:

var 
    FJSONRequest: ISuperObject; 
then 
    FJSONRequest := SO(Request.Content); // Webservice request 

Это возвращает объект со строкой, содержащей текст 'null'.

Очевидно, что это связано с тем, что SuperObject не заботится о котировках ("searchtext": a дает те же результаты, что и "searchtext": "a").

Перед тем, как погрузиться в подпрограмму токенизатора 980 строк, есть ли у кого-нибудь решение?

Я имею в виду вдоль линий (или/или):

  • оставить нулевой DataField из объекта JSON

  • возвращается пустая строка

Если все остальное терпит неудачу, я все еще мог бы сделать

FJSONRequest := SO(StringReplace(Request.Content,': null,',':,',[rfReplaceAll])); 

, потому что мне нужно обрабатывать запросы, поступающие от приложения от одного из наших разработчиков, но это не является надежным.
(Нет, он не может подавить null потому there's a bug in the way Mono handles his datacontract.)

КСТАТИ Я испытываю точно the behaviour mentioned here, но в другой части кода надобъекта, так что обходной путь не делает работу.

+1

нуль это не то же самое, что и пустая строка. Это совершенно другое значение. Ваш 'StringReplace' не будет работать. Подумайте, что он делает с текстом, аннулированным. –

+0

Установите мой stringReplace() более жестким, но действительно не надежным. –

+1

Исправлена ​​ошибка, о которой вы указали [исправлено более чем за год до ее появления] (https://code.google.com/p/superobject/source/detail?r=55d5b03a621bc2570e50da5d745ded4e9b0dfa12). И токенизация «null» также кажется правильной, поскольку Super Object правильно анализирует действительный JSON и вообще отклоняет недействительный JSON. Найдите [обработку состояния 'tsNull' в' TSuperObject.ParseEx'] (https://code.google.com/p/superobject/source/browse/superobject.pas#3400). Вы уверены, что используете последнюю версию кода? –

ответ

3

не Официальный 1.2.4 ZIP файл в разделе загрузки http://code.google.com/p/superobject/downloads/list даты с 2010 года, но отдельные файлы http://code.google.com/p/superobject/source/browse имеют обновление вплоть до октября 2012 года

Если вы идете в этот последний URL и нажмите на Download zip вы можете извлеките их.

Эти обновленные файлы позволяют использовать специальный случай null.

Код по-прежнему «прощает», если опустить кавычки строкового значения:

{ 
"bookdate": 1377554400000, 
"searchtext": a, 
"listtype": 1 
} 

но теперь обрабатывает специальный случай

{ 
"bookdate": 1377554400000, 
"searchtext": null, 
"listtype": 1 
} 

, как если бы это был

{ 
"bookdate": 1377554400000, 
"searchtext": , 
"listtype": 1 
} 

или

{ 
"bookdate": 1377554400000, 
"listtype": 1 
} 

[Избегайте случайного типа nil или NULL]

Этот релиз поддерживает вплоть до VER230 (Delphi XE2) [Обратите внимание, что 'официального' 1.2.4 даже не компилировались на более поздних версиях Delphi], поэтому для более поздних версий Delphi вам придется исправлять директивы компилятора.

Оно также устанавливает следующее:

  • Когда значение с плавающей точкой произошло иметь точное целое значение, то JSON, будет иметь завершающий период:

    { "floatingpointvalue": 4.}

    Это теперь исправлено:

    { "floatingpointvalue": 4}

  • Ошибки в преобразованиях данных в течение дня, происходящих вокруг переключателя, на летнее время в скачках - да, неясно.
    Был ошибка в секции кода в окружении {$IFDEF WINDOWSNT_COMPATIBILITY}

Обратите внимание, что это по-прежнему определяется по умолчанию, я предлагаю вам отключить определить, например, с {.$IFDEF WINDOWSNT_COMPATIBILITY} [который должен работать на Windows NT в настоящее время?], которая позволяет преобразования даты-времени OS ручки:

{$ELSE} 
function TzSpecificLocalTimeToSystemTime(
    lpTimeZoneInformation: PTimeZoneInformation; 
    lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; 

function SystemTimeToTzSpecificLocalTime(
    lpTimeZoneInformation: PTimeZoneInformation; 
    lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; 
{$ENDIF}