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.takac@gmail.com"}
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Michal Takáč
  • 1,005
  • 3
  • 17
  • 37
  • "System.Runtime.Serialization.Xml"... in the error. Hmm. Check your default serializer. – ADyson Jan 03 '18 at 10:23
  • 2
    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 class – Panagiotis Kanavos Jan 03 '18 at 10:25
  • I also noticed this one, but im totally new to .NET. Can you elaborate on that default serializer thingy? – Michal Takáč Jan 03 '18 at 10:26
  • Besides, you don't need any of that code. Strings are UTF16 and all deserializers can handle them. – Panagiotis Kanavos Jan 03 '18 at 10:26
  • @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/php – Michal Takáč Jan 03 '18 at 10:27
  • 3
    @MichalTakáč forget about default serializers and use JSON.NET. A simple JSonConvert.DeserializeObject(userData)` is enough – Panagiotis Kanavos Jan 03 '18 at 10:27
  • @MichalTakáč are you using the *wrong* tutorial perhaps? What link did you use. The current tutorials *don't* use DataContractSerializer. Did you check https://www.asp.net/learn ? – Panagiotis Kanavos Jan 03 '18 at 10:30
  • @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 deserialization – Panagiotis Kanavos Jan 03 '18 at 10:32
  • 2
    I just switched to JSON.NET and it works well. Thank you for help :) – Michal Takáč Jan 03 '18 at 10:32
  • @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 well – Panagiotis Kanavos Jan 03 '18 at 10:34

1 Answers1

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);
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Michal Takáč
  • 1,005
  • 3
  • 17
  • 37