Для WCF, когда необходимо статически сообщить сериализатору о типе данных? - PullRequest
1 голос
/ 08 января 2010

Я использую сериализатор JSON WCF для создания JSON для использования в качестве возвращаемых данных для платформы ASP.NET MVC. Я делаю это потому, что встроенный JsonAction не предоставляет никакого способа управления именованием открытых свойств в сериализованном JSON.

public override void ExecuteResult(ControllerContext context)
{
    ...

    if (Data != null)
    {
        var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(Data.GetType());
        System.IO.MemoryStream ms = new System.IO.MemoryStream();

        serializer.WriteObject(ms, this.Data);

        response.Write(Encoding.Default.GetString(ms.ToArray()));
    }
}

В этом примере я использую это с OpenFlashChart, поэтому я установил this.Data для экземпляра PieChart. Работало нормально. Затем я установил this.Data для экземпляра Chart и получил следующее исключение:

Type 'OpenFlashChart.Pie' with data contract name 'Pie:http://schemas.datacontract.org/2004/07/OpenFlashChart' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Очевидно, что когда я дал сериализатору элемент PieChart, он мог заключить, что мне также нужен класс Pie. Почему, когда я предоставляю Chart<PieChart>, он больше не смотрит на классы, используемые PieChart? Есть ли способ обойти эту проблему без необходимости аннотировать все с помощью KnownTypeAttributes?

Ответы [ 2 ]

1 голос
/ 08 января 2010

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

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

Если я прав, то вы можете сделать это без комментариев.

Во-первых, вызовите конструктор в DataContractJsonSerializer, который принимает Type и IEnumerable<Type>.

Затем измените способ создания сериализатора на что-то вроде этого:

DataContractJsonSerializer serializer = null;
Type dataType = Data.GetType();
if(dataType.IsGenericType)
    serializer = new DataContractJsonSerializer(dataType, dataType.GetGenericArguments());
else
    serializer = new DataContractJsonSerializer(dataType);

Это был бы мой следующий шаг.

0 голосов
/ 10 июня 2011

Поскольку пост Андраса изначально был одним из решений, которые я реализовал в отношении сериализации / десериализации JSON, и с тех пор нашел лучший метод (по крайней мере, для моих собственных целей), я хотел поделиться:

// Add a reference to System.Web.Extensions **(.NET 4.0 required)**

using System.Web.Script.Serialization;
...
// To serialize...
JavaScriptSerializer serializer = new JavaScriptSerializer();
String serializedData = serializer.Serialize(data);

// To deserialize...
deserializedData = serializer.Deserialize<data.GetType()>(serializedData);
// OR even
var anyObject = .serializer.Deserialize<dynamic>(serializedData);

Довольно просто

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