Pergunta

Eu estou tentando usar o seguinte código para serializar um tipo anônimo para JSON:

var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray()); 

No entanto, eu recebo a seguinte exceção quando este é executado:

Tipo '<> F__AnonymousType1`3 [System.Int32, System.Int32, System.Object []]' não pode ser serializado. considere marcação -lo com o DataContractAttribute atributo, e marcando toda a sua membros deseja serializado com o atributo DataMemberAttribute. Vejo O Microsoft .NET Framework documentação para outro suportado tipos.

Eu não posso aplicar atributos para um tipo anônimo (tanto quanto eu sei). Existe outra maneira de fazer isso serialização ou estou faltando alguma coisa?

Foi útil?

Solução

Tente o JavaScriptSerializer vez do DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);

Outras dicas

Como já foi mencionado, Newtonsoft JSON.NET é uma boa opção. Aqui está um exemplo específico para simples serialização JSON:

return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

Eu descobri que ele seja, uma biblioteca versátil muito flexível.

Você pode tentar a minha ServiceStack JsonSerializer é o mais rápido .NET JSON serializador no momento. Ele suporta a serialização DataContract do, Qualquer POCO Type, Interfaces, objetos de ligação tardia, incluindo tipos anônimos, etc.

Exemplo básico

var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>(); 

Nota:. Só use Microsofts JavaScriptSerializer se o desempenho não é importante para você como eu tive que deixá-lo fora das minhas referências desde a sua até 40x-100x mais lento do que os outros serializers JSON

Por favor note que este é a partir de 2008. Hoje eu diria que o serializador deve ser construído e que você provavelmente pode usar arrogância atributos + para informar os consumidores sobre os seus dados de endpoint e de retorno.


Iwould argumentar que você não deve ser a serialização de um tipo anônimo . Eu sei que a tentação aqui; Você quer gerar rapidamente alguns tipos Lance-afastado que está indo só para ser usado em um ambiente vagamente digite aka Javascript no navegador. Ainda assim, eu criaria um tipo real e decorá-lo como Serializable. Então você pode digitar fortemente seus métodos da web. Enquanto isso não importa nem um pouco de Javascript, ele faz acrescentar alguma auto-documentação para o método. Qualquer programador razoavelmente experiente será capaz de olhar para a assinatura da função e dizer: "Oh, este é tipo Foo! Sei como isso deve olhar em JSON."

Dito isto, você pode tentar JSON.Net para fazer a serialização. Eu não tenho idéia se ele vai funcionar

A maneira mais rápida que eu encontrei foi isto:

var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);

Namespace: System.Web.Script.Serialization.JavaScriptSerializer

Assumindo que você está usando isso para um serviço web, você pode simplesmente aplicar o seguinte atributo para a classe:

[System.Web.Script.Services.ScriptService]

Em seguida, o seguinte atributo para cada método que deve retornar Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

E definir o tipo de retorno para os métodos para ser "objeto"

public static class JsonSerializer
{
    public static string Serialize<T>(this T data)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream();
            serializer.WriteObject(stream, data);
            string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
            stream.Close();
            return jsonData;
        }
        catch
        {
            return "";
        }
    }
    public static T Deserialize<T>(this string jsonData)
    {
        try
        {
            DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
            T data = (T)slzr.ReadObject(stream);
            stream.Close();
            return data;
        }
        catch
        {
            return default(T);
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top