Веб-сервис / сериализация ASMX: как принудительно включить свойство «__type» в javascript

#c# #javascript #web-services #json #asmx

#c# #javascript #веб-сервисы #json #asmx

Вопрос:

Я работаю с веб-сервисами asmx и сериализую / десериализую множество данных через них для панели администратора JSON, над которой я работаю.

Когда информация загружена, я вызываю веб-сервис, который загружает массив User[] в javascript. Однако у меня есть около 25 подклассов User с их собственными уникальными свойствами, которые фактически загружаются этим вызовом веб-сервиса. Кажется, что загрузка их таким образом работает нормально, но при сохранении возникают некоторые проблемы.

Метод save принимает массив User[] для сохранения. В большинстве подклассов в javascript нет подсказки __type, и десериализация завершается неудачей. Кажется, это отлично работает на классах, у которых есть свойство __type.

Итак, мой вопрос заключается в следующем. Как я могу принудительно включить __type в объекты javascript, которые сериализуются?

Вот мой вызов C # для загрузки объектов (немного упрощенный) на случай, если вам это понадобится:

 [WebMethod(EnableSession = true)]
public User[] GetUsersInGroup(int UserGroupID)
{
    List<User> UsersInGroup = User.GetUsersInGroup(UserGroupID);
    return UsersInGroup.ToArray();
}
  

И вот метод сохранения:

 [WebMethod(EnableSession = true)]
public void SaveUsers(User[] Users)
{
        foreach (User CurUser in Users)
        {
            CurUser.Save();
        }
}
  

И, как и было запрошено, заголовок сервиса:

   [ScriptService]
    public class FormFields : System.Web.Services.WebService
    {
  

А JSON (упрощенный) — комментарий показывает, чего там нет:

 {
    "d": [
        {
            "__type": "Tools.User.AccountingUser",  /* This is missing */
            "UserID": 3934,
            "HasQBAccess": true 
        },
        {
            "__type": "Tools.User.PowerUser",
            "UserID": 3937,
            "AccessDB": true,
            "AccessFTP": true 
        } 
    ] 
}
  

Комментарии:

1. Пожалуйста, покажите начало класса веб-сервиса. Опубликованный вами код даже не вернет XML, доступный только для JSON.

2. Добавил начало сервиса к вопросу. Раньше у меня был атрибут [ScriptMethod(ResponseFormat=ResponseFormat.Json)], чтобы сделать его JSON, но я изменил его на xml по умолчанию в надежде, что это решит мою проблему… Этого не произошло. Однако для меня действительно не имеет значения, сериализован / десериализован ли его JSON или XML.

3. @ChrisG: XML не будет использоваться __type . Это может использовать xsi:type .

4. Да, но когда он попадает в javascript, он по-прежнему имеет __type в качестве свойства, независимо от xml или json. И похоже, что . net знает, что с ним делать в любом случае. Моя проблема на самом деле заключается в том, что __type в первую очередь попадает в объект js

5. @ChrisG: пожалуйста, опубликуйте пример неправильного вывода и покажите, как бы вы хотели, чтобы это выглядело.

Ответ №1:

В интересах получения какого-то ответа, который работает, даже если он не очень хороший.

Пока что лучший ответ, который я могу найти, — добавить действительно длинное уродливое определение функции в мой веб-сервис. Мне никогда не нужно его вызывать, просто позволяя ему находиться там, C # распознает типы:

 [WebMethod(EnableSession = true)]
public void ThisMethodSucks(AccountingUser u1, PowerUser u2, AdminUser u3, DatabaseUser u4, ADAdministratorUser u5, PSUser u6, NUTUser u7, TechUser u8, ...[all classes here])
{
      //this method never needs to get called, just sits here.
}
  

Комментарии:

1. Принял мой собственный ответ здесь, поскольку прошло более года, а я все еще не нашел чего-то лучшего, что работает в веб-сервисах asmx.