Можно ли отправить словарь с сервера на клиент C #?

1

Поэтому я могу отправлять простые объекты, такие как строки, без проблем. Я также могу отправить тот же словарь на свой javascript-клиент. Тем не менее, я не могу заставить своего клиента С# забрать его. Я предполагаю, что это связано с тем, что в javascript-клиенте отправляемый тип не нужно указывать, но в С# он делает это.

Здесь настройка клиента

 connection = new HubConnection(ServerURI);
 hubProxy = connection.CreateHubProxy("ControllerHub");
 hubProxy.On<Dictionary<Tuple<string, string>, RequestEntry>>("ReceiveTickerStateData", overviewDictionary => receiveTickerStateData(overviewDictionary));
 connection.Start().Wait();

Вот код сервера, который запускается для отправки словаря, но клиент так и не получил его.

public void GetTickerStateData()
{
    Clients.Caller.ReceiveTickerStateData(DealTickerState.Instance.GetRequestDict);
}

Любые идеи или идеи приветствуются. Благодарю!

------------------------Additions

Дальнейшее тестирование показало, что я использую кортеж (string, string) в качестве ключа для словаря. По-видимому, десериализатор JSON не знает, как справиться с этим. Дает мне ошибку:

Не удалось преобразовать строку (DEFAULT, IDCO) в тип словаря

System.Tuple'2 [System.String, System.String]. Создайте TypeConverter для преобразования из строки в объект типа ключа. Path '[' (DEFAULT, IDCO) ']', строка 1, позиция 19.

Я получил это путем ручного сериализации и отправки строки.
Я попытался отправить словарь только с строкой в качестве ключа, и он отлично работает как в сериализованной строке, так и в том, что есть. (т.е. автоматическое сериализация сигнала)

Итак, теперь, чтобы решить, я могу создать конвертер типов? или я отправляю данные, используя более простую структуру коллекции, которая работает.

  • 1
    Можете ли вы добавить класс RequestEntry к вашему вопросу? Он должен иметь одинаковую реализацию как на клиенте, так и на сервере. Можете ли вы также включить что-нибудь, отслеживаемое клиентом SignalR ?
  • 0
    Смотрите выше правки.
Теги:
signalr
signalr.client

3 ответа

0
Лучший ответ

Кажется, что реальный ответ "Да", это возможно, но вам нужно написать настраиваемый конвертер JSON. Вы можете найти больше информации об этом здесь, хотя ответ кажется немного неполным.

Как правильно сериализовать кортеж в качестве ключевого словаря

2

Да, как JSON. Используйте JSON.NET, включенный JavaScriptSerializer не будет работать. Вы можете получить JSON.NET из NuGet. Преобразуйте словарь в JSON и отправьте его в виде строки. На стороне клиента просто десериализуйте его, используя встроенный метод JSON.parse().

  • 1
    Signalr уже использует Json.NET.
  • 0
    Я ценю быстрый ответ. Я попробовал ваше предложение в пятницу. Закончил тестирование этим утром. Пожалуйста, смотрите мое редактирование.
1

Вы также можете создать промежуточный тип, который хранит словарь во время передачи (я использую List<KeyValuePair<T1,T2>>), важно, чтобы вы проверяли отсутствие дублирующих ключей при десериализации этого из клиента.

[Serializable]
public class SerializableDictionary<T1,T2>
{
    public List<KeyValuePair<T1,T2>> SerializedDictionary { get; set; }

    public SerializableDictionary( Dictionary<T1,T2> dictionary )
    {
        if( dictionary != null && dictionary.Count > 0 )
        {
            SerializedDictionary = dictionary.Select( item => item ).ToList();
        }
        else 
        {
            throw new ArgumentNullException( "Cannot serialize a null or empty dictionary" );
        }
    }

    public static explicit operator SerializableDictionary<T1,T2>(Dictionary<T1,T2> dictionary) 
    {
        return new SerializableDictionary<T1,T2>(dictionary);
    }

    public static explicit operator Dictionary<T1,T2>(SerializableDictionary<T1,T2> dictionary) 
    {
        if ( dictionary.SerializedDictionary == null ) return null;
        return dictionary.SerializedDictionary.ToDictionary( item => item.Key, item => item.Value );
    }
}

Этот метод не работает для каждого словаря (например, хранится в исключениях), поскольку они не могут быть легко дополнены для этого словаря, поддерживающего службу.

  • 1
    К вашему сведению - эту технику также можно использовать для сопоставления Tuple <String, String> с универсальным типом <T, T>, который, вероятно, не попадет в те же проблемы секьюритизации.
  • 0
    Это определенно хорошая альтернатива, однако я нашел другой вопрос, отвечающий на мою проблему, который я разместил ниже.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню