codecutout / jsonapiserializer Goto Github PK
View Code? Open in Web Editor NEWJsonApiSerializer supports configurationless serializing and deserializing objects into the json:api format (http://jsonapi.org).
License: MIT License
JsonApiSerializer supports configurationless serializing and deserializing objects into the json:api format (http://jsonapi.org).
License: MIT License
how can i convert the class type name to snake case ?
Always get following error after upgrade from 1.4.0 to >=1.5.0
System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'.
at JsonApiSerializer.JsonConverters.ResourceObjectConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at JsonApiSerializer.JsonConverters.DocumentRootConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs:line 652
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriterjsonWriter, Object value, Type objectType) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs:line 80
Controller method that is called and producing above error:
public async Task<string> GetSampleSheet(string runName)
{
SomeObject someObject= new SomeObject();
var json = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonApiSerializerSettings()));
return json;
}
If i remove the new JsonApiSerializerSettings() than it works but i need the data object to appear in response.
.csproj (.net core 2.2.0)
<PackageReference Include="Microsoft.AspNetCore.App" />
...
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="JsonApiSerializer" Version="1.6.1" />
...
I checked the code on line 652 of JsonSerializerInternalWriter.cs but it is not clear to me why it would fail there.
Can you help me figure out where the problem lies in?
with the model
public interface IWithId
{
string Id { get; set; }
}
public interface ILocationWithId : IWithId
{
}
public class LocationWithId : ILocationWithId
{
public string Id { get; set; }
public IEnumerable<ILocationWithId> Parents { get; set; }
}
run with
var root = new LocationWithId()
{
Id = "Willesdon Green",
Parents = new ILocationWithId[]
{
new LocationWithId()
{
Id = "Brent",
Parents = new ILocationWithId[]
{
new LocationWithId()
{
Id = "London"
}
}
}
}
};
var json = JsonConvert.SerializeObject(root, settings);
produces the following incorrect result (note the array is located at "parents" rather than "data"
{
"data": {
"type": "locationwithid",
"id": "Willesdon Green",
"relationships": {
"parents": [
{
"data": {
"id": "Brent",
"type": "locationwithid"
}
}
]
}
},
"included": [
{
"type": "locationwithid",
"id": "Brent",
"relationships": {
"parents": [
{
"data": {
"id": "London",
"type": "locationwithid"
}
}
]
}
}
]
}
I experience an exception when deserialize an object.
Example:
{"data": null}
Exception:
JsonApiSerializer.Exceptions.JsonApiFormatException: 'Unable to find closing element element'.
I have an example json api resource that looks like this:
{ "data": [ { "attributes": { "name": "Test", "description": "Unassigned" }, "relationships": { "areas": { "links": { "self": "https://localhost:44317/api/types/1/relationships/areas", "related": "https://localhost:44317/api/types/1/areas" } } }, "type": "types", "id": "1" } ] }
Note that there is no 'data' in the relationship - this is intentional because we don't want to include them in this request to the server.
I get an exception: Expected to find nested object within data[0].relationships.areas that matches \data\
If I'm reading this right, it sounds like the deserializer is expecting "data". The JSON API spec (https://jsonapi.org/format/#document-resource-object-relationships) says it must contain at least one of the following: links, data, meta.
So I believe in this case data should not be required, because 'links' are present. In which case the relationships should just be empty. Could be totally wrong though ¯_(ツ)_/¯
Hi,
This is really a question not an issue. I've kicked off my API explorations with .NET Core and the type of approach here (https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db). This project looks perfectly aligned to that, with the same structure for defining the objects etc.
I was wondering when this project is recommended versus using the deserialisation provided by WebAPI when you tell it a particular object is in the request body and should be deserialised from there.
Many thanks!
Issue refers to the following documentation: https://github.com/codecutout/JsonApiSerializer#integrating-with-microsoftaspnetcoremvc
Documentation recommends newing up JsonInputFormatter
with JsonInputFormatter(ILogger, JsonSerializerSettings, ArrayPool<char>, ObjectPoolProvider)
constructor (JsonInputFormatter`4
). Per Microsoft, this constructor is now obsoleted: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.formatters.jsoninputformatter.-ctor?view=aspnetcore-2.2#Microsoft_AspNetCore_Mvc_Formatters_JsonInputFormatter__ctor_Microsoft_Extensions_Logging_ILogger_Newtonsoft_Json_JsonSerializerSettings_System_Buffers_ArrayPool_System_Char__Microsoft_Extensions_ObjectPool_ObjectPoolProvider_
It is still possible to use this constructor, but due to likelihood that it will be removed from future versions of of dotnet, I am looking for a better/more future-proof way of integrating. The only remaining non-obsolete constructor requires passing both MvcOptions
(available in IServiceCollection.AddMvc`1
) and MvcJsonOptions
(available in IMvcBuilder.AddJsonOptions`1)
), but I've not yet found a way to access both MvcOptions
and MvcJsonOptions
in the same place in order to use the preferred constructor.
Though this is not definitive, it appears that Microsoft intends that custom serialization settings be achieved via IMvcBuilder.AddJsonOptions`1
: aspnet/Mvc#4339 (comment)
I will follow up if I find a good solution for integrating with Aspnet Core WebApi that doesn't go against current "best practices", but wanted to post here as well in case it is relevant to others.
Thanks.
~Jordan
Hey there,
We have a "Match" resource which we are serializing and sending to a client, within this match resource we have a relationship to a set of "Spectator" resources (Both have an Id property and are setup correctly) however there may not be any spectators watching a match so there is a possibility that this list can be empty.
When serializing the empty list it seems to put it as a attribute rather than a relationship. Whereas it seems to be setup correctly when there is at least one spectator in the list.
Is there any way around this?
Example Output:
"data": [
{
"type": "match",
"id": "32737895-7e44-408e-914b-e70a578dde88",
"links": {
"self": "ommitted",
"schema": "ommitted"
},
"attributes": {
"shardId": "pc-eu",
"createdAt": "2018-03-16T17:52:25.5652711Z",
"duration": 1000,
"stats": {},
"tags": {},
"spectators": {
"data": []
},
"patchVersion": "master"
},
"relationships": {
"rosters": {
"data": [
//Many Rosters omitted for brevity
]
},
"assets": {
"data": [
{
"id": "3f21af6f-6368-407a-bd59-cbf29bd0dca2",
"type": "asset"
}
]
}
}
}
]
The following code produces a stack overflow (regardless of whether it's the parent or child that's serialized at the end):
type Parent =
{ Id: string
Data: string
Child: Child option }
and Child =
{ Id: string
Data: string
mutable Parent: Parent option }
let child = {Id = "b"; Data = "dataB"; Parent = None}
let parent = {Id = "a"; Data = "dataA"; Child = Some child}
child.Parent <- Some parent
JsonConvert.SerializeObject(child, JsonApiSerializerSettings())
On the contrary, it works fine when the types are normal classes:
type Parent() =
member val Id: string = "" with get, set
member val Data: string = "" with get, set
member val Child: Child option = None with get, set
and Child() =
member val Id: string = "" with get, set
member val Data: string = "" with get, set
member val Parent: Parent option = None with get, set
let child = Child(Id = "b", Data = "dataB", Parent = None)
let parent = Parent(Id = "a", Data = "dataA", Child = Some child)
child.Parent <- Some parent
JsonConvert.SerializeObject(child, JsonApiSerializerSettings())
I'd really like to use records for my API models though, due to several other benefits. Would it be possible for you to investigate this?
Perhaps it would help you to see what the two approaches compile to. Here's the record types and here's the classes from SharpLab.io.
using Microsoft.FSharp.Core;
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: FSharpInterfaceDataVersion(2, 0, 0)]
[CompilationMapping(SourceConstructFlags.Module)]
public static class _
{
[CompilationMapping(SourceConstructFlags.RecordType)]
[Serializable]
public sealed class Parent : IEquatable<_.Parent>, IStructuralEquatable, IComparable<_.Parent>, IComparable, IStructuralComparable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal string Id@;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal string Data@;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal FSharpOption<_.Child> Child@;
[CompilationMapping(SourceConstructFlags.Field, 0)]
public string Id
{
get
{
return this.Id@;
}
}
[CompilationMapping(SourceConstructFlags.Field, 1)]
public string Data
{
get
{
return this.Data@;
}
}
[CompilationMapping(SourceConstructFlags.Field, 2)]
public FSharpOption<_.Child> Child
{
get
{
return this.Child@;
}
}
public Parent(string id, string data, FSharpOption<_.Child> child)
{
this.Id@ = id;
this.Data@ = data;
this.Child@ = child;
}
[CompilerGenerated]
public override string ToString()
{
return ExtraTopLevelOperators.PrintFormatToString<FSharpFunc<_.Parent, string>>(new PrintfFormat<FSharpFunc<_.Parent, string>, Unit, string, string, _.Parent>("%+A")).Invoke(this);
}
[CompilerGenerated]
public sealed override int CompareTo(_.Parent obj)
{
if (this != null)
{
if (obj == null)
{
return 1;
}
IComparer genericComparer = LanguagePrimitives.GenericComparer;
int num = string.CompareOrdinal(this.Id@, obj.Id@);
if (num < 0)
{
return num;
}
if (num > 0)
{
return num;
}
genericComparer = LanguagePrimitives.GenericComparer;
int num2 = string.CompareOrdinal(this.Data@, obj.Data@);
if (num2 < 0)
{
return num2;
}
if (num2 > 0)
{
return num2;
}
return LanguagePrimitives.HashCompare.GenericComparisonWithComparerIntrinsic<FSharpOption<_.Child>>(LanguagePrimitives.GenericComparer, this.Child@, obj.Child@);
}
else
{
if (obj != null)
{
return -1;
}
return 0;
}
}
[CompilerGenerated]
public sealed override int CompareTo(object obj)
{
return this.CompareTo((_.Parent)obj);
}
[CompilerGenerated]
public sealed override int CompareTo(object obj, IComparer comp)
{
_.Parent parent = (_.Parent)obj;
if (this != null)
{
if ((_.Parent)obj == null)
{
return 1;
}
int num = string.CompareOrdinal(this.Id@, parent.Id@);
if (num < 0)
{
return num;
}
if (num > 0)
{
return num;
}
int num2 = string.CompareOrdinal(this.Data@, parent.Data@);
if (num2 < 0)
{
return num2;
}
if (num2 > 0)
{
return num2;
}
return LanguagePrimitives.HashCompare.GenericComparisonWithComparerIntrinsic<FSharpOption<_.Child>>(comp, this.Child@, parent.Child@);
}
else
{
if ((_.Parent)obj != null)
{
return -1;
}
return 0;
}
}
[CompilerGenerated]
public sealed override int GetHashCode(IEqualityComparer comp)
{
if (this != null)
{
int num = 0;
num = -1640531527 + (LanguagePrimitives.HashCompare.GenericHashWithComparerIntrinsic<FSharpOption<_.Child>>(comp, this.Child@) + ((num << 6) + (num >> 2)));
int arg_43_0 = -1640531527;
string text = this.Data@;
num = arg_43_0 + (((text == null) ? 0 : text.GetHashCode()) + ((num << 6) + (num >> 2)));
int arg_65_0 = -1640531527;
text = this.Id@;
return arg_65_0 + (((text == null) ? 0 : text.GetHashCode()) + ((num << 6) + (num >> 2)));
}
return 0;
}
[CompilerGenerated]
public sealed override int GetHashCode()
{
return this.GetHashCode(LanguagePrimitives.GenericEqualityComparer);
}
[CompilerGenerated]
public sealed override bool Equals(object obj, IEqualityComparer comp)
{
if (this != null)
{
_.Parent parent = obj as _.Parent;
return parent != null && string.Equals(this.Id@, parent.Id@) && string.Equals(this.Data@, parent.Data@) && LanguagePrimitives.HashCompare.GenericEqualityWithComparerIntrinsic<FSharpOption<_.Child>>(comp, this.Child@, parent.Child@);
}
return obj == null;
}
[CompilerGenerated]
public sealed override bool Equals(_.Parent obj)
{
if (this != null)
{
return obj != null && string.Equals(this.Id@, obj.Id@) && string.Equals(this.Data@, obj.Data@) && LanguagePrimitives.HashCompare.GenericEqualityERIntrinsic<FSharpOption<_.Child>>(this.Child@, obj.Child@);
}
return obj == null;
}
[CompilerGenerated]
public sealed override bool Equals(object obj)
{
_.Parent parent = obj as _.Parent;
return parent != null && this.Equals(parent);
}
}
[CompilationMapping(SourceConstructFlags.RecordType)]
[Serializable]
public sealed class Child : IEquatable<_.Child>, IStructuralEquatable, IComparable<_.Child>, IComparable, IStructuralComparable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal string Id@;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal string Data@;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public FSharpOption<_.Parent> Parent@;
[CompilationMapping(SourceConstructFlags.Field, 0)]
public string Id
{
get
{
return this.Id@;
}
}
[CompilationMapping(SourceConstructFlags.Field, 1)]
public string Data
{
get
{
return this.Data@;
}
}
[CompilationMapping(SourceConstructFlags.Field, 2)]
public FSharpOption<_.Parent> Parent
{
get
{
return this.Parent@;
}
set
{
this.Parent@ = value;
}
}
public Child(string id, string data, FSharpOption<_.Parent> parent)
{
this.Id@ = id;
this.Data@ = data;
this.Parent@ = parent;
}
[CompilerGenerated]
public override string ToString()
{
return ExtraTopLevelOperators.PrintFormatToString<FSharpFunc<_.Child, string>>(new PrintfFormat<FSharpFunc<_.Child, string>, Unit, string, string, _.Child>("%+A")).Invoke(this);
}
[CompilerGenerated]
public sealed override int CompareTo(_.Child obj)
{
if (this != null)
{
if (obj == null)
{
return 1;
}
IComparer genericComparer = LanguagePrimitives.GenericComparer;
int num = string.CompareOrdinal(this.Id@, obj.Id@);
if (num < 0)
{
return num;
}
if (num > 0)
{
return num;
}
genericComparer = LanguagePrimitives.GenericComparer;
int num2 = string.CompareOrdinal(this.Data@, obj.Data@);
if (num2 < 0)
{
return num2;
}
if (num2 > 0)
{
return num2;
}
return LanguagePrimitives.HashCompare.GenericComparisonWithComparerIntrinsic<FSharpOption<_.Parent>>(LanguagePrimitives.GenericComparer, this.Parent@, obj.Parent@);
}
else
{
if (obj != null)
{
return -1;
}
return 0;
}
}
[CompilerGenerated]
public sealed override int CompareTo(object obj)
{
return this.CompareTo((_.Child)obj);
}
[CompilerGenerated]
public sealed override int CompareTo(object obj, IComparer comp)
{
_.Child child = (_.Child)obj;
if (this != null)
{
if ((_.Child)obj == null)
{
return 1;
}
int num = string.CompareOrdinal(this.Id@, child.Id@);
if (num < 0)
{
return num;
}
if (num > 0)
{
return num;
}
int num2 = string.CompareOrdinal(this.Data@, child.Data@);
if (num2 < 0)
{
return num2;
}
if (num2 > 0)
{
return num2;
}
return LanguagePrimitives.HashCompare.GenericComparisonWithComparerIntrinsic<FSharpOption<_.Parent>>(comp, this.Parent@, child.Parent@);
}
else
{
if ((_.Child)obj != null)
{
return -1;
}
return 0;
}
}
[CompilerGenerated]
public sealed override int GetHashCode(IEqualityComparer comp)
{
if (this != null)
{
int num = 0;
num = -1640531527 + (LanguagePrimitives.HashCompare.GenericHashWithComparerIntrinsic<FSharpOption<_.Parent>>(comp, this.Parent@) + ((num << 6) + (num >> 2)));
int arg_43_0 = -1640531527;
string text = this.Data@;
num = arg_43_0 + (((text == null) ? 0 : text.GetHashCode()) + ((num << 6) + (num >> 2)));
int arg_65_0 = -1640531527;
text = this.Id@;
return arg_65_0 + (((text == null) ? 0 : text.GetHashCode()) + ((num << 6) + (num >> 2)));
}
return 0;
}
[CompilerGenerated]
public sealed override int GetHashCode()
{
return this.GetHashCode(LanguagePrimitives.GenericEqualityComparer);
}
[CompilerGenerated]
public sealed override bool Equals(object obj, IEqualityComparer comp)
{
if (this != null)
{
_.Child child = obj as _.Child;
return child != null && string.Equals(this.Id@, child.Id@) && string.Equals(this.Data@, child.Data@) && LanguagePrimitives.HashCompare.GenericEqualityWithComparerIntrinsic<FSharpOption<_.Parent>>(comp, this.Parent@, child.Parent@);
}
return obj == null;
}
[CompilerGenerated]
public sealed override bool Equals(_.Child obj)
{
if (this != null)
{
return obj != null && string.Equals(this.Id@, obj.Id@) && string.Equals(this.Data@, obj.Data@) && LanguagePrimitives.HashCompare.GenericEqualityERIntrinsic<FSharpOption<_.Parent>>(this.Parent@, obj.Parent@);
}
return obj == null;
}
[CompilerGenerated]
public sealed override bool Equals(object obj)
{
_.Child child = obj as _.Child;
return child != null && this.Equals(child);
}
}
}
namespace <StartupCode$_>
{
internal static class $_
{
}
}
using Microsoft.FSharp.Core;
using System;
using System.Reflection;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: FSharpInterfaceDataVersion(2, 0, 0)]
[CompilationMapping(SourceConstructFlags.Module)]
public static class _
{
[CompilationMapping(SourceConstructFlags.ObjectType)]
[Serializable]
public class Parent
{
internal string Id@;
internal string Data@;
internal FSharpOption<_.Child> Child@;
public string Id
{
get
{
return this.Id@;
}
set
{
this.Id@ = value;
}
}
public string Data
{
get
{
return this.Data@;
}
set
{
this.Data@ = value;
}
}
public FSharpOption<_.Child> Child
{
get
{
return this.Child@;
}
set
{
this.Child@ = value;
}
}
public Parent() : this()
{
this.Id@ = "";
this.Data@ = "";
this.Child@ = null;
}
}
[CompilationMapping(SourceConstructFlags.ObjectType)]
[Serializable]
public class Child
{
internal string Id@;
internal string Data@;
internal FSharpOption<_.Parent> Parent@;
public string Id
{
get
{
return this.Id@;
}
set
{
this.Id@ = value;
}
}
public string Data
{
get
{
return this.Data@;
}
set
{
this.Data@ = value;
}
}
public FSharpOption<_.Parent> Parent
{
get
{
return this.Parent@;
}
set
{
this.Parent@ = value;
}
}
public Child() : this()
{
this.Id@ = "";
this.Data@ = "";
this.Parent@ = null;
}
}
}
namespace <StartupCode$_>
{
internal static class $_
{
}
}
An Item similiar to the following
var root = new LocationWithId()
{
Id = "Willesdon Green",
Parents = Enumerable.Range(0, 3).Select(i => new LocationWithId()
{
Id = $"London_{i}_"
})
};
Does not serialize the list correct (array is in the wrong location)
Hello, (it's me again!)
I'm encountering a problem with a custom JsonConverter
that converts longs
to TimeSpan
s.
It seems to work fine with another Json.NET deserializer I have in the app (the one created by Akavache for offline caching), but fails with JsonApiSerializer (it's not called at all).
The exception:
Newtonsoft.Json.JsonSerializationException: Error converting value 5581 to type 'System.TimeSpan'. Path 'data[0].attributes.duration'.
|-> System.ArgumentException: Could not cast or convert from System.Int64 to System.TimeSpan.
01-02 20:14:01.971 E/mono ( 5029): ReactiveUI.UnhandledErrorException: An object implementing IHandleObservableErrors (often a ReactiveCommand or ObservableAsPropertyHelper) has errored, thereby breaking its observable pipeline. To prevent this, ensure the pipeline does not error, or Subscribe to the ThrownExceptions property of the object in question to handle the erroneous case. ---> Newtonsoft.Json.JsonSerializationException: Error converting value 5581 to type 'System.TimeSpan'. Path 'data[0].attributes.duration'. ---> System.ArgumentException: Could not cast or convert from System.Int64 to System.TimeSpan.
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable (System.Object value, System.Type initialType, System.Type targetType) [0x00067] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast (System.Object initialValue, System.Globalization.CultureInfo culture, System.Type targetType) [0x00031] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) [0x000b0] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): --- End of inner exception stack trace ---
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) [0x000e0] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0009b] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.971 E/mono ( 5029): at JsonApiSerializer.Util.ReaderUtil.TryPopulateProperty (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonReader value) [0x00012] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.971 E/mono ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter.PopulateProperties (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract) [0x00064] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.971 E/mono ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter+<>c__DisplayClass3_0.<ReadJson>b__0 (JsonApiSerializer.Util.ForkableJsonReader dataReader) [0x000fb] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.971 E/mono ( 5029): at JsonApiSerializer.Util.ReaderUtil.ReadInto[TReader,TResult] (TReader reader, System.Text.RegularExpressions.Regex pathRegex, System.Func`2[T,TResult] action) [0x0000d] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.971 E/mono ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x0004b] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.971 E/mono ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader,
01-02 20:14:01.973 E/mono-rt ( 5029): [ERROR] FATAL UNHANDLED EXCEPTION: ReactiveUI.UnhandledErrorException: An object implementing IHandleObservableErrors (often a ReactiveCommand or ObservableAsPropertyHelper) has errored, thereby breaking its observable pipeline. To prevent this, ensure the pipeline does not error, or Subscribe to the ThrownExceptions property of the object in question to handle the erroneous case. ---> Newtonsoft.Json.JsonSerializationException: Error converting value 5581 to type 'System.TimeSpan'. Path 'data[0].attributes.duration'. ---> System.ArgumentException: Could not cast or convert from System.Int64 to System.TimeSpan.
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable (System.Object value, System.Type initialType, System.Type targetType) [0x00067] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast (System.Object initialValue, System.Globalization.CultureInfo culture, System.Type targetType) [0x00031] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) [0x000b0] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): --- End of inner exception stack trace ---
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) [0x000e0] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0009b] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at JsonApiSerializer.Util.ReaderUtil.TryPopulateProperty (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonReader value) [0x00012] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter.PopulateProperties (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract) [0x00064] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter+<>c__DisplayClass3_0.<ReadJson>b__0 (JsonApiSerializer.Util.ForkableJsonReader dataReader) [0x000fb] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at JsonApiSerializer.Util.ReaderUtil.ReadInto[TReader,TResult] (TReader reader, System.Text.RegularExpressions.Regex pathRegex, System.Func`2[T,TResult] action) [0x0000d] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at JsonApiSerializer.JsonConverters.ResourceObjectConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x0004b] in <114082c9b9634d14a07a89c38a135e48>:0
01-02 20:14:01.973 E/mono-rt ( 5029): at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.Js
The property in question:
[JsonConverter(typeof(TimeSpanInSecondsConverter))]
public TimeSpan Duration { get; set; }
TimeSpanInSecondsConverter
class (should not be relevant, just in case):namespace WeBSurg.Core.JsonConverters
{
using System;
using Newtonsoft.Json;
public class TimeSpanInSecondsConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(TimeSpan);
public override bool CanRead => true;
public override bool CanWrite => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType != typeof(TimeSpan))
throw new ArgumentException();
if (!(reader.Value is long spanSeconds))
return null;
return TimeSpan.FromSeconds(spanSeconds);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var duration = (TimeSpan) value;
writer.WriteValue((int) duration.TotalSeconds);
}
}
}
Does JsonApiSerializer supports JsonConverters?
Anyway, thanks for this piece of software, it helped me a lot these last times :)
var root = new[]
{
new LocationWithId() { Id = "London", Description ="Capital" },
new LocationWithId() {
Id = "Kings-Cross",
Parents = new[] { new LocationWithId() { Id = "London", Description= "Capital" } }
},
new LocationWithId() {
Id = "Farringdon",
Parents = new[] { new LocationWithId() { Id = "London", Description = "Capital" } }
},
};
has an included element, however as London is already in the data the included element is redundant.
I have the following classes:
public class MyClass
{
public string Id { get; set; }
public NestedClass MyObject { get; set; }
}
public class NestedClass
{
public JObject Data { get; set; }
}
and if i do the following:
var doc = new DocumentRoot<MyClass>()
{
Data = new MyClass()
{
MyObject = new NestedClass()
{
}
}
};
var json = JsonConvert.SerializeObject(doc, new JsonApiSerializerSettings());
this will produce:
{
"data": {
"type": "myclass",
"relationships": {
"myObject": {
}
}
}
}
where i'm needing myObject
to be an attribute, not a relationship. Is there something i can do to mitigate this? I assume it's because a JObject
has a Type
property....
Hi,
In my API I want to be able dynamically serialize properties on my model. For example the user only requests certain fields - http://myurl.com?fields[myobject]=fieldA,fieldB,fieldC
I want to be able to read the fields[myobject] property on my model and serialize only the properties that have been asked for by the user.
Hence in my controller I want to set the Conditional Properties on my model depending on fields user requests -
https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm
Unfortunately this doesn't seem to apply/work with JsonApiSerializer. As soon as the JsonApiSerializer is disabled ( and reverted to default Json.NET) Conditional Properties work.
Any suggestions how to get Conditional Properties working with JsonApiSerializer ?
Thanks
I have a sign-in endpoint that should accept two different resources: A User
resource with username and password, and a ConfirmationCode
resource containing an SMS confirmation code.
For example, it should accept both
{
"data": {
"type": "user",
"attributes": {
"username": "someUser",
"password": "somePwd"
}
}
}
and
{
"data": {
"type": "confirmation-code",
"id": "6081f88f-8a7d-44ef-902b-76fc66461808",
"attributes": {
"code": "1234"
}
}
}
I would expect that when I try to deserialize the first json above to a ConfirmationCode
object, it should fail since the JSON API type does not match. What actually happens is that I simply get an empty User
object.
Would it be possible to check the "type" parameter before deserializing, and failing in some way (e.g. throwing an exception) if the type does not match?
Serialized an object with:
var t = JsonConvert.SerializeObject(allMethod.Data, new JsonApiSerializerSettings());
var tt = JsonConvert.DeserializeObject<Compound[]>(t, new JsonApiSerializerSettings());
where allMethod.Data is Compound[]. During deserialize I get the following Exception
JsonApiSerializer.Exceptions.JsonApiFormatException was unhandled
HResult=-2146233088
Message=Expected to find json object at
Path=""
Source=JsonApiSerializer
StackTrace:
at JsonApiSerializer.Util.ReaderUtil.d__1.MoveNext()
at JsonApiSerializer.Util.ReaderUtil.ReadAheadToIdentifyObject(ForkableJsonReader reader)
at JsonApiSerializer.JsonConverters.IncludedConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at JsonApiSerializer.JsonConverters.DocumentRootConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
at JsonApiSerializer.JsonConverters.DocumentRootConverter.TryResolveAsRootData(JsonReader reader, Type objectType, JsonSerializer serializer, Object& obj)
at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at TestBed.Program.Main(String[] args) in C:_\Thanos\TestBed\Program.cs:line 30
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
It would be useful to get the property of the object that causes this exception instead of getting an unspecified "Expected to find json object at" message.
By The way when I use the JsonConvert.DeserializeObject<Compound[]>(t); with defaults it seems to work. Might this be an issue with the already mentioned null handling?
How to add Total Pages and Total Count in Meta?
Currently there is no special handling for errors. So it is impossible to serialize or deserialize error documents.
how to convert the id with integer type to string ?
I tried the serialization example and it works correctly like documented.
But when I try to serialize one of my objects I don't understand why it is not serialized with the JSON:API structure.
My class is:
public class VLSignUpRequestDTO
{
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("first-name")]
public string FirstName { get; set; }
[JsonProperty("last-name")]
public string LastName { get; set; }
[JsonProperty("password")]
public string Password { get; set; }
[JsonProperty("password-confirmation")]
[JsonIgnore]
public string ConfirmPassword { get; set; }
[JsonProperty("referral-code")]
public string ReferralCode { get; set; }
[JsonProperty("accept_terms")]
public bool AreTermsAccepted { get; set; }
[JsonProperty("shop")]
public bool? Shop { get; set; }
[JsonProperty("company-name")]
public string CompanyName { get; set; }
}
Then I try to serialize it like this:
var signUp = new VLSignUpRequestDTO
{
AreTermsAccepted = true,
CompanyName = "My Company",
Email = "[email protected]",
FirstName = "John",
LastName = "Doe",
Password = "qwerty"
};
string json = JsonConvert.SerializeObject(signUp, new JsonApiSerializerSettings());
And the json result string is this:
[
{
"email": "[email protected]",
"first-name": "John",
"last-name": "Doe",
"password": "qwerty",
"accept_terms": true,
"company-name": "My Company"
}
]
How can I get it to format as
{
"data": {
"type": "VLSignUpRequestDTO",
"attributes": {
"email": "[email protected]",
"first-name": "John",
"last-name": "Doe",
"password": "qwerty",
"shop": false,
"company-name": "My Company",
"referral-code": ""
}
}
}
etc?
I would like all properties to be kebab-case by default, e.g. MyProperty
becomes my-property
. This is dead simple with the help of Humanizer's Underscore()
and Hyphenate()
string extensions by defining a simple contract resolver (shown in F# below):
type KebabCaseContractResolver() =
inherit DefaultContractResolver()
override __.ResolvePropertyName(propName: string) =
propName.Underscore().Hyphenate()
However, JsonApiSerializer comes with its own contract resolver, so I can't use the one I created above. I have also tried subclassing your contract resolver and overriding ResolvePropertyName
as above, but that had no effect and ResolvePropertyName
wasn't even called.
I currently use JsonPropertyAttribute
for all properties to explicitly specify the JSON property names manually, but that's far from ideal since the transformation is trivially automatable as shown above.
Is there a way I can enforce my own JSON property naming convention while using JsonApiSerializer?
Hello,
I get an error when trying to deserialize lists of resources:
JsonApiSerializer.Exceptions.JsonApiFormatException: Expected to find json object at path ''
at JsonApiSerializer.Util.ReaderUtil+<IterateProperties>d__1.MoveNext () [0x000ad] in <114082c9b9634d14a07a89c38a135e48>:0
JsonApiSerializer.Exceptions.JsonApiFormatException: Expected to find json object at path ''
at JsonApiSerializer.Util.ReaderUtil+<IterateProperties>d__1.MoveNext () [0x000ad] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.Util.ReaderUtil.ReadAheadToIdentifyObject (JsonApiSerializer.Util.ForkableJsonReader reader) [0x000cf] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectConverter+<>c__DisplayClass3_0.<ReadJson>b__0 (JsonApiSerializer.Util.ForkableJsonReader dataReader) [0x00033] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.Util.ReaderUtil.ReadInto[TReader,TResult] (TReader reader, System.Text.RegularExpressions.Regex pathRegex, System.Func`2[T,TResult] action) [0x0000d] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x0004b] in <114082c9b9634d14a07a89c38a135e48>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) [0x00055] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at JsonApiSerializer.Util.ReaderUtil.TryPopulateProperty (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonReader value) [0x00012] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectConverter.PopulateProperties (Newtonsoft.Json.JsonSerializer serializer, System.Object obj, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract) [0x00027] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectConverter+<>c__DisplayClass3_0.<ReadJson>b__0 (JsonApiSerializer.Util.ForkableJsonReader dataReader) [0x000fb] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.Util.ReaderUtil.ReadInto[TReader,TResult] (TReader reader, System.Text.RegularExpressions.Regex pathRegex, System.Func`2[T,TResult] action) [0x0000d] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x0004b] in <114082c9b9634d14a07a89c38a135e48>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) [0x00055] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at JsonApiSerializer.JsonConverters.ResourceObjectListConverter+<>c__DisplayClass4_0.<ReadJson>b__0 (System.Object x) [0x00000] in <114082c9b9634d14a07a89c38a135e48>:0
at System.Linq.Enumerable+SelectEnumerableIterator`2[TSource,TResult].ToArray () [0x0001d] in <b5bd9d990a0b4733885e90ca5ec6c0fb>:0
at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x0001f] in <b5bd9d990a0b4733885e90ca5ec6c0fb>:0
at JsonApiSerializer.Util.ListUtil.CreateList (System.Type listType, System.Collections.Generic.IEnumerable`1[T] elements) [0x00032] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x00088] in <114082c9b9634d14a07a89c38a135e48>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) [0x00055] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at JsonApiSerializer.JsonConverters.DocumentRootConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x000d9] in <114082c9b9634d14a07a89c38a135e48>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) [0x00055] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00008] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at JsonApiSerializer.JsonConverters.DocumentRootConverter.TryResolveAsRootData (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.JsonSerializer serializer, System.Object& obj) [0x00060] in <114082c9b9634d14a07a89c38a135e48>:0
at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.ReadJson (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) [0x00015] in <114082c9b9634d14a07a89c38a135e48>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable (Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) [0x00055] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00053] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x0002d] in <c19705166c7c4a608e182e859c4de6d2>:0
at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <c19705166c7c4a608e182e859c4de6d2>:0
The minimal amount of JSON to reproduce seems to be:
{
"data": [
{
"type": "media",
"id": "42170",
"attributes": {
}
}
],
"included": [
]
}
The type I try to deserialize from that is Media[]
or List<Media>
(tried both).
JsonSerializationException.SpecificationInformation
is null
.
The JSON posted above seems valid though (and I get no error if the array is empty). Moreover, I'm pretty sure this worked before on another endpoint, unfortunately it's broken today and I don't have an hand on the API I get JSON from, so I can't diff the payloads.
Thanks for your help (and thanks for the package, that saved me a lot of time, but I'm a bit stuck here 😄).
I have following model
public class LocationDto
{
public string Id { get; set; }
public string Type => "location";
public string Name => { get; set; }
public LocationDto Region { get; set; }
}
I am trying to deserialize it from following json:
{
"data": {
"id": "1",
"type": "location",
"attributes": {
"name": "test"
},
"relationships": {
"region": {
"data": {
"type": "location",
"id": "2"
}
}
}
}
But I got error - {System.Object b__0(JsonApiSerializer.Util.ForkableJsonReader)} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo} - "Object reference not set to an instance of an object."
Problem is in deserialization region relationship. I guess it expects to find region relation attributes in include and deserialize it, becouse when region.id is same as location.id exception won't occurred . According to http://jsonapi.org/format/#crud-updating-resource-relationships json that I use is valid. Maybe I missed something?
error while trying to deserialize the following json
"{"data":[{"type":"assets","id":7,"attributes":{"asset_allocation_id":6,"asset_subtype_id":14,"code":"a18j09","name":"a18j09","active":true,"custom_asset_subtype":false,"custom_asset_allocation":false,"investment_variation":"ACV","integer_min_investment":false}}]}"
Error : Exception has occurred: CLR/JsonApiSerializer.Exceptions.JsonApiFormatException
An exception of type 'JsonApiSerializer.Exceptions.JsonApiFormatException' occurred in Newtonsoft.Json.dll but was not handled in user code: 'Expected to find json object at path '''
Model:
using System;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace App.ViewModel {
public class assets {
public int id { get; set; }
public int asset_allocation_id { get; set; }
public int asset_subtype_id { get; set; }
public string code { get; set; }
public string name { get; set; }
public bool active { get; set; }
public bool custom_asset_subtype { get; set; }
public bool custom_asset_allocation { get; set; }
public string isin { get; set; }
public string trading_name { get; set; }
public string description { get; set; }
public string investment_variation { get; set; }
public string custom_investment_variation { get; set; }
public string issuer_name { get; set; }
public byte? liquidity_days { get; set; }
public decimal? min_investment { get; set; }
public bool integer_min_investment { get; set; }
public string indexer_name { get; set; }
public asset_allocations asset_allocations { get; set; }
public asset_subtypes asset_subtypes { get; set; }
}
}
From the JSON API specification on attributes:
Attributes may contain any valid JSON value.
Complex data structures involving JSON objects and arrays are allowed as attribute values. However, any object that constitutes or is contained in an attribute MUST NOT contain a relationships or links member, as those members are reserved by this specification for future use.
For example, I'd like to be able to (de)serialize the following JSON (especially the history bit):
{
"data": {
"type": "user",
"id": 5,
"attributes": {
"name": "David",
"history": [
{ "url": "http://google.com", "time": "2015-10-01T20:12:53Z" },
{ "url": "http://apple.com", "time": "2014-10-01T20:12:53Z" },
{ "url": "http://yahoo.com", "time": "2013-10-01T20:12:53Z" }
]
}
}
}
Some documentation from ember about embedded records.
Can this be done using this serializer already, or if not, what would be needed to achieve this?
public interface ILineItem {}
public class LineItem : ILineItem
{
public string Id {get; set;}
}
public class Order
{
public string Id { get; set; }
public IEnumerable<ILineItem> Lines {get; set;}
}
serializing
new Order{
Id = "order",
Lines = new LineItem[]{
new LineItem {Id="123"}
}
}
results in the following (notice the lines element should have a data element with an array, not be an array)
{
"data": {
"type": "order",
"id": "order",
"relationships": {
"lines": [
{
"data": {
"id": "123",
"type": "lineitem"
}
}
]
}
}
}
At the moment if I want a relationship I need to do this..
public Relationship<List> Authors { get; set; }
And this gives me an author inside of the Relationships of the resource object. However, I dont know Authors until run time. I want something more like....
public Relationship<IDictionary<string, List>> Relationships { get; set; }
Now I could have anything added and all would be good. Any ideas how I could do this?
A NullReferenceException
is thrown in
JsonApiSerializer.JsonConverters.DocumentRootConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
when trying to deserialise a explicit implementation.
I have used the JsonApiDotNetCore library to build an Api to return a valid JsonApi reponse. Here is an example response from our foos endpoint:
{
"data": [
{
"attributes": {
"emailAddress": "[email protected]",
"firstName": "John"
},
"type": "foos",
"id": "1"
}
],
"links": {
"last": "http://localhost:60000/v1/foos?page[size]=10&page[number]=1"
},
"meta": {
"total-records": 1
}
}
To deserialize this I have a corresponding client side model in C#:
public class FooModel
{
[JsonProperty(propertyName: "emailAddress")]
public string EmailAddress { get; set; }
[JsonProperty(propertyName: "firstName")]
public string FirstName { get; set; }
}
Here is how we try to deserialize the json:
var result = await _httpClient.SendAsync(request);
var responseBody = await result.Content.ReadAsStringAsync();
var myFoos = JsonConvert.DeserializeObject<DocumentRoot<FooModel[]>>(responseBody, new JsonApiSerializerSettings());
But in the Data object within the myFoos
variable, both EmailAddress and FirstName are null. Some of the meta data has been populated.
Is there anything that I am doing wrong here?
Package versions:
Newtonsoft.Json: v12.0.1
JsonApiSerializer: v1.6.2
Hello Everyone!!
I am really appreciating this library. Great Job. Maybe this is not the right place to ask, but I really dont know.
I am trying to get a global configuration using .NET CORE 2 MVC API.
I can easily convert an object using this code. This is a controller and I am converting and respond using Ok(Json).
public IActionResult Get([FromRoute]string company)
{
var parts = _partService.GetAll(company);
string json = JsonConvert.SerializeObject(parts, new JsonApiSerializerSettings());
return Ok(json);
}
. It Works, but add some backslashes to the JSON due to the duplicate serialization, from the JsonConvert and then from the MVC.
"{\"data\":[{\"type\":\"partdefinitionapimodel\",\"id\":\"2026001632590498180\",\"attributes\":{\"name\":\"Tax
I Tried to look over the internet and could not find any place where I could change globally the JsonSerializerSettings with NET CORE.
I am thinking there is something related to services.AddMvc().AddJsonOption inside Startup class but I really dont know where to look or how to do it.
Thanks in advance for any help!!
Hi,
First off thanks for creating this library it works great!.
Recently came across a requirement where a resource could be of any type and we need to deserialize into concrete type based on "type" property
For example we have sample json as
"data": {
"type": "products",
"id": "123456",
"attributes": {},
"relationships": {
"content": {
"links": {
"self": "/v1/products/123456/relationships/content",
"related": "/v1/products/123456/content"
},
"data": {
"type": "contentA",
"id": "999999"
}
}
}
}
}
content.data.type could be "contentA", "contentB" and so on.
And have defined below classes to deserialize into
using System.IO;
using System.Reflection;
using JsonApiSerializer;
using JsonApiSerializer.JsonApi;
using Newtonsoft.Json;
namespace MyJsonApiSerializer
{
interface IContent
{
string Type { get; }
string Id { get; }
}
class ContentA : IContent
{
public string Type { get; } = "contentA";
public string Id { get; set; }
}
class ContentB : IContent
{
public string Type { get; } = "contentB";
public string Id { get; set; }
}
class Product
{
public string Type { get; } = "products";
public string Id { get; set; }
[JsonProperty("content")] public Relationship<IContent> Content { get; set; }
}
class Program
{
static void Main(string[] args)
{
var thisAssembly = Assembly.GetExecutingAssembly();
using (var stream = thisAssembly.GetManifestResourceStream("MyJsonApiSerializer.product.json"))
{
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd();
var product = JsonConvert.DeserializeObject<Product>(json, new JsonApiSerializerSettings());
}
}
}
}
}
What we need is to deserialize the json into Product class but Content propery should get deserialized into Relationship or Relationship as per "type". Don't think JsonApiSerializer is smart enough to infer the type and deserialize accordingly but any help on how to extend the current behavior to support this would be appreciated.
Input data for testing:
{
"data": {
"id": "2",
"type": "user",
"attributes": {
"username": "Education Designer",
"name": "Education Designer",
"email": null,
"phone_number": "+79261623199",
"address": null,
"birthday": null,
"referral_code": "kc8afc",
"last_sign_in_ip": null,
"last_sign_in_at": null,
"sign_in_count": 0
},
"relationships": {
"user_entry": {
"data": {
"id": "2",
"type": "user_entry"
}
},
"referred_user": {
"data": {
"id": "1",
"type": "referred_user"
}
}
},
"links": {
"referral_code": "https://best.url/ref/kc8afc"
}
},
"meta": {
"user_coupons": {
"active": {
"count": 0
}
}
},
"included": [
{
"id": "1",
"type": "referred_user",
"attributes": {
"username": "Marketing Agent",
"referral_code": "dcwypm"
}
},
{
"id": "2",
"type": "user_entry",
"attributes": {
"name": "BNS",
"balance": 0
}
}
]
}
I have a class with a property marked with [JsonConverter] attribute. The class has been deserialized correctly using this converter. However, starting with JsonApiSerializer 1.6.0, the converter is no longer called, rendering deserialization incorrect.
Hi,
I'm currently searching for a possibility to specify which related resources should be serialized as included
resources in an serialized result.
E.g.: We have an Article
with an one-to-one relationship to a Person
When receiving the request /articles/1?include=author
we want to return:
{
"data":{
"type": "article",
"id": "1",
"relationships": {
"author": {
"data": {
"type": "people",
"id": "99" }
}
}
},
"included": [{
"type": "people",
"id": "99",
"attributes": {
"first-name": "Patrick",
"last-name": "Gebhardt",
}
}]
}
On the other hand when receiving /articles/1
our response should look like
{
"data":{
"type": "article",
"id": "1",
"relationships": {
"author": {
"data": {
"type": "people",
"id": "9" }
}
}
}
}
From the code in ResourceObjectConverter
listed below it looks like a resource is always included if there are properties w/ data (excluding several fields).
Whats the best starting point for this problem?
Should I implement an custom ResourceObjectConverter
which is able to deal with the specific include option handling?
Thanks in advance!
First of all, thank you for this nice library! 👍 So far, implementing the server-side for an ember-data application I'm working on, has been great using this library. However I've started using model validation in combination with relationships, and now I'm running into the following issue.
Say I have a model like this (tree structure):
public class Category
{
public string Id { get; set; }
[Required]
public string Name { get; set; }
public Category Parent { get; set; }
public IEnumerable<Category> Children { get; set; }
}
And I want to update an existing record:
[Route("{id}")]
public Category Patch(string id, [FromBody]Category category)
{
category.Id = id;
if (!ModelState.IsValid)
{
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
}
// save in database & return
}
I want to be able to send the following JSON (generated by ember-data):
{
"data": {
"attributes": {
"name": "Apple TV"
},
"id": "5bb0bae631ee771950a56f27",
"relationships": {
"parent": {
"data": {
"id": "5bb0b50f31ee752168a5b2b0",
"type": "categories"
}
}
},
"type": "categories"
}
}
However, this JSON will fail ModelValidation for the relationship "parent":
{
"Message": "The request is invalid.",
"ModelState": {
"category.Parent.Name": [
"The Name field is required."
]
}
}
So my expectation is that while the "name" field is required, it shouldn't be required for referenced objects. For referenced objects, only "id" and "type" should suffice.
I've also seen this comment which might also work here. That would however require two models if I want to include full related objects for get queries and only light relationships for post/patch queries.
Property names are, by default, converted from e.g. SomePropertyName
to somePropertyName
. However, type names are converted from SomeTypeName
to sometypename
. I know the type names can be overridden using a Type
property, but I think the serializer by default should convert type names in the same way as property names. (In particular, since I use a custom NamingStrategy, see #41, I would expect the type name to be converted using the same stragety.)
Correct me if I am wrong or I am using your library wrongly. When I try to serialise my DTO object it serialise two that make sense because in web api by default it will serialise json.net. but the thing is why I cant register JsonApiSerializerSettings as formatter in wep api config, then I believe this double serialisation will prevent.
any way this is awesome project. thanks for your sharing.
Hi!
http://jsonapi.org/format/#crud-creating specifies that when creating a resource it should be possible to let the server create the ID.
Can you tell me if this scenario is supported? And if yes could you point me in the right direction, I've been trying to get this working for a few hours how.
Thanks very much.
Regards,
Chris
Imagine a simple relationship where a Foo
has a Boo
:
"data": [
{
"id": "1",
"type": "foos",
"relationships": {
"bar" : {
data: {
"type": "bars",
"id": "1"
}
}
}
}
What I'd like is to be able to deserialize Foo's "bar" relationship to the id, not to the full object.
See the comment for the Bar
property below:
class Foo
{
public int Id { get; set; }
public Bar Bar { get; set; } // instead, I would like to have this: public int BarId { get; set; }
}
class Bar
{
public int Id { get; set; }
}
How can I do this?
I encountered an unexpected behavior when deserializing an invalid json:api string(at least unexpected for me).
Below you can find a console application which illustrates the behavior.
Message
and Attachment
. The Message
contains one Attachment
.Main
method I definied an invalid json:api representation of the Message
model (see invalidJson
variable)
included
tag contains invalid data since it's not a proper resource object
for the related Attachment
.Expected behavior: An exception is thrown while deserializing the invalid json:api string.
Actual behavior: The invalid json:api string gets deserialized and even the Attachment
attributes encrypted
and size
are properly set although they are not defined in a json:api compliant way within the included
tag.
using System;
using System.ComponentModel.DataAnnotations;
using JsonApiSerializer;
using JsonApiSerializer.JsonApi;
using Newtonsoft.Json;
namespace DeserializeInvalidJsonApi
{
class Program
{
public class Message
{
[Required]
public string Id { get; set; }
[Required]
[RegularExpression("^message$")]
public string Type { get; set; }
[Required]
public Attachment Attachment { get; set; }
}
public class Attachment
{
[Required]
public string Id { get; set; }
[Required]
[RegularExpression("^attachment$")]
public string Type { get; set; }
[Required]
public bool Encrypted { get; set; }
[Required]
public int Size { get; set; }
}
static void Main(string[] args)
{
string invalidJson = @"{
""data"":{
""id"":""3e69af94-ed06-4544-bcdf-36117d351bfe"",
""type"":""message"",
""relationships"":{
""attachment"":{
""data"":{
""type"":""attachment"",
""id"":""123123124""
}
}
}
},
""included"":[
{
""type"":""attachment"",
""id"":""123123124"",
""encrypted"": false,
""size"": 12345
}
]
}";
Console.WriteLine("Start deserialization");
Message deserializedJsonApi = JsonConvert.DeserializeObject<Message>(invalidJson,
new JsonApiSerializerSettings());
Console.WriteLine(deserializedJsonApi.Attachment.Size.ToString());
Console.WriteLine(deserializedJsonApi.Attachment.Encrypted.ToString());
Console.WriteLine("Deserialization done");
}
}
}
JSON API specifies a format for so-called "error objects". While I could create such error documents myself, I would be interested to see what would be needed to support creating such documents based on ModelState validation.
An example from the JSON API site:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json
{
"jsonapi": { "version": "1.0" },
"errors": [
{
"code": "123",
"source": { "pointer": "/data/attributes/firstName" },
"title": "Value is too short",
"detail": "First name must contain at least three characters."
},
{
"code": "225",
"source": { "pointer": "/data/attributes/password" },
"title": "Passwords must contain a letter, number, and punctuation character.",
"detail": "The password provided is missing a punctuation character."
},
{
"code": "226",
"source": { "pointer": "/data/attributes/password" },
"title": "Password and password confirmation do not match."
}
]
}
For reference, the default output of ModelState looks like this:
if (!ModelState.IsValid)
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
{
"Message": "The request is invalid.",
"ModelState": {
"category.Name": [
"The field Name must be a string or array type with a minimum length of '20'."
]
}
}
I have an issue where i'm trying to serialise an object, that has a top level class with an Id property, and a list of nested classes which also have an Id property.
public class MyClass1
{
public string Id { get; set; }
public string MyTopProperty { get; set; }
public IEnumerable<MyClass2> MyClass2 { get; set; }
}
public class MyClass2
{
public string Id { get; set; }
public string MyProperty { get; set; }
}
and if i do:
var myClass = new MyClass1()
{
MyTopProperty = "hello",
MyClass2 = new List<MyClass2>()
{
}
};
var doc = new DocumentRoot<MyClass1>()
{
Data = myClass
};
var json = JsonConvert.SerializeObject(doc, new JsonApiSerializerSettings());
this will give me:
{
"data": {
"type": "myclass1",
"attributes": {
"myTopProperty": "hello"
},
"relationships": {
"myClass2": {
"data": [
]
}
}
}
}
when really i'm expecting to see:
{
"data": {
"type": "myclass1",
"attributes": {
"myTopProperty": "hello"
},
"relationships": {
"myClass2": [
]
}
}
}
this becomes an issue when i receive some json and i try deserialising it back into MyClass1
and i get an exception that says Expected to find nested object within data.attributes.myClass2 that matches \data$\
Is there a way around this?
Hi!
First off thanks for creating this library it works great!
I got a question about the implementation; Correct me if I'm wrong but from the examples I understand that, in order to use the JsonApi serialization, I need to overwrite the existing dotnet JsonInput- and JsonOutput formatters.
If I'm correct (I tested it) this means that I loose the option to do content negotiation (https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-2.0#content-negotiation).
Is this intentionally or could I do a PR to reintroduce content negotiation?
I would like to ask you if it is possible to create an option that objects with same Id don't have the same reference.
For instance in my code I have a situation like this (approximately)
[DataContract]
public class Earth
{
[DataMember(Name = "id")]
public int Id {get;set;}
[DataMember(Name = "countries")]
public Country[] Countries {get;set;}
}
[DataContract]
public class Country
{
[DataMember(Name = "id")]
public int Id {get;set;}
[DataMember(Name = "people")]
public Person[] People {get;set;}
}
[DataContract]
public class Person
{
[DataMember(Name = "Name")]
public string Name {get;set;}
// this doesn't exist in the api
public Country Country {get;set;}
}
In this example I have list of countries in Earth. And in those countries i have a list of people.
But people can live in multiple countries. As the deserializer cannot fill a country for each person (I would like a back link as well) I have to do something like this
foreach c in country
foreach p in c.people
p.country= c
to get a back link.
But the problem is that the deserializer actually creates the same person in multiple countries as the id is the same by reference. Then I cannot have them have a different country in the model (if i change country for one object I will change it for another as well).
my question is - can you create an option that objects which are same by id don't created the same by reference (but only by content)?
thanks in advance,
Ivan
The JSON API standard for resource with parent relationship is as follows:
{
"data": {
"type": "photos",
"attributes": {
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
},
"relationships": {
"photographer": {
"data": { "type": "people", "id": "9" }
}
}
}
}
(http://jsonapi.org/format/#crud-creating)
Let's assume we have the following model in our code:
public class Photo {
public int Id { get; set; }
public int PeopleId { get; set; }
public string Title { get; set; }
public string Src { get; set; }
public People People { get; set; }
}
PeopleId
is a EF specific way of creating the relationship easier. Right now the api will crash because EF is not able to save the data since the only field set on the People relationship is the Id. A workaround in the controller is:
photo.peopleId = photo.People.Id;
photo.people = null;
Is there a way we could get this work done automatically?
Serializing the following:
new DocumentRoot<IEnumerable<Service>>
{
Data = records
};
will produce wrong JSON output if records
is an IEnumerable<Service>
result from an Select(...)
method call:
{
"data": [
{
"type": "Service",
"id": "ff3e06c0-7bdc-9846-bd33-42421f8b289f",
"attributes": {
"name": "Service 1",
"date": "2017-01-01T00:00:00",
"favorite": true
}
}
],
"included": [
{
"type": "Service",
"id": "ff3e06c0-7bdc-9846-bd33-42421f8b289f",
"attributes": {
"name": "Service 1",
"date": "2017-01-01T00:00:00",
"favorite": true
}
}
]
}
Note the unnecessary included
property.
The serialization works well if I convert records
to a List<Service>
:
new DocumentRoot<IEnumerable<Service>>
{
Data = records.ToList()
};
With .Net Core and a default formatter set as shown in #35, I am getting the included resources only on the first request. Additional requests to the same endpoint do not have the included resources in the returned json. I am eagerly loading the related entities and they do indeed appear in the query response before serialization every time. Is this expected behavior? Do I have something misconfigured?
Thanks!
Hello,
I'm getting a json where the data.id is integer, by what I see in the ReaderUtil.ReadAheadToIdentifyObject class it is mandatory that it be string. Is there any way to change this behavior?
The JsonApiSerializerSettings
class sets its own ContractResolver, JsonApiContractResolver
, so it's not possible to do this:
var jsonSettings = new JsonApiSerializerSettings(resourceConverter) {
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new DefaultContractResolver {
NamingStrategy = new SnakeCaseNamingStrategy()
}
};
The JsonApiContractResolver
forces the use of CamelCaseNamingStrategy
.
I can override property names with [JsonProperty("snake_name")]
to workaround, but it would be cool to be able to pass down another naming strategy :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.