Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataMember Attribute is not honored in dotnet core 3.0

I created a sample dotnet core 3.0 Web API project and did the following changes,

  1. Create a Model class TestData
using System.Runtime.Serialization;
namespace WebApplication17.Models
{
    [DataContract]
    public class TestData
    {
        [DataMember(Name = "testaction")]
        public string Action { get; set; }
    }
}

Then I made changes in controller WeatherForecastController, to add a post endpoint

[HttpPost("package/{packageName}/version/{version}")]
public void Post(string packageName, string version, [FromBody] TestData activityPayload)
{
    Console.WriteLine(activityPayload.Action);
}

Now I made a call from postman or curl with body

{   
    "testaction": "action"  
}

Still in Post method of WeatherForecastController, activityPayload.Action is null.

I was expecting it to be 'action'

like image 279
Jitendra Avatar asked Sep 16 '19 23:09

Jitendra


People also ask

Is DataMember attribute required?

You must specify [DataMember] attribute on the property or the field of your Data Contract class to identify it as a Data Member. DataContractSerializer will serialize only those members, which are annotated by [DataMemeber] attribute.

What is Datacontract and DataMember in WCF?

A datacontract is a formal agreement between a client and service that abstractly describes the data to be exchanged. In WCF, the most common way of serialization is to make the type with the datacontract attribute and each member as datamember.

What is Datacontract attribute?

[DataContract] attribute specifies the data, which is to serialize (in short conversion of structured data into some format like Binary, XML etc.) and deserialize(opposite of serialization) in order to exchange between the client and the Service.

Why use DataContract?

It is used to get or set the order of serialization and deserialization of a member. It instructs the serialization engine that member must be present while reading or deserializing. It gets or sets the DataMember name. It will specify whether the default value to be serialized.


1 Answers

As of .NET Core 3.0 RC1 the System.Text.Json library does not have support for System.Runtime.Serialization attributes. You can find an issue on GitHub which is tracking this omission but right now it does not appear that there is any intention to change that.

Option 1: Newtonsoft.Json

What you can do in the interim is switch to using Newtonsoft.Json as the JSON serializer for ASP.NET Core 3.0 which should restore this functionality (at the cost of not leveraging the System.Text.Json parser which is a fair bit faster).

First, add a reference to the Microsoft.AspNetCore.Mvc.NewtonsoftJson package in your project:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
  </ItemGroup>
</Project>

And then call the extension on your services collection.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddNewtonsoftJson();
}

Option 2: Use System.Text.Json.Serialization

On the other hand, if you're happy to define your models without System.Runtime.Serialization attributes and use the System.Text.Json.Serialization attributes instead, then you can do the following:

using System.Text.Json.Serialization;
namespace WebApplication17.Models
{
    public class TestData
    {
        [JsonPropertyName("testaction")]
        public string Action { get; set; }
    }
}

You can find the full list of supported attributes here: https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonpropertynameattribute?view=netcore-3.0

like image 91
Jitendra Avatar answered Sep 20 '22 14:09

Jitendra