Сериализация IDictionary<string, object> в WCF

У нас есть приложение, для которого один из наших объектов DTO имеет свойство, типизированное как IDictionary<string, object>,

Я сейчас пытаюсь выставить этот объект через службу WCF. Это работает в некоторых случаях, но не в общем случае. Чтобы продемонстрировать проблему, рассмотрим следующие два метода:

[OperationContract]
public IDictionary<string, object> Test1()
{
    return new Dictionary<string, object>
    {
        { "testkey1", "newstringvalue"},
    };
}

[OperationContract]
public IDictionary<string, object> Test2()
{
    return new Dictionary<string, object>
    {
        { "testkey1", "newstringvalue"},
        { "testkey2", new object [] { "one" , "two", "three", } }
    };
}

Метод Test1() работает как положено, но когда я вызываю Test2(), я получаю странную ошибку времени выполнения на клиенте:

Время ожидания канала запроса в ожидании ответа после 00:01:00. Увеличьте значение тайм-аута, передаваемое вызову Request, или увеличьте значение SendTimeout в Binding. Время, выделенное для этой операции, могло быть частью более длительного времени ожидания.

Внутреннее исключение: удаленный сервер возвратил ошибку: (504) Время ожидания шлюза.

И это несмотря на то, что исключение было выдано мгновенно, т.е. На самом деле мне не пришлось ждать ни минуты для этого ответа. Ошибка не отображается на сервере.

Я подозреваю, что это связано с тем, что сериализатор не может сериализовать объект [], но это не то, что указано в ошибке.

Итак, мои вопросы:

  1. Что здесь происходит?
  2. Как мне обойти это, чтобы я мог правильно сериализовать свои объекты?

Благодарю.

2 ответа

Решение

Поскольку ни я, ни кто-либо из моих коллег не могли придумать, как заставить эту сериализацию работать напрямую, мы в конце концов решили эту проблему, обернув наш объект в пользовательский объект, который преобразует Dictionary<string, object> к Dictionary<string, string>, который имеет специальный случай сериализации, определенный для строковых массивов. Затем мы изменили приложение, чтобы знать об этом. Не особенно элегантно, но достаточно просто и, кажется, работает.

Я думаю, что вам нужно добавить object[] к известным типам с помощью KnownTypeAttribute, чтобы второй вариант работал, так как это то, что вы помещаете в словарь.

В любом случае, чтобы увидеть реальную ошибку на сервере, вам нужно включить трассировку WCF (или запустить отладчик в режиме, в котором он останавливается на каждом исключении, даже если оно перехвачено)

Другие вопросы по тегам