41

I have the following entity class:

public class FacebookComment : BaseEntity
{
    [BsonId(IdGenerator = typeof(ObjectIdGenerator))]
    [BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]
    [JsonProperty("_id")]
    public ObjectId Id { get; set; }

    public int? OriginalId { get; set; }
    public DateTime Date { get; set; }
    public string Message { get; set; }
    public string Sentiment { get; set; }
    public string Author { get; set; }
}

When this object is serialized to JSON, I want the Id field to be written as "_id":{...}. AFAIK, I should just have to pass the desired propertyname to the JsonProperty attribute; and I should be good to go. However, when I call JsonConvert.SerializeObject; it seems to ignore my attribute and renders this instead:

{
    Author: "Author name",
    Date: "/Date(1321419600000-0500)/",
    DateCreated: "/Date(1323294923176-0500)/",
    Id: {
        CreationTime: "/Date(0)/",
        Increment: 0,
        Machine: 0,
        Pid: 0,
        Timestamp: 0
    },
    Message: "i like stuff",
    OriginalId: null,
    Sentiment: "Positive"
}

As you can see, the Id field is being rendered with the wrong field name.

Any ideas? Been working on this issue for an hour; can't figure out why the serializer is seemingly ignoring my JsonProperty.

Any constructive input is greatly appreciated.

Frank Rosario
  • 2,512
  • 5
  • 31
  • 47

7 Answers7

47

Short Answer: Make sure all your assemblies are referencing the SAME EXACT JSON.NET DLL. What's probably happening is you are applying [JsonProperty] from one DLL in one assembly, and serializing the object from a different assembly which is looking for a different [JsonProperty] and because the CLR object types are different it is effectively being ignored.


Longer Answer: I just had this problem but fortunately because I had one class that was working with JsonProperty and one that wasn't I was able to do some detective work.

I stripped the non-working class down to the bare minimum and compared it to the working class and couldn't see ANY differences - except for the fact that the non-working class was in a different assembly.

When I moved the class to the other assembly it worked perfectly as it should.

I poked around for a bit trying to look into JSON serialization of namespaces, but that didn't seem to apply so I looked at the references and sure enough I was referencing an old JSONNET3.5 DLL in my entities DLL and the NUGET 4.5 version in my main project file.

This gives me two instances of [JsonProperty] attribute (which is just a regular class) and just because they're named the same doesn't mean the serializer is going to even recognise the attribute.

OrionMD
  • 389
  • 1
  • 7
  • 13
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • 1
    I'm only using 1 assembly referencing Newtonsoft.Json and I'm still getting this problem, not even the DataMember attribute works for me. Very strange stuff. – pqsk Nov 18 '15 at 21:33
  • 1
    are you sure you did a clean build and there is no extra dll in your bin? if you have multiple projects do you have the same JSON.NET DLL defined for each? try evaluating `typeof(JsonProperty).Assembly.CodeBase` at runtime to ensure DLL is loaded and not coming from somewhere unexpected – Simon_Weaver Nov 18 '15 at 21:39
  • I stripped it down to just 1 project and did the clean just to be sure and the same unfortunately. Maybe it's a bug with this version? – pqsk Nov 18 '15 at 22:02
  • Does the expression in my last comment compile ok and run? What project type is this? Website/mvc? – Simon_Weaver Nov 18 '15 at 22:08
  • it runs fine and it is pointing to my bin where it was copied to by VS. This project is a console app. Perhaps this is the culprit? I'm calling a rest api and then processing the data – pqsk Nov 18 '15 at 22:24
  • Console should be fine. But let's go back to when you said 'it doesn't work'. What exactly do you mean? are you serializable or deserializing – Simon_Weaver Nov 18 '15 at 22:26
  • Yes sorry deserialization, but of course only with the JsonProperty, every other property works. I tried Required= Required.Default and also Required.Always and those don't seem to work either. – pqsk Nov 18 '15 at 22:50
  • I'm not sure what you mean 'every other property works'. Shouldn't they all have JsonProperty? Also I always like to put `[JsonObject(Mode=MemberSerialization.OptIn)]` on my object. Anyway I just remembered once I had a cut and paste error with TWO properties with `[JsonProperty(Name="foo")]` and that caused this issue – Simon_Weaver Nov 18 '15 at 22:56
  • I'm only using it on those that I need a different name than that actual property. Example: [JsonProperty("3h")]public string myProperty{get; set;} The other properties deserialize correctly without the JsonProperty attribute. – pqsk Nov 18 '15 at 23:11
  • 1
    Ok yes this sounds very similar to when I had duplicates. it didn't know what to do. You're SURE you don't have two "3h" defined? in a base class perhaps? If you add a fake property `[JsonProperty("testProperty")]` does that work ok? or ANY JsonProperty causes it to break? and you're sure you're using JSON.NET to do the deserialization? did you try `JsonConvert.DeserializeObject(jsonString)` – Simon_Weaver Nov 18 '15 at 23:20
  • 1
    You sir are the man. I was using new JavaScriptSerializer().Deserialize(jsonResponse). I thought that was Json.NET. My mistake. It works perfect now using your change. Thanks so much for taking the time to help me find the problem. – pqsk Nov 18 '15 at 23:25
  • 1
    Great :) I think everyone makes that mistake sometime :) – Simon_Weaver Nov 19 '15 at 00:56
  • not a working solution, my property is "$type" and it can no be Deserialize – Mahdi Aug 05 '19 at 07:14
  • @Mahdi it sounds like your issue has nothing to do with this which is not intended to be an answer to every possible Json.NET issue. With that said does it only fail for properties with a $? You should ask a new question with specifics. – Simon_Weaver Aug 05 '19 at 07:17
  • 1
    This resolved it for me. I had two different 'usings' Thanks for posting!!! – Steven Marcus Feb 25 '22 at 23:22
27

I had the same problem (.Net Core 3.1) and the reason was that I was using JsonPropertyName annotation, which is in System.Text.Json.dll but using JsonConvert.Serialize(string), which is obviously in Newtonsoft.Json.dll. It seems the serialization functions only respect their own library annotations. Changing JsonPropertyName annoation to JsonProperty fixed it, as the latter is in Newtonsoft.Json.dll

Abubakar Mehmood
  • 938
  • 1
  • 10
  • 19
11

In my case I was applying the JsonProperty atrtibute on properties alright, but since I was using asp.net core 3.1, types from System.Text.Json were used, not types from JSON.Net. So if you start using asp.core 3.1, you should make a decision as to which library you would like to use for json. HTH.

ashilon
  • 1,791
  • 3
  • 24
  • 41
  • 17
    To expand on this: .NET Core 3.1 uses the "JsonPropertyName" attribute from System.Text.Json.Serialization. If you're just passing in a string, you can switch from `[JsonProperty("name")]` to `[JsonPropertyName("name")]`, switch out your Newtonsoft import, and you'll be all set. – Isaac Lyman Jun 16 '20 at 18:43
10

This post helped me.

I used serialiser:

new JavaScriptSerializer().Serialize(message)

But rigtly use this:

JsonConvert.SerializeObject(message);
Community
  • 1
  • 1
user5866334
  • 101
  • 1
  • 2
4

I fixed this issue by marking my Id property with [System.Runtime.Serialization.DataMember(Name="_id")] instead of JsonProperty. Still not entirely clear as to why it didn't work originally though...

Frank Rosario
  • 2,512
  • 5
  • 31
  • 47
2

In my case, I was using record types, which means you have to use a property: prefix for the fields as mentioned in this question:

public record Person
(
  [property:JsonPropertyName("name")]
  string Name,
);
Daniel Veihelmann
  • 1,275
  • 10
  • 13
1

I also found that my JsonProperty tags were being ignored. I ultimately found that a silent failure loading Newtonsoft Json was to blame. Nancy.Serialization.JsonNet tries to load Newtonsoft Json 9.0.0.0 which was an earlier version than I had installed. No error is surfaced and the serializer provided by Nancy.Serialization.JsonNet is unavailable. Adding a library mapping to the application config fixed the issue:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

This was discovered by trying to load the JsonNetSerializer early within the Main method:

Type t=typeof(JsonNetSerializer);

This triggered the load error and lead to the config resolution.

Andrew Taylor
  • 1,368
  • 1
  • 11
  • 8