Reputation: 43
I'm sure this question has been asked over and over again, but for some reason, I still can't manage to get this to work.
I want to deserialize a JSON object that contains a single member; a string array:
[{"idTercero":"cod_Tercero"}]
This is the class that I'm trying to deserialize into:
[DataContract]
public class rptaOk
{
[DataMember]
public string idTercero { get; set; }
public rptaOk() { }
public rptaOk(string idTercero)
{
this.idTercero = idTercero;
}
}
This is the method that I try to deserialize:
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;
}
}
And so I try to fill the object:
rptaOk deserializedRpta = deserializarOk(rpta);
But for some reason, this returns ""
MessageBox.Show(deserializedRpta.idTercero);
Upvotes: 2
Views: 24554
Reputation:
I realize this answer is really late, but here is a complete single type DataContractJsonSerializer
that I called a 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);
/*
*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
I just made this for testing purposes you can use it for whatever you want.
If you were thinking this was a faster option, You should test the data, because depending on the complexity of the type Newtonsoft.Json
will likely be faster.
Upvotes: 0
Reputation: 13591
Without any dependencies outside of the .net framework, you could do it this way
[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);
Upvotes: 4
Reputation: 48134
I think you're making this a lot more difficult than it needs to be. Firstly, your sample json and the class you're trying to deserialize into do not have an array of strings. They have a single property of type string. Secondly, why are you using this class DataContractJsonSerializer
? You're not doing anything with it that you can't get from a simple call to json.NET's generic deserialization method. I would remove all of your code except the class definition and replace it with this simple one liner;
rptaOk[] myInstances = JsonConvert.DeserializeObject<rptaOk>(jsonString);
Also, no matter what the structure of your json is, if you have a class to correctly model it that method will correctly deserialize it. If you want to enforce some kind of contract I recommend using json schemas which json.NET also supports. If you use a schema it enforces a rigid contract, if you attempt to deserialize into an object there is something of an implicit contract. I don't know every scenario which will cause it to throw, but if your json is too far from the class definition it will. If your class has properties that don't appear in the json I believe they will just get initialized with the default values for that type.
EDIT: I just noticed your json is actually an array of objects. So you simply need to make the lhs of that assignment an array or rptaOk
objects, rather than a singleton.
Upvotes: 2
Reputation: 163
I don't know if your're wiling to change the library that you're using, but I use library "Newtonsoft.Json" to desserialize JSON objects, it's pretty easy to use
[HttpPost]
public void AddSell(string sellList)
{
var sellList = JsonConvert.DeserializeObject<List<Sell>>(sellListJson);
BD.SaveSellList(sellList);
}
As you can see you can deserialize a whole json object list to a List<> fo the type "Sell", an object that i've created... And, of course, you can do that to an array too. I don't know the correct syntax for this, but you can convert this list to an array afterwards
Hope this helps
Upvotes: 2