在C#中使用DataContractJsonSerializer反序列化JSON对象

lawou6xi  于 2023-05-08  发布在  C#
关注(0)|答案(4)|浏览(149)

我相信这个问题已经被问了一遍又一遍,但出于某种原因,我仍然无法让它发挥作用。
我想反序列化一个包含单个成员的JSON对象;字符串数组:

[{"idTercero":"cod_Tercero"}]

这是我尝试反序列化的类:

[DataContract]
public class rptaOk
{
    [DataMember]
    public string idTercero { get; set; }

    public rptaOk() { }

    public rptaOk(string idTercero)
    {
        this.idTercero = idTercero;
    }
}

这是我尝试反序列化的方法:

public T Deserialise<T>(string json)
    {
        DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
        using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            T result = (T)deserializer.ReadObject(stream);
            return result;
        }
    }

所以我试着填充这个对象:

rptaOk deserializedRpta = deserializarOk(rpta);

但由于某种原因,这个返回“”

MessageBox.Show(deserializedRpta.idTercero);
kiayqfof

kiayqfof1#

在.net framework之外没有任何依赖项的情况下,您可以这样做。

[DataContract(Name="rptaOk")]
public class RptaOk
{
    [DataMember(Name="idTercero")]
    public string IdTercero { get; set; }
}

[CollectionDataContract(Name="rptaOkList")]
public class RptaOkList : List<RptaOk>{}

var stream = new StreamReader(yourJsonObjectInStreamFormat);
var serializer = new DataContractSerializer(typeof(RptaOkList));
var result = (RptOkList) serializer.ReadObject(stream);
vpfxa7rd

vpfxa7rd2#

我不知道你是否愿意改变你正在使用的库,但我使用库“Newtonsoft.JSON”来反序列化JSON对象,它非常容易使用

[HttpPost]
    public void AddSell(string sellList)
    {
        var sellList = JsonConvert.DeserializeObject<List<Sell>>(sellListJson);
        BD.SaveSellList(sellList);
    }

正如你所看到的,你可以将整个json对象列表反序列化为类型为“Sell”的List<>,这是我创建的一个对象。当然,你也可以对数组这样做。我不知道正确的语法,但是你可以在后面把这个列表转换成数组
希望这对你有帮助

ckx4rj1h

ckx4rj1h3#

我觉得你把事情搞得太复杂了。首先,您的示例json和您试图反序列化的类没有字符串数组。它们只有一个字符串类型的属性。第二,为什么要使用DataContractJsonSerializer类?你没有做任何你不能从一个简单的调用json.NET的通用反序列化方法。我会删除除类定义之外的所有代码,并将其替换为这个简单的一行代码;

rptaOk[] myInstances = JsonConvert.DeserializeObject<rptaOk>(jsonString);

此外,无论json的结构是什么,如果你有一个类来正确地建模它,那么这个方法就会正确地反序列化它。如果你想强制执行某种契约,我建议你使用json.NET也支持的json模式。如果你使用一个模式,它会强制执行一个严格的契约,如果你试图反序列化到一个对象中,就会有一些隐式的契约。我不知道每一个会导致它抛出的场景,但如果你的json离类定义太远,它就会抛出。如果你的类的属性没有出现在json中,我相信它们会被初始化为该类型的默认值。
编辑:我刚刚注意到你的JSON实际上是一个对象数组。所以你只需要把这个赋值的lhs变成一个数组或者rptaOk对象,而不是一个单例。

zsbz8rwp

zsbz8rwp4#

我意识到这个答案已经很晚了,但这里有一个完整的单一类型DataContractJsonSerializer,我称之为JsonContract<T>

private static readonly JsonContract<TestViewModel> SingleTypeMemorySerializer = new();

序列化

SingleTypeMemorySerializer.Serialize.WriteType(defaultModel);
string testString = SingleTypeMemorySerializer.Serialize.WriteOutStream();
SingleTypeMemorySerializer.Serialize.Reset();

反序列化

SingleTypeMemorySerializer.Deserialize.Read(testString);

JsonContract

/*
*MIT License
*
*Copyright (c) 2023 S Christison
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

/// <summary>
/// Single Type Json Contract
/// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
/// <para><see cref="DataContractJsonSerializerSettings"/> to change settings for this <see cref="JsonContract{T}"/></para>
/// </summary>
public class JsonContract<T>
{
    private readonly DataContractJsonSerializer _dc;

    public DataContractJsonSerializerSettings DataContractJsonSerializerSettings = new()
    {
        DateTimeFormat = new DateTimeFormat("dd:MM:yyyy:hh:mm:ss:fff"),
        EmitTypeInformation = EmitTypeInformation.Never,
        UseSimpleDictionaryFormat = true,
        IgnoreExtensionDataObject = true,
    };

    /// <summary>
    /// Single Type Json Contract
    /// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
    /// <para><see cref="DataContractJsonSerializerSettings"/> to change settings for this <see cref="JsonContract{T}"/></para>
    /// </summary>
    public JsonContract()
    {
        _dc = new(typeof(T), DataContractJsonSerializerSettings);
        Serialize = new Serializer<T>(_dc);
        Deserialize = new Deserializer<T>(_dc);
    }

    /// <summary>
    /// Serialize <see cref="T"/> into a <see href="Compliant JSON String"/>
    /// <para><see cref="DataContractJsonSerializerSettings"/> to change settings for this <see cref="JsonContract{T}"/></para>
    /// </summary>
    public Serializer<T> Serialize;

    /// <summary>
    /// Deserialize a <see href="Compliant JSON String"/> into <see href="T"/>
    /// <para><see cref="DataContractJsonSerializerSettings"/> to change settings for this <see cref="JsonContract{T}"/></para>
    /// </summary>
    public Deserializer<T> Deserialize;
}

/// <summary>
/// Single Type Json Serializer
/// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
/// </summary>
public class Serializer<T> : MemoryStream
{
    private readonly DataContractJsonSerializer _dc;
    private readonly StreamReader _sr;

    /// <summary>
    /// Single Type Json Serializer
    /// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
    /// </summary>
    /// <param name="dc">Data Contract Json Serializer</param>
    public Serializer(DataContractJsonSerializer dc)
    {
        _sr = new(this);
        _dc = dc;
    }

    public void Reset()
    {
        Position = 0;

        _sr.DiscardBufferedData();
    }

    public void WriteType(T s)
    {
        _dc.WriteObject(this, s);
    }

    public string WriteOutStream()
    {
        Position = 0;

        return _sr.ReadToEnd();
    }
}

/// <summary>
/// Single Type Json Deserializer
/// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
/// </summary>
public class Deserializer<T> : MemoryStream
{
    private readonly DataContractJsonSerializer _dc;

    /// <summary>
    /// Single Type Json Deserializer
    /// <para><see href="System.Runtime.Serialization.Json"/> Wrapper</para>
    /// </summary>
    /// <param name="dc">Data Contract Json Serializer</param>
    public Deserializer(DataContractJsonSerializer dc)
    {
        _dc = dc;
    }

    public T Read(string json)
    {
        if (Position != 0)
        {
            Position = 0;
            Flush();
        }

        byte[] bytes = Encoding.Unicode.GetBytes(json);

        for (int i = 0; i < bytes.Length; i++)
        {
            WriteByte(bytes[i]);
        }

        Position = 0;
        return Read(this);
    }

    public T Read(Stream json)
    {
        return (T)_dc.ReadObject(json);
    }
}

测试结果

[S] Newtonsoft Average Ticks Per Action             : 89.81 Max: 925 Min: 80
[S] Newtonsoft Average Actions Per Millisecond      : 111.34617525888
[D] Newtonsoft Ticks Per Action                     : 183.296 Max: 1554 Min: 132
[D] Newtonsoft Average Actions Per Millisecond      : 54.5565642458101
-
[S] JsonContract Ticks Per Action                   : 121.837 Max: 1152 Min: 108
[S] JsonContract Average Actions Per Millisecond    : 82.0768731994386
[D] JsonContract Ticks Per Action                   : 355.315 Max: 1424 Min: 337
[D] JsonContract Average Actions Per Millisecond    : 28.1440412028763

注意事项

.NET Standard 2.0
我只是做了这个测试的目的,你可以用它来做任何你想要的。
如果你认为这是一个更快的选择,你应该测试数据,因为根据类型Newtonsoft.Json的复杂性可能会更快.

相关问题