dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.15k stars 9.92k forks source link

Using Metadata attribute to add attribute to some property of the class does not work #48686

Closed goodstas closed 1 year ago

goodstas commented 1 year ago

Is there an existing issue for this?

Describe the bug

Hi, I have auto generated class by protoc and i want to add JsonIgnore attribute for some of the properties of my class in the partial class because i don't want to reveal them in my REST API. I found this question (https://stackoverflow.com/questions/35570965/add-attribute-to-the-property-dynamically) on stackoverflow and i tried to implement the same according to the answer which talked about using Metadata attribute and creating appropriate class with the attribute .

So i created some WeatherForecast sample of ASP.NET app. I modified WeatherForecast class . So it looks as follows :

public partial class WeatherForecast
    {
        [JsonIgnore]
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string? Summary { get; set; }
    }

I manually added JsonIgnore over Date property. After that i created partial class and metadata class for WeatherForecast class in different file.

 [MetadataType(typeof(WeatherForecastMetada))]
    public partial class WeatherForecast
    {

    }

    public partial class WeatherForecastMetada
    {
        [JsonIgnore]
        public string? Summary { get; set; }
    }

Unfortunately i don't see any impact of JsonIgnore on Summary property when i run the application. From other side i don't see Date property of the WeatherForecast as it supposed to be.

I tried to register WeatherForecast to TypeDescriptor but it doesn't help. What do i miss?

Expected Behavior

No response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

NET 6

Anything else?

No response

MackinnonBuck commented 1 year ago

Thanks for reaching out. MetadataTypeAttribute only works for data annotations, and it won't have any impact on the behavior of JSON serialization.

halter73 commented 1 year ago

Rather than trying to add attributes to a type at runtime which will never really work without creating an entirely new type at runtime using something like System.Reflection.Emit, your best bet might be to either:

  1. Use a Data Transfer Object (DTO) with just the properties you want to serialize and deserialize. Convert from WeatherForecast to WeatherForecastDTO (or whatever you call it) by copying just the properties you want to serialize.
  2. Or use a custom converter for System.Text.Json, and configure the MVC JsonSerializerOptions.Converters to use it with .AddControllers().AdJsonOptions(...).
goodstas commented 1 year ago

@halter73 Custom converter doesn't do the same as JsonIgnore... @MackinnonBuck

I want to explain what i try to do. I have some system that knows to generate proto files and C# classes based on some definitions. There are some types in C# that have no equivalent in protocol buffers like Guid. I used auto generated C# files to create some generic framework which uses these files to write them to database (code-first approach) and for example my auto generated entities have Id property of type Guid that is used as primary key for the table. Now i asked to use C# classes which are generated from auto generated proto files. Except Guid type there are another types like Polygon, Point and so on from NetTopologySuite nuget which are also in use in my framework and my entities have properties with these types. These types also are not supported by protocol buffers.

I'm looking for some solution how i can create some proto file and after that use the generated class or transform it to another class in some way which have C# types that i use in my entities like Guid and Polygon ...

I hope you succeeded to understand the description of the problem i try to solve :) I will appreciate if you can give some ideas.