Словарь объектов не работает как JSON - PullRequest
3 голосов
/ 04 сентября 2011

Я потратил WAY слишком много времени, пытаясь понять, как извлечь все значения, которые мне нужны, из моего приложения на C # с использованием JS и JSON. Он отлично работает, когда я просто использую простые структуры, такие как массив, но мне нужно иметь возможность увеличивать список во время выполнения.

Прямо сейчас, лучшее, что я мог выяснить, это создать словарь с возрастающим значением ключа, а остальные 3 значения - как объект класса. Однако, это, кажется, вылетает из моего приложения на C #.

Каков наилучший способ сделать это?

Соответствующий код C #:

public class ChatData
{
    string userName;
    string message;
    System.DateTime timestamp;

    public ChatData(string name, string msg)
    {
        userName = name;
        message = msg;
        timestamp = System.DateTime.Now;
    }
}

        else if (string.Equals(request, "getchat"))
        {
            //string since = Request.Query.since;

            Dictionary<int, ChatData> data = new Dictionary<int, ChatData>();

            data.Add(1, new ChatData("bob", "hey guys"));
            data.Add(2, new ChatData("david", "hey you"));
            data.Add(3, new ChatData("jill", "wait what"));

            return Response.AsJson(data);
        }

Соответствующий Javascript:

function getChatData()
{
    $.getJSON(dataSource + "?req=getchat", "", function (data)
    {
        //$.each(data, function(key, val)
        //{
            //addChatEntry(key, val);
        //})
    });
}

Ответы [ 2 ]

3 голосов
/ 04 сентября 2011

Вы не объяснили, что такое Response.AsJson и как оно реализовано, но если оно использует JavaScriptSerializer, вы получите следующее исключение:

Необработанное исключение: System.ArgumentException: Тип «System.Collections.Generic. Dictionary`2 [[System.Int32, mscorlib, Версия = 4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089], [ChatData, Test, Version = 1.0.0.0, Культура = нейтральная, PublicKeyToken = null]] 'не поддерживается для сериализация / десериализация словаря, ключи должны быть строками или объекты.

, что довольно очевидно. Вы не можете использовать целые числа в качестве ключей, если вы намерены JSON сериализовать эту структуру. Кроме того, поскольку ваш класс ChatData больше не имеет конструктора по умолчанию / без параметров, вы не сможете десериализовать строку JSON обратно в этот класс (но я думаю, вам это пока не нужно).

Таким образом, одним из возможных решений вашей проблемы будет использование:

Dictionary<string, ChatData> data = new Dictionary<string, ChatData>();
data.Add("1", new ChatData("bob", "hey guys"));
data.Add("2", new ChatData("david", "hey you"));
data.Add("3", new ChatData("jill", "wait what"));

Теперь, конечно, это сказанное и смотрящее на javascript, который вы закомментировали, и на то, что вы собираетесь делать, как я уже объяснил вам в вашем предыдущем вопросе , словари не сериализуются как массивы javascript, поэтому вы не может зациклить их.

Короче говоря, определите класс:

public class ChatData
{
    public string Username { get; set; }
    public string Message { get; set; }
    public DateTime TimeStamp { get; set; }
}

и затем заполните массив этого класса:

var data = new[]
{
    new ChatData { Username = "bob", Message = "hey guys" },
    new ChatData { Username = "david", Message = "hey you" },
    new ChatData { Username = "jill", Message = "wait what" },
};
return Response.AsJson(data);

и, наконец, потребляют:

$.getJSON(dataSource, { req: 'getchat' }, function (data) {
    $.each(data, function(index, element) {
        // do something with element.Username and element.Message here, like
        $('body').append(
            $('<div/>', {
                html: 'user: ' + element.Username + ', message:' + element.Message
            })
        );
    });
});
2 голосов
/ 04 сентября 2011

Почему бы просто не использовать типизированный список? Также вам понадобится конструктор по умолчанию для его сериализации / десериализации. Обратите внимание, как я изменил ваш класс для использования свойств также. Обратите внимание, что, как упоминает @rudolf_franek, вы можете добавить свойство ID в класс ChatData, если вам нужна возможность ссылки на него.

public class ChatData
{
     public ChatData()
     {
         TimeStamp = DateTime.Now;
     }
     public int ID { get; set; }
     public string Who { get; set; }
     public string Said { get; set; }
     public DateTime TimeStamp { get; set; }
}

...

var data = new List<ChatData>
{
    new ChatData { ID = 1, Who = "bob", Said = "hey guys" },
    ...
};

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