开发者

For WCF, when is it necessary to statically tell a serializer about a data type?

开发者 https://www.devze.com 2022-12-16 07:09 出处:网络
I am using the WCF JSON serializer to produce JSON for use as return data for the ASP.NET MVC framework. I am doing this because the built-in JsonAction does not provide any way to control the naming

I am using the WCF JSON serializer to produce JSON for use as return data for the ASP.NET MVC framework. I am doing this because the built-in JsonAction does not provide any way to control the naming of public properties in the serialized JSON.

public override voi开发者_运维百科d 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()));
    }
}

In this example, I am using this with OpenFlashChart, so I set this.Data to a PieChart instance. It worked fine. Then, I set this.Data to an instance of Chart, and I got the following exception:

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.

Obviously, when I gave the serializer a PieChart element, it was able to infer that I needed the Pie class as well. Why when I provide it Chart<PieChart> is it no longer looking at the classes used by PieChart? Is there a way to get around this issue without having to annotate everything with KnownTypeAttributes?


I've edited my previous answer because I've just realised the problem here.

I think problem is because the type being serialized is generic, you have to add any generic parameter types to the DataContractJsonSerializer's known types.

If I'm right, then you can still do this without annotating.

Firstly, call the constructor on DataContractJsonSerializer which accepts a Type and an IEnumerable<Type>.

Then change how you construct the serializer to something like this:

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

That would be my next step.


As Andras' post was initially one of the solutions I implemented in regards to JSON serialization/deserialization and have since found a better method (for my own purposes, at least), I wanted to share:

// 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);

Pretty simple

0

精彩评论

暂无评论...
验证码 换一张
取 消