Deserialize json with C# .NET Core
Asked Answered
T

1

9

Im trying to deserialize data that Ive got over POST in JSON format but having some problem.

The error message is:

SerializationException: Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. System.Runtime.Serialization.XmlObjectSerializerReadContext.HandleMemberNotFound(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, int memberIndex)

Controller where the serialization is happening:

    public String RequestToken(string userData)
    {
            Contract.Ensures(Contract.Result<string>() != null);
            UserModel deserializedUser = new UserModel();
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(userData));
            ms.Position = 0;
            DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedUser.GetType());
            deserializedUser = ser.ReadObject(ms) as UserModel;
    }

UserModel that is used as a contract:

using System;
using System.Runtime.Serialization;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace WishareIntegrationApi.Entities
{
    [DataContract]
    public class UserModel
    {
        [BsonId]
        [BsonRepresentation(BsonType.String)]
        [DataMember]
        public ObjectId _id { get; set; }
        [DataMember]
        public string displayName { get; set; }
        [DataMember]
        public string photoURL { get; set; }
        [DataMember]
        public string email { get; set; }
        [DataMember]
        public int registeredAt { get; set; }
    }
}

And an example JSON i'm sending over post:

{"_id":"8kmXH1fzSrVS8PqNLMwyhRH4hBw1","displayName":"Michal Takáč","photoURL":"https://lh3.googleusercontent.com/-xa5oE48RffQ/AAAAAAAAAAI/AAAAAAAACDE/OLrtV5-VIvw/photo.jpg","email":"[email protected]"}
Toadinthehole answered 3/1, 2018 at 10:22 Comment(10)
"System.Runtime.Serialization.Xml"... in the error. Hmm. Check your default serializer.Camenae
Why are you using the deprecated DataContractJsonSerializer? .NET itself uses JSON.NET in ASP.NET Web API. .NET Core uses Json.NET both in both in ASP.NET MVC and Web API. By using DataContractJsonSerializer you are introducing a dependency on a legacy classShuman
I also noticed this one, but im totally new to .NET. Can you elaborate on that default serializer thingy?Dallasdalli
Besides, you don't need any of that code. Strings are UTF16 and all deserializers can handle them.Shuman
@PanagiotisKanavos Im following the tutorial ive found on msdn website :D To be honest it looks too complicated for json serialization/deserialization to me compared to node/phpDallasdalli
@MichalTakáč forget about default serializers and use JSON.NET. A simple JSonConvert.DeserializeObject<UserModel>(userData)` is enoughShuman
@MichalTakáč are you using the wrong tutorial perhaps? What link did you use. The current tutorials don't use DataContractSerializer. Did you check asp.net/learn ?Shuman
@MichalTakáč I suspect you are looking at a WCF tutorial because MVC/Web API doesn't need manual deserialization. You should be able to write public String RequestToken(UserModel userData) and MVC will handle deserializationShuman
I just switched to JSON.NET and it works well. Thank you for help :)Dallasdalli
@MichalTakáč check the correct tutorials too because you shouldn't have to deserialize anything. It's not just that you are wasting time doing what's available in the box, you are probably using inappropriate techniques and code as wellShuman
T
15

Switch to JSON.Net.

JSON serialization APIs are not part of .Net core and I don't expect them to port that over. If you used classes from namespaces like System.Web.Script.Serialization switch to other serialization, in particular Microsfot frameworks based on .Net core use JSON.Net serializers.

As mentioned by many users in comments, I've switched from old way of doing serialization/deserialization using contracts to JSON.NET

Here is the correct solution for the controller

public async Task<String> RequestToken(string userData)
{
     var user = JsonConvert.DeserializeObject<UserModel>(userData);
}
Toadinthehole answered 3/1, 2018 at 11:13 Comment(2)
$ dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJsonSegregationist
But they have replaced them now with System.Text.Json since .Net Core 3.1.Macmullin

© 2022 - 2024 — McMap. All rights reserved.