Giter VIP home page Giter VIP logo

core's Issues

JsonStringEnumConverter attribute is not working when global JsonStringEnumConverter is registered globally

Hi,

thanks for JsonStringEnumConverter, it's what I was looking for. Unfortunately, the converter can't be used when System.Text.Json.Serialization.JsonStringEnumConverter is registered globally.
Here is a sample repository.

There are two projects and a shared library with enums. The first project is called "Enums" and there is defined global System.Text.Json.Serialization.JsonStringEnumConverter. So, with that one can't use enum values as they are defined with the EnumMember attribute. The second project is called "EnumMembers" and there is no global enum converter registered, that is working as expected, but for enums without JsonConverter one must use numbers instead of a string.

We serialize and deserialize enums as strings, but sometimes (OpenID connect client registration) we need to follow the standard and use defined naming convention, so EnumMember attributes are in place and we don't want every enum to decorate with JsonConverter attribute.

Is there a way out?

DateTime format doesn't match .Net Framework's JavaScriptSerializer or Json.Net's DateFormatHandling.MicrosoftDateFormat

In your Json extensions code, if I format CultureInfo's DateTimeFormat, the property MinSupportedDateTime comes out like this:

JavascriptSerializer/DateFormatHandling.Microsoft = "MinSupportedDateTime":"/Date(-62135596800000)/"

But with your code, it seems to come out like "MinSupportedDateTime":"/Date(-62135596800000)/" (missing the \ before /). Will that still work as intended?

Unable to have spaces in JsonPropertyName

Not sure what's causing this, as the tests shown in the documentation show this should be possible
image
image

However, my other enum without spaces seems to work fine
image

I'm using .NET 5.0, System.Text.Json 6.0 (from System.Net.Http.Json)

Security Issue in Macross.Json.Extensions

I noticed that your dependency on System.Text.Json version 4.7.0 has a security issue.

Are there any plans to upgrade this to a secure version? I would love to use this library but that is currently an issue for us.

Here's what my scanner found along with some information on remediation steps. I think it's as simple as bumping up System.Text.Json to 4.7.2+

 Detailed paths

    Introduced through: project@undefined › [email protected][email protected][email protected]

Overview

Affected versions of this package are vulnerable to Remote Code Execution (RCE) due to how text encoding is performed.
Remediation

Upgrade System.Text.Encodings.Web to version 4.5.1, 4.7.2, 5.0.1 or higher.

Handle mutable properties on the LogEvent

The FileLogger converts the LogEvent into a LoggerJsonMessage:

LoggerJsonMessage.FromLoggerData(Group?.GroupName, _CategoryName, Scopes, logLevel, eventId, state, exception, formatter));

But be careful when the extracted properties are complex objects that can be mutable (ex disposed or returned to object pool after being logged). Then the output might not be like you expect, when the async-writer finally starts converting to the actual json-output.

Macross.Json.Extensions 2.1.0 Nuget

Hi! I see that there were several beta releases for Macross.Json.Extensions 2.1.0, but never a production release (at least not on NuGet Gallery). Was that an oversight or did you decide not to release 2.1.0 before proceeding into beta on 2.2.0?

Support Enum deserialization from Array for Flags enums

When working with [Flags] enums, these are often represented as an array of strings in JSON.

It would be nice to have this functionality too in the JsonStringEnumMemberConverter.
It should check if the value is a string or a number and proceed as before, but also introduce support if the value is an array.

Case sensitive enum deserialize

Currently it seems that the library deserializes enum values without taking case sensitivity into an account, so e.g. a value of "hELLo" successfully deserializes into the enum value Hello. Is there a way to force an exception if the casing isn't exactly as specified in the [EnumMember] attribute?

Aliases for Enum deserialization

Thank you for this project, it has been helpful to me in accepting non-standard string values for my enums.

I have a need in the deserialization of an Enum from a string to be able to accept different values/aliases that tie back to the same Enum value. Additionally, if that enum value was deserialized with an alias, I'd like it to be serialized using the default value, not an alias value.

As a made up (probably bad) example pretend I have a Color enum:

public enum Color
{
  Red,
  Green,
  Blue,
}

And I'd like to accept both the color name or the hex value:

{
  "color": "FF0000",
  "highlightColor": "Blue"
}

And then if that object which was originally deserialized was then serialized I'd like it to consistently serialize to the default value names like the following:

{
  "color": "Red",
  "highlightColor": "Blue"
}

Originally I just added a new Enum value, set it equal to the default value and that works for deserialization and comparing the value to Color.Red in code. But doesn't work when re-serializing the value back out. It look like doing it this way always writes out the last defined value which in this case is the alias value instead of the desired default value.

public enum Color
{
  Red,
  [EnumMember(Value = "FF0000")]
  RedHex = Red,

  Green,
  [EnumMember(Value = "00FF00")]
  GreenHex = Green,

  Blue,
  [EnumMember(Value = "0000FF")]
  BlueHex = Blue,
}

Is there anything in your Converter that could help with this, or is there anything I'm missing?

JsonStringEnumMemberConverterOptionsAttribute & custom naming policy is not working together

Hi,
I've tried the combination of

`[JsonStringEnumMemberConverterOptions(deserializationFailureFallbackValue: MyEnum.Unknown)]
[JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum MyEnum
{
Unknown = 0,

[EnumMember(Value = "value1")]
ValidValue = 1

}`
When I use the following custom policy name :

public void ConfigureServices(IServiceCollection services) { services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new JsonStringEnumMemberConverter(new UpperSnakeCaseNamingPolicy(), false)); options.JsonSerializerOptions.WriteIndented = true; });

Issues observed:

  1. once the fallback attribute is added converter is not working on serialize/deserialize
  2. fallback value is not being handled

Am I missing something in my implementation?

NLog FileTarget KeepFileOpen=true

NLog opens and closes the file for every file-write by default for compatibility reasons. So instead of doing this:

Target Target = new FileTarget("File")
{
FileName = $"{LogFileDirectoryPath}nlog -${{shortdate}}.log",
Layout = Layout
};

Then do like this:

 Target Target = new FileTarget("File") 
 { 
 	FileName = $"{LogFileDirectoryPath}nlog -${{shortdate}}.log", 
 	Layout = Layout,
        KeepFileOpen = true,       // Serilog Default, but not for NLog
        ConcurrentWrites = false,  // Same as Serilog Shared
        Autoflush = true,          // Same as Serilog Buffered
 }; 

If you want to increase performance even further, then you can enable NLog AsyncWrapper (Enables batch witing of LogEvents using background-timer-thread. Gives much better performance when multiple threads are concurrently logging):

Target = new AsyncTargetWrapper("FileAsync", Target) { OverflowAction = AsyncTargetWrapperOverflowAction.Grow };

See also: https://github.com/NLog/NLog/wiki/performance

Add option for ignoring invalid enum string values

It would be nice to have an option for ignoring failures to parse enum values, and setting the member to the default value or the 0 value instead.

Example use case:

I am parsing data from an external service and one of the values is a string value with a limited set of values. I use an enum in conjunction with JsonStringEnumMemberConverter in order to keep my code clean and ensure I don't typo any of those strings the 100s of times I am comparing them throughout the code.

One day the external service adds in a new string to the list of strings they use in this field. Due to what I am doing I don't care about data with this new value. As things are right now the JSON parsing would fail.

If I could indicate to JsonStringEnumMemberConverter I wanted it to ignore these errors and return a default/0 value instead, I could reserve enum value 0 to mean "invalid" and check for this value to determine if the value was not parsed (or potentially use a nullable enum and check for null) and ignore the specific object. In other scenarios I could try to recover or use partial data after detecting this case.

Workaround for now I will probably go with is for me to pull in the source code of JsonStringEnumMemberConverter directly and replace the throw statements with return statements casting 0 to the proper type.

Unable to deserialize null to DateTime? using JsonMicrosoftDateTimeConverter

When trying to populate a nullable DateTime property from a JSON string with a null value an exception is thrown when employing JsonMicrosoftDateTimeConverter.

C#
[JsonConverter(typeof(JsonMicrosoftDateTimeConverter))]
public DateTime? PaymentDueDate { get; set; }

JSON:
...
"PaymentDueDate": null,
...

Exception:
Message:
System.Text.Json.JsonException : The JSON value could not be converted to System.Nullable 1[System.DateTime]. Path: $.PaymentDueDate | LineNumber: 75 | BytePositionInLine: 28.
Stack Trace:
JsonDateTimeConverter 1.ReadDateTime(Utf8JsonReader& reader)
JsonNullableDateTimeConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
JsonConverter 1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
JsonPropertyInfo 1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
ObjectDefaultConverter 1.ReadPropertyValue(Object obj, ReadStack& state, Utf8JsonReader& reader, JsonPropertyInfo jsonPropertyInfo, Boolean useExtensionProperty)
ObjectDefaultConverter 1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
JsonConverter 1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
JsonConverter 1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, Type returnType, JsonSerializerOptions options)
JsonSerializer.Deserialize[TValue](String json, Type returnType, JsonSerializerOptions options)
JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
JsonTests.AdHocDeserialiseTest() line 128
--- End of stack trace from previous location where exception was thrown ---

JsonStringEnumMemberConverter: Enums cannot be used as dictionary keys

Issue:

When using an enum with JsonStringEnumMemberConverter as a dictionary key it'll fail:

The type 'App.MyEnum' is not a supported dictionary key using converter of type 'System.Text.Json.Serialization.JsonStringEnumMemberConverter+EnumMemberConverter`1[App.MyEnum]'.

Reproduction:

The enum & class to reproduce this:

[JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum MyEnum
{
    [EnumMember(Value = "one")]
    One = 1,
    [EnumMember(Value = "two")]
    Two = 2,
}

public class MyModel
{
    [JsonPropertyName("stuff")]
    public IDictionary<MyEnum, string> Stuff { get; set; }
}

Suggested solution:

ReadAsPropertyName() & WriteAsPropertyName() need to be added to the converter to fix this: dotnet/runtime#46520 (comment)

JsonStringEnumMemberConverter must be defined on each property and does not work with arrays of enums

If I declare an enum for use with my data contract, it does not get applied unless the containing class member also specifies to use that converter.

Further more, this does not work if you have an array of your enum.

contracts.api.v1.role

    [JsonConverter(typeof(Macross.Json.Extensions.JsonStringEnumMemberConverter))] //doesn't work unless specified on each child property of the class that uses it
    public enum Role
    {
        [EnumMember(Value = "Admin")]
        Admin = 1,
        [EnumMember(Value = "User")]
        User = 2,
    }

contracts.api.v1.user

    public class User
    {
        public string Username { get; set; } = string.Empty;
        [JsonConverter(typeof(Macross.Json.Extensions.JsonStringEnumMemberConverter))]//exception: JsonStringEnumMemberConverter is not compatible with type Role[], does not deserialize properly without this declaration
        public Role[] Roles { get; set; } = new Role[0];
    }

suggestion: backward compatibility to deserialize same enum type option to itself

In case of using a custom converter policy for example:
options.Converters.Add(new JsonStringEnumMemberConverter(new UpperSnakeCaseNamingPolicy(), false));

 class public enum Days
{
   SundayDay,
   MondayDay,
   FridayDay
}

In POST action , when trying to deserialize "SUNDAY_DAY " the input can be :

  • "Sunday_Day"
  • "SUnday_DAY"
  • "sunday_day"
    the result of deserialize will be correct -> Days.SundayDay

We might want to support backward compatibility to deserialize same enum type option to itself.
So in POST action , when trying to deserialize "SundayDay " to -> Days.SundayDay it will work.

Adding this line of code, will accomplish that:

_TransformedToRaw[typedValue.ToString()] = new EnumInfo(name, typedValue, rawValue);

Please consider adding this capability to the code.
Thanks!

not working deserialazer in controller

Settings for controller:

builder.Services.AddControllers().AddJsonOptions(options =>
{ options.JsonSerializerOptions.Converters
.Add(new JsonStringEnumMemberConverter());
});

Enums:

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

namespace OCPIServer.Application.Ocpi.Contracts.Enums.Versioning;
//I tried with and without attributes
//[JsonStringEnumMemberConverterOptions(deserializationFailureFallbackValue: OcpiVersion.Unknown)]
//[JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum OcpiVersion
{
[EnumMember(Value = "unknown")]
Unknown = 0,

[EnumMember(Value = "2.0")]
v2_0 = 200,

[EnumMember(Value = "2.1")]
v2_1 = 210

}

Controller(endpoint):

[HttpGet("versions/{version}")]
    public GetVersionModel GetVersions(OcpiVersion version)
    {
        return _ocpiVersionsService.GetVersion(version);
    }

Everything works if you set 210 or v2_1_0 in the request. But I need the value (2.1.0) to be specified in the request. Like this
https://localhost:7059/.../versions/2.1.0.
But that doesn't work. Deserialization does not occur. I get error 400 "The value '2.1.0' is not valid."

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.