Runtime: System.Text.Json.Serialization.JsonSerializer should respect DataMemberAttribute.Name

Created on 24 Jun 2019  路  10Comments  路  Source: dotnet/runtime

The following code outputs {"MyDataMember":"dataMember"}, should be {"RENAMED":"dataMember"}

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

namespace JsonSerializerIssue
{
    [DataContract]
    internal class MyData
    {
        [DataMember(Name = "RENAMED")]
        public string MyDataMember { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyData myData = new MyData() { MyDataMember = "dataMember" };
            Debug.WriteLine(JsonSerializer.ToString(myData));
        }
    }
}
area-System.Text.Json enhancement json-functionality-doc

Most helpful comment

Is there a particular reason why the new JsonPropertyName attribute won't work for your scenario?

For example, if we build a Blazor app, and ofc we'd like to make JSON models shared between our server and client to keep them consistent, but on the client side (i.e. Blazor project), we can't use System.Text.Json due to the runtime restrictions so we can't use JsonPropertyName.

What's more, many existing projects now use DataContract/DataMember attributes because it's common and most of JSON libs respect it.

I knew that now it's life after WCF, and we'd better not use these attributes introduced by WCF since it's nearly EoS. But we need attributes that could describe JSON models across so many JSON libs and runtime.

All 10 comments

Is there a particular reason why the new JsonPropertyName attribute won't work for your scenario?

We have tens of thousand lines of code and would like to replace Newtonsoft.Json with the new functionality.

+1 for sticking with an existing API.

Is there a particular reason why the new JsonPropertyName attribute won't work for your scenario?

For example, if we build a Blazor app, and ofc we'd like to make JSON models shared between our server and client to keep them consistent, but on the client side (i.e. Blazor project), we can't use System.Text.Json due to the runtime restrictions so we can't use JsonPropertyName.

What's more, many existing projects now use DataContract/DataMember attributes because it's common and most of JSON libs respect it.

I knew that now it's life after WCF, and we'd better not use these attributes introduced by WCF since it's nearly EoS. But we need attributes that could describe JSON models across so many JSON libs and runtime.

there is currently no replacement for [DataMember(EmitDefaultValue)] in System.Text.Json.

@ahsonkhan Can you explain why it is necessary to create a new attribute only for json serialization? What if I also need to serialize to other formats? Should I now decorate my type with additional attributes?

Why not use the existing common attribute?

@jjrdk, I agree. It seems logical to abstract the serialization decorations to allow for the serializing and deserializing in multiple formats (based on request Accept headers for example).

Closing as duplicate - this falls under the ask to support types from System.Runtime.Serialization: https://github.com/dotnet/corefx/issues/38758.

Should this be reopened as the conclusion of dotnet/runtime#29975 was to make individual issues for individual features, which this is.

Early-on during design of STJ in 3.0, it was decided not to support pre-existing attributes mainly because they would only be partially supported and it would be hit-and-miss meaning STJ would only support some of those in the first release and additional support added in future releases. This would cause endless confusion over what is and what is not supported. STJ can't just throw NotSupportedException for the unsupported cases since that would mean the attribute usage would need to be removed from the corresponding types (not feasible unless the types are owned), or have a way to turn off the exception.

Also since STJ would need to explicitly look for those attributes, it would cause some slowdown during warm-up.

Consider just the DataMemberAttribute properties:

  • EmitDefaultValue: in 3.0, we couldn't support since we didn't have that feature. Now in 5.0 it is.
  • IsNameSetExplicitly: not supported yet.
  • IsRequired: not supported yet.
  • Name: supported through STJ.PropertyNameAttribute.
  • Order: not supported yet.

Then there's also a few other attributes including CollectionDataContractAttribute, OnDeserializedAttribute that would also contribute to hit-and-miss. STJ also didn't consider other areas including System.IConvertible.

So we went with a new explicit model that is intuitive (if it's not in the STJ namespace then it's not supported) that is high-performance with the thought we can add support for pre-existing attributes through an opt-in modeflag of some sort or perhaps a pluggable metadata provider. These have not been implemented yet.

Moving-forward, having a pluggable metadata provider along with an opt-in System.Runtime.Serialization "compat" implementation of that provider makes sense to me. Not sure if that has enough priority for 6.0, but it could be considered along with the feature to expose metadata and more flexible converters.

Was this page helpful?
0 / 5 - 0 ratings