.NET Добавляет JSON в строку, уже сериализованную с помощью DataContractJsonSerializer. - PullRequest
0 голосов
/ 06 сентября 2010

Я использую DataContractJsonSerializer для сериализации объекта в json, а затем возвращаюсь к клиенту с AJAX. Теперь мне нужно сериализовать другой объект, чтобы вернуться вместе с ним. Проблема в том, что MS "d" обернут вокруг JSON, что мешает мне просто объединять строки в одну строку JSON.

json = json & """,""SecurityGroups"": 1"

Возвращает:

{
    "d":"[{
        \"__type\":\"User:#HagarDB\",
        \"ID\":1
    }]\",
    \"SecurityGroup\": 1"
}

Любые предложения будут с благодарностью. Я бы предпочел не делать еще один вызов на сервер, чтобы получить другой объект.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2010

В вашем коде есть как минимум две проблемы. Первый: вы делаете сериализацию JSON дважды . Второе: вы не можете добавить строку JSON с другими данными, потому что в результате строка не будет больше в формате JSON.

Если вы используете атрибут [ScriptMethod(ResponseFormat = ResponseFormat.Json)] для веб-метода, возвращаемый вами объект будет автоматически сериализован в строку JSON . Таким образом, вы должны не сериализовать его вручную раньше.

Если объект, который вы хотите сериализовать, уже является строкой, то во время сериализации все предложения будут отменены (" будет заменено на \"). В вашем случае после ручной сериализации объекта вы получили строку [{"__type":"User:#HagarDB", "ID":1}], которая является правильной строкой JSON. Чтобы убедиться в этом, вы можете просто вставить строку в валидатор http://www.jsonlint.com/. Подробнее о формате JSON вы можете прочитать на http://www.json.org/.

Если вы добавите данные с другой строкой, такой как "SecurityGroup": 1 (которая не является строкой JSON, правильным будет {"SecurityGroup": 1}) с запятой между строками, вы получите строку

[{"__type":"User:#HagarDB", "ID":1}], "SecurityGroup": 1

что также неверно JSON. Правильный JSON будет что-то вроде

{ "MyArray": [ {"__type": "User:#HagarDB", "ID": 1 } ], "SecurityGroup": 1 }

В конце вы возвращаете строку в результате веб-метида и получаете результат в виде {d: result}, где все квоты будут экранированы:

{
    "d": "[{\"__type\":\"User:#HagarDB\", \"ID\":1}], \"SecurityGroup\": 1"
}

Это строка JSON, но это не то, что вам нужно.

Решение вашей проблемы очень простое. Ваш веб-метод может выглядеть следующим образом

[WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public MyResult MyMethod () {
    List<Users> users = BuildMyInnerInformation();
    return new MyResult { Users: users, SecurityGroup: 1};
}

public class MyResult {
    public List<Users> Users { get; set; }
    public int SecurityGroup { get; set; }
}
0 голосов
/ 06 сентября 2010

Как RPM1984 предлагает в комментарии, наилучшим решением, вероятно, будет создание класса, который содержит оба объекта, которые вы хотите сериализовать.

Если по какой-то причине это не вариант, вы можете сделать несколько простых манипуляций со строками, чтобы вставить новый объект:

// Find position of the ending characters }] 
var endPosition = json.IndexOf("}]");
// Insert the new json between the } and the ]
var newJson = json.Substring(0, endPosition +1) + newJson + json.Substring(endPosition);

Может быть, вам нужно добавить запятую перед новым json, и, возможно, вам нужно настроить строковые индексы, но вы поймете, в чем суть. Поскольку json - это простой формат строки, вы также можете рассматривать его как строку.

Это последнее предложение довольно уродливо, но оно должно работать как разовое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...