System.Text.Json: Handling Infinity values - json.net

From what I can tell, this is the appropriate way to handle double "Infinity" values when using NewtonsoftJson, to avoid those values when serializing.
x.SerializerSettings.FloatFormatHandling = FloatFormatHandling.DefaultValue;
What is the corresponding way to do this when using System.Text.Json?

Without a custom converter you cannot instruct System.Text.Json to write a 0, but - for the record - NaN and the infinities can be handled with JsonNumberHandling.AllowNamedFloatingPointLiterals.
From JsonNumberHandling Enum:
The "NaN", "Infinity", and "-Infinity" String tokens can be read as floating-point constants, and the Single and Double values for these constants will be written as their corresponding JSON string representations.
using System.Text.Json;
var options = new JsonSerializerOptions {
NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals
};
Console.WriteLine(JsonSerializer.Serialize(Double.NaN, options));
Console.WriteLine(JsonSerializer.Serialize(Double.NegativeInfinity, options));
Console.WriteLine(JsonSerializer.Serialize(Double.PositiveInfinity, options));
Console.WriteLine(JsonSerializer.Deserialize<double>("\"NaN\"", options));
Console.WriteLine(JsonSerializer.Deserialize<double>("\"-Infinity\"", options));
Console.WriteLine(JsonSerializer.Deserialize<double>("\"Infinity\"", options));
prints
"NaN"
"-Infinity"
"Infinity"
NaN
-∞
∞

I ended up using a custom converter.
In startup.cs
.AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new DoubleInfinityConverter())
);
The converter
internal class DoubleInfinityConverter : JsonConverter<double>
{
public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetDouble();
public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
{
if (double.IsNaN(value) || double.IsInfinity(value))
{
writer.WriteStringValue(default(double).ToString());
return;
}
writer.WriteStringValue(value.ToString());
}
}

Related

How can I determine if an Array is readonly using TS compiler-api?

I'd like to determine if an array type is readonly. This includes ReadonlyArray and readonly prefixed.
Examples:
type a = ReadonlyArray<string>
type b = readonly string[]
The relevant non-exposed TypeChecker code is:
let globalReadonlyArrayType = <GenericType>getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1) || globalArrayType;
function isReadonlyArrayType(type: Type): boolean {
return !!(getObjectFlags(type) & ObjectFlags.Reference) && (<TypeReference>type).target === globalReadonlyArrayType;
}
function getGlobalTypeOrUndefined(name: __String, arity = 0): ObjectType | undefined {
const symbol = getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined);
return symbol && <GenericType>getTypeOfGlobalSymbol(symbol, arity);
}
function getTypeOfGlobalSymbol(symbol: Symbol | undefined, arity: number): ObjectType {
function getTypeDeclaration(symbol: Symbol): Declaration | undefined {
const declarations = symbol.declarations;
for (const declaration of declarations) {
switch (declaration.kind) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
return declaration;
}
}
}
if (!symbol) {
return arity ? emptyGenericType : emptyObjectType;
}
const type = getDeclaredTypeOfSymbol(symbol);
if (!(type.flags & TypeFlags.Object)) {
error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbolName(symbol));
return arity ? emptyGenericType : emptyObjectType;
}
if (length((<InterfaceType>type).typeParameters) !== arity) {
error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity);
return arity ? emptyGenericType : emptyObjectType;
}
return <ObjectType>type;
}
TypeChecker Method
cspotcode pointed out that you can get IndexInfo via the TypeChecker.
const isReadonlyArrayType = (type: Type) =>
type.checker.isArrayLikeType(type) &&
!!type.checker.getIndexInfoOfType(type, IndexKind.Number)?.isReadonly
TS Compiler Method
The following matches the compiler's logic.
let globalReadonlyArrayType: Type;
export const isReadonlyArrayType = (type: Type): boolean => {
const { checker } = type;
if (!globalReadonlyArrayType) {
const symbol =
checker.resolveName('ReadonlyArray', /* location */ void 0, SymbolFlags.Type, /* excludeGlobals */ false)!;
globalReadonlyArrayType = checker.getDeclaredTypeOfSymbol(symbol);
}
return !!((type as ObjectType).objectFlags & ObjectFlags.Reference) &&
((<TypeReference>type).target === globalReadonlyArrayType);
};
Notes
It appears that there may be no immediate advantage of the TypeChecker method over using the Compiler method. The one concern that I had was that comparing target equality may fail if ReadonlyArray was extended, but it appears that this is currently not possible with TypeScript (v3.9.3)
Logic-wise, if performing isArrayLikeType first, the TypeChecker method would be performing a little more work, but likely not enough to worry about in terms of performance.
With that said, it seems that there may be advantage in the TypeChecker method over the second in the event that TS changes its readonly logic, allows extension of ReadonlyArray, etc.
For that reason, I'd recommend using the TypeChecker method.
If you're not using byots, you could probably replace the call to isArrayLikeType with !!((type as ObjectType).objectFlags & ObjectFlags.Reference)
Caveat: My understanding of ReadonlyArray is at a basic level, as of writing this, so if I'm wrong on any of this, please let me know!

JToken.ReadFrom vs JToken.Load?

The Json.net documentation between these 2 methods are exactly the same.
JToken.ReadFrom
JToken.Load
Both are static methods. Both have the same signatures.
Is there a preferred method? Does one depend on the next?
They are functionally identical.
In the abstract JToken class, Load ultimately calls ReadFrom, which figures out which type of JToken is being read and then delegates to the Load methods of the concrete subclasses as appropriate. JArray, JObject, JProperty and JConstrutor all have their own versions of Load which hide JToken.Load and create and return that object type (i.e. JObject.Load creates a JObject, etc.) Note that JValue does not have a Load method of its own, so that is handled in JToken.ReadFrom.
You can see for yourself in the source code:
public static JToken Load(JsonReader reader)
{
return Load(reader, null);
}
public static JToken Load(JsonReader reader, JsonLoadSettings? settings)
{
return ReadFrom(reader, settings);
}
public static JToken ReadFrom(JsonReader reader)
{
return ReadFrom(reader, null);
}
public static JToken ReadFrom(JsonReader reader, JsonLoadSettings? settings)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
...
switch (reader.TokenType)
{
case JsonToken.StartObject:
return JObject.Load(reader, settings);
case JsonToken.StartArray:
return JArray.Load(reader, settings);
case JsonToken.StartConstructor:
return JConstructor.Load(reader, settings);
case JsonToken.PropertyName:
return JProperty.Load(reader, settings);
case JsonToken.String:
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.Date:
case JsonToken.Boolean:
case JsonToken.Bytes:
JValue v = new JValue(reader.Value);
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Comment:
v = JValue.CreateComment(reader.Value!.ToString());
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Null:
v = JValue.CreateNull();
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Undefined:
v = JValue.CreateUndefined();
v.SetLineInfo(lineInfo, settings);
return v;
default:
throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
}

increase performance func<T> for reflection

I am currently working on a piece of code that determines the Type and the Value of a field (all enum's) so we can lookup a translation for the specific enum. I know this is a quite expensive, but i don't see a better solution. Who knows a better fit?
I am using automapper for mapping..
//removed some code
CreateMap<CarModel, CarDTO>
.ForMember(dst => dst.CarBodyType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.CarBodyType)))
.ForMember(dst => dst.FuelType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.FuelType)))
.ForMember(dst => dst.GearType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.GearType)))
//removed more for clearity (there are more enums)
private string ResolveEnumTranslation(CarDetail carDetail, ResolutionContext context, Func<CarDetail, object> property)
{
var selectedEnum = property.Invoke(carDetail);
if (context.Items.TryGetValue(localeKey, out var locale) && locale is string localeString)
{
return carDetail.Country.Translations
.FirstOrDefault(t => t.EnumType == selectedEnum.GetType().Name
&& t.EnumValue == (int)selectedEnum
&& string.Equals(t.CountryLocale?.Locale, localeString, StringComparison.OrdinalIgnoreCase))
?.TranslatedValue ?? property.Invoke(carDetail).ToString();
}
return selectedEnum.ToString();
}
really curious what would be a better approach.
You can make the method generic on the enum type, which allows to pass in the enum value as-is.
This enables to retrieve the enum type via typeof(T) which occurs at compile time, whereas selectedEnum.GetType() occurs at runtime.
You'll have to profile whether this improves performance.
Starting from C# 7.3 you can even use the generic Enum constraint to guard that an enum value gets passed as argument; eg.
where T : Enum
Call the method below via
ResolveEnumTranslation(detail, context, car.GearType)
private string ResolveEnumTranslation<T>(
CarDetail carDetail, ResolutionContext context, T selectedEnum
) where T : Enum
{
var typeName = typeof(T).Name;
if (context.Items.TryGetValue(localeKey, out var locale) && locale is string localeString)
{
return carDetail.Country.Translations
.FirstOrDefault(t =>
t.EnumType == typeName
&& t.EnumValue == Convert.ToInt32(selectedEnum)
&& string.Equals(t.CountryLocale?.Locale, localeString, StringComparison.OrdinalIgnoreCase)
)?.TranslatedValue ?? selectedEnum.ToString();
}
return selectedEnum.ToString();
}

dart, how to get generic type of method parameter using reflection?

I have test application:
import 'dart:mirrors';
class A {
void eventHandlerInt(List<int> x){}
void eventHandlerBool(List<bool> x){}
}
void testMirrors(aFunction){
ClosureMirror mir = reflect(aFunction);
var param = mir.function.parameters.first;
//How to get the Type T of List<T> of the first param?
}
void main() {
var a = new A();
testMirrors(a.eventHandlerInt);
testMirrors(a.eventHandlerBool);
}
I would like to be able to find out what the generic type is of the first parameter of the method passed into testMirrors, so in the example above it would be int then bool. Is this even possible? if I inspect param the type property is null.
List<TypeMirror> types = mir.function.parameters.first.type.typeArguments;
param.forEach((e) => print(e.simpleName));
prints
Symbol("int")
Symbol("bool")

Using Moq can you verify a method call with an anonymous type?

I'm trying to verify a method call using Moq, but I can't quite get the syntax right. Currently, I've got this as my verify:
repository.Verify(x => x.ExecuteNonQuery("fav_AddFavorites", new
{
fid = 123,
inputStr = "000456"
}), Times.Once());
The code compiles, but the test fails with the error:
Expected invocation on the mock once, but was 0 times:
x => x.ExecuteNonQuery("fav_AddFavorites", new <>f__AnonymousType0<Int32, String>(123, "000456"))
No setups configured.
Performed invocations:
IRepository.ExecuteNonQuery("fav_AddFavorites", { fid = 123, inputStr = 000456 })
How can I verify the method call and match the method parameters for an anonymous type?
UPDATE
To answer the questions:
I am trying to verify both that the method was called and that the parameters are correct.
The signature of the method I'm trying to verify is:
int ExecuteNonQuery(string query, object param = null);
The setup code is simply:
repository = new Mock<IRepository>();
UPDATE 2
It looks like this is a problem with Moq and how it handles anonymous types in .Net. The code posted by Paul Matovich runs fine, however, once the code and the test are in different assemblies the test fails.
This Passes
public class Class1
{
private Class2 _Class2;
public Class1(Class2 class2)
{
_Class2 = class2;
}
public void DoSomething(string s)
{
_Class2.ExecuteNonQuery(s, new { fid = 123, inputStr = "000456" });
}
}
public class Class2
{
public virtual void ExecuteNonQuery(string s, object o)
{
}
}
/// <summary>
///A test for ExecuteNonQuery
///</summary>
[TestMethod()]
public void ExecuteNonQueryTest()
{
string testString = "Hello";
var Class2Stub = new Mock<Class2>();
Class1 target = new Class1(Class2Stub.Object);
target.DoSomething(testString);
Class2Stub.Verify(x => x.ExecuteNonQuery(testString, It.Is<object>(o => o.Equals(new { fid = 123, inputStr = "000456" }))), Times.Once());
}
##Update##
That is strange, it doesn't work in different assemblies. Someone can give us the long definition about why the object.equals from different assemblies behaves differently, but for different assemblies, this will work, any variance in the object values will return a different hash code.
Class2Stub.Verify(x => x.ExecuteNonQuery(testString, It.Is<object>(o => o.GetHashCode() == (new { fid = 123, inputStr = "000456" }).GetHashCode())), Times.Once());
One option is to "verify" it in a Callback. Obviously this needs to be done at Setup time, e.g.:
aMock.Setup(x => x.Method(It.IsAny<object>())).Callback<object>(
(p1) =>
{
dynamic o = p1;
Assert.That(o.Name, Is.EqualTo("Bilbo"));
});
None of the answers are great when your test assembly is different than the system under test's assembly (really common). Here's my solution that uses JSON serialization and then strings comparison.
Test Helper Function:
using Newtonsoft.Json;
public static class VerifyHelper
{
public static bool AreEqualObjects(object expected, object actual)
{
var expectedJson = JsonConvert.SerializeObject(expected);
var actualJson = JsonConvert.SerializeObject(actual);
return expectedJson == actualJson;
}
}
Example System Under Test:
public void DoWork(string input)
{
var obj = new { Prop1 = input };
dependency.SomeDependencyFunction(obj);
}
Example Unit Test:
var expectedObject = new { Prop1 = "foo" };
sut.DoWork("foo");
dependency.Verify(x => x.SomeDependencyFunction(It.Is<object>(y => VerifyHelper.AreEqualObjects(expectedObject, y))), Times.Once());
This solution is really simple, and I think makes the unit test easier to understand as opposed to the other answers in this thread. However, because it using simple string comparison, the test's anonymous object has to be set up exactly the same as the system under the test's anonymous object. Ergo, let's say you only cared to verify the value of a single property, but your system under test sets additional properties on the anonymous object, your unit test will need to set all those other properties (and in the same exact order) for the helper function to return true.
I created a reusable method based on Pauls answer:
object ItIsAnonymousObject(object value)
{
return It.Is<object>(o => o.GetHashCode() == value.GetHashCode());
}
...
dependency.Verify(
x => x.SomeDependencyFunction(ItIsAnonymousObject(new { Prop1 = "foo" })),
Times.Once());
Also, this can be used for property name case-insensitive comparison:
protected object ItIsAnonymousObject(object value)
{
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return It.Is<object>(o => JsonSerializer.Serialize(o, options) == JsonSerializer.Serialize(value, options));
}

Resources