cosullivan / hypermedia Goto Github PK
View Code? Open in Web Editor NEWHypermedia library for .NET
Home Page: http://cainosullivan.com/Hypermedia
License: MIT License
Hypermedia library for .NET
Home Page: http://cainosullivan.com/Hypermedia
License: MIT License
Hello,
we wanted to use you client library with our JSON API server implementation and recognized an issue regarding the JSON API conformity.
Using the URL http://hypermedia.cainosullivan.com/v1/posts/1?$prettify=true&$format=jsonapi, the response starts with:
{
"jsonapi":{
"version":"1.0"
},
"data":{
"type":"posts",
"id":1,
...
}
Your server implementation returns a number as "data.id". The JSON API specifies that both "data.type" and "data.id" must be strings:
Identification
Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings.
Regards
Jochen
The .NET Standard is fairly outdated now.
Given that the Core, Standard and Framework are now unified, I think it makes sense to upgrade to .NET 6.
This also gives us access to the System.Text.Json
lib which might prove useful
Link inside Samples section in Readme.md file all broken. Could you fix links?
View the Hypermedia.Sample.WebApi project for an example of how to use the Hypermedia library. The sample API is running live at http://hypermedia.cainosullivan.com/ and has the following endpoints;
http://hypermedia.cainosullivan.com/v1/users?$format=jsonapi
http://hypermedia.cainosullivan.com/v1/posts?$format=jsonapi
http://hypermedia.cainosullivan.com/v1/comments?$format=jsonapi
Try it out now.
http://hypermedia.cainosullivan.com/v1/posts/1?$prettify=true&$format=jsonapi
This segment in PrimitiveConverter
:
if (type == typeof(double))
{
return (double)((JsonNumber)jsonValue).Value;
}
Seems to throw this exception for 26.8428
:
Cannot convert type 'JsonLite.Ast.JsonNumber' to 'double'
"related" link is done automatically when using the fluent. But how do I add other links to links section / links object such like "self","up" using the fluent?
Hi, I have problems formatting attribute names in .NET Core 2.2 using Hypermedia. Below is an example of the result of a formatted object:
{ "data":{ "type":"products", "id":"1", "attributes":{ "Name":"ProductA", "Price":10, "Description":"descripcion 1", "OwnerName": "OwnerA" } } }
As you see we have the attribute names with Capital letter ("Name" instead of "name").
Composite words are not dashed and also start with Capital letter ("OwnerName" instead of "owner-name").
I'm missing something?
Thanks in advance.
Versions:
.NET Core 2.2
Hypermedia 1.1.0
Hypermedia.JsonApi.AspNetCore 1.3.6
Create unit tests
Would be great if support for serializing errors (http://jsonapi.org/format/#error-objects) was available.
Unless they are already implemented and I'm overlooking them.
The test suite should be run before a PR can be merged.
CodeQL should also be run to check for greivous errors.
Hello
i use hypermedia in Xamarin form and i am looking for a sample for using PostAsync method but i couldn't find it in your sample project .is it possible to give me an example for using PostAsync method for sending data to server.
As it stands, we get an error when we attempt to use a record
object in our map.
"EqualityContract" property not found on type
Hello
I need to do a PATCH request with the Hypermedia , but i don't know how , is it possible to give me an example for sending PATCH request with hypermedia client
Based on usage of the FieldOptions enum (e.g. in default resolver creator), it seems like IField.Is should return true if options == None, but it does not. Either need to add a check for None or make None 0xff instead of 0.
Personally, I think it's time to leave the .NET Framework behind.
This project doesn't use anything like WinForms or WPF, so there are no issues there.
However, some of the sample projects are .NET Framework, as is the WebApi package. Which is why #32 failed rather spectacularly and I had to reset the whole thing (I had the Windows Specific Projects hidden and forgot - whoops...).
The benefits of the upgrade to .NET 6 include:
System.Text.Json
My suggested course of action would be:
Hypermedia.Sample.WebApi
Hypermedia.WebApi
Hypermedia.JsonApi.WebApi
System.Text.Json
everywhere but I'd recommend waiting for #42 to be completed first or there will be a nightmare regression testing it.This one, again, might be a bit niche or might not be wanted. However, I often find I want to deserialise a string to an enum using a custom value through an attribute, like:
[EnumMember(Value = "Pld Frag Deb")]
PayloadFragmentationDebris,
As it stands, the simple Enum.Parse()
used in EnumConverter
doesn't (AFAICT) support this
Say I have a data structure where there might be multiple levels of links.
It would be good to be able to fetch these links recursively or to a certain depth (to prevent loops)
Hello
I use Hypermedia.Jsonapi.client ( 2.1.1 ) package in my project in Xamarin Form . i receive an error when i try to update package to 2.4.3 . this is the error
Attempting to gather dependency information for multiple packages with respect to project 'Planbox', targeting '.NETPortable,Version=v4.5,Profile=Profile111'
GET http://nuget.uxdivers.com/grial/FindPackagesById()?id='Hypermedia.JsonApi.Client'&semVerLevel=2.0.0
GET https://api.nuget.org/v3/registration3-gz-semver2/hypermedia.jsonapi.client/index.json
OK http://nuget.uxdivers.com/grial/FindPackagesById()?id='Hypermedia.JsonApi.Client'&semVerLevel=2.0.0 97ms
OK https://api.nuget.org/v3/registration3-gz-semver2/hypermedia.jsonapi.client/index.json 386ms
Total number of results gathered : 16
Gathering dependency information took 875.43 ms
Summary of time taken to gather dependencies per source :
http://nuget.uxdivers.com/grial - 102.25 ms
https://api.nuget.org/v3/index.json - 398.63 ms
Attempting to resolve dependencies for multiple packages.
Resolving dependency information took 0 ms
Resolving actions install multiple packages
Retrieving package 'Hypermedia.JsonApi.Client 2.4.3' from 'nuget.org'.
Removed package 'Hypermedia.JsonApi.Client 2.1.1' from 'packages.config'
Added file 'packages.config' to project 'Planbox'.
Removed reference 'Hypermedia' from project 'Planbox'.
Removed reference 'Hypermedia.JsonApi.Client' from project 'Planbox'.
Removed reference 'Hypermedia.JsonApi' from project 'Planbox'.
Removed reference 'JsonLite' from project 'Planbox'.
Successfully uninstalled 'Hypermedia.JsonApi.Client 2.1.1' from Planbox
For adding package 'Hypermedia.JsonApi.Client.2.4.3' to project 'Planbox' that targets 'portable45-net45+win8+wpa81'.
Install failed. Rolling back...
Package 'Hypermedia.JsonApi.Client 2.4.3' does not exist in project 'Planbox'
For adding package 'Hypermedia.JsonApi.Client 2.1.1' to project 'Planbox' that targets 'portable45-net45+win8+wpa81'.
For adding package 'Hypermedia.JsonApi.Client 2.1.1' to project 'Planbox' that targets 'portable45-net45+win8+wpa81'.
Package 'Hypermedia.JsonApi.Client 2.1.1' already exists in folder '/Users/afshinhaftlangi/mobile/Planbox/packages'
Added reference 'Hypermedia' to project 'Planbox'.
Added reference 'Hypermedia.JsonApi.Client' to project 'Planbox'.
Added reference 'Hypermedia.JsonApi' to project 'Planbox'.
Added reference 'JsonLite' to project 'Planbox'.
Added package 'Hypermedia.JsonApi.Client 2.1.1' to 'packages.config'
Added file 'packages.config' to project 'Planbox'.
Package 'Hypermedia.JsonApi.Client 2.4.3' does not exist in folder '/Users/afshinhaftlangi/mobile/Planbox/packages'
Executing nuget actions took 13.3 sec
Could not install package 'Hypermedia.JsonApi.Client 2.4.3'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile111', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
I'm attempting to use this library but there seems to be a lack of information in the docs that's making this difficult.
For instance, it's not clear to me whether .BackingField()
is required or not. It's also not clear when we have to use the various relationship building methods.
The best guess I can make from the quick-start is that .With()
is used for each type
your API can return and then you use BelongsTo()
or HasMany()
for any relationships that get returned for that object. However, that then raises the question of what we do when there's a single has relationship (there's no .Has()
) or when an object might belong to many other objects.
This has currently led to me having developed quite a complicated model for the ESA's discosWeb API but I'm unable to get it to work. I get this error:
System.ArgumentException: "EqualityContract" property not found on type "DISCOSweb_Sdk.Models.ResponseModels.DiscosObjects.DiscosObject".
System.ArgumentException
"EqualityContract" property not found on type "DISCOSweb_Sdk.Models.ResponseModels.DiscosObjects.DiscosObject".
Check your contract resolver configuration. (Parameter 'field')
at Hypermedia.Metadata.Runtime.RuntimeFieldAccessor.From[T](String field)
at Hypermedia.Configuration.FieldBuilder`1..ctor(IContractBuilder`1 builder, RuntimeField field)
at Hypermedia.Configuration.ContractBuilder`1.Field(String name)
at Hypermedia.Configuration.ReflectionTypeDiscovery.Discover[TEntity](ContractBuilder`1 builder, TypeInfo type)
at Hypermedia.Configuration.ReflectionTypeDiscovery.Discover[TEntity](IBuilder parent)
at Hypermedia.Configuration.Builder.With[TEntity](ITypeDiscovery discovery)
at Hypermedia.Configuration.BuilderExtensions.With[TEntity](IBuilder builder, String name)
at DISCOSweb_Sdk.Mapping.JsonApi.DiscosObjects.DiscosObjectContractBuilder.WithDiscosObject(IBuilder builder) in /home/james/repos/DISOSweb-sdk/src/DISCOSweb-Sdk/DISCOSweb-Sdk/Mapping/JsonApi/DiscosObjects/DiscosObjectContractBuilder.cs:line 21
at DISCOSweb_Sdk.Mapping.JsonApi.DiscosObjectResolver.CreateResolver() in /home/james/repos/DISOSweb-sdk/src/DISCOSweb-Sdk/DISCOSweb-Sdk/Mapping/JsonApi/DiscosObjectResolver.cs:line 22
at DISCOSweb_Sdk.Tests.Client.ClientTests.CanFetchADiscosObject() in /home/james/repos/DISOSweb-sdk/src/DISCOSweb-Sdk/DISCOSweb-Sdk.Tests/Client/ClientTests.cs:line 20
at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext() in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\Runners\TestInvoker.cs:line 264
--- End of stack trace from previous location ---
at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\ExecutionTimer.cs:line 48
at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in C:\Dev\xunit\xunit\src\xunit.core\Sdk\ExceptionAggregator.cs:line 90
But because of the lack of docs, I'm not even sure where to start. If you'd take a look at this PR and point me in the right direction, I'd really appreciate it.
If someone would be so kind as to explain this to me in a bit of detail, I'm more than happy to prepare additional docs and to contribute them with a PR.
I tried the formatter with non-Latin characters and it serialize it as '????'
There is an example for deserializing received content, but none for serializing content that I want to post to my backend.
I have been using NewtonSoft for regular JSON. Its JsonSerializerSettings can take a resolver as an argument. Maybe you can make it so, that your resolver can be plugged in.
sample.
API doc
Create a suite of functional tests
When Hypermedia attempts to deserialize a relationship with an empty to-one relationship (ie "relationships": { "person": {ย "data": null } }
), it crashes in DeserializeRelationships
on this line because data
is being cast to JsonObject
when it is JsonNull
.
Will need to create a suite of integration tests.
This will require a mock server that conforms to the JSON API standard.
There's an error in EnumerableConverter.DeserializeArray. Looks to be made by the latest change. You're changing the type to ICollection<>, then trying to create an instance of it using Activator, but Activator can't create instances of interfaces. Here's my fix for it.
@EnumerableConverter.TryGetCollectionType
- if (TypeHelper.TryGetCollectionType(type, out collectionType))
+ Type tmpCollectionType;
+ if (TypeHelper.TryGetCollectionType(type, out tmpCollectionType))
I also added support for arrays:
public object DeserializeValue(IJsonSerializer serializer, Type type, JsonValue jsonValue)
{
if (type.IsArray)
return DeserializeArray(serializer, type, (JsonArray)jsonValue);
else
return DeserializeCollection(serializer, type, (JsonArray)jsonValue);
}
static ICollection DeserializeArray(IJsonSerializer serializer, Type type, JsonArray jsonArray)
{
Type elementType = type.GetElementType();
var array = Array.CreateInstance(elementType, jsonArray.Count);
int index = 0;
foreach (var jsonValue in jsonArray)
{
var value = serializer.DeserializeValue(elementType, jsonValue);
array.SetValue(value, index);
index++;
}
return array;
}
static ICollection DeserializeCollection(IJsonSerializer serializer, Type type, JsonArray jsonArray)
{
// TODO: the collection access should be converted to a dynamically compiled delegate
Type elementType;
MethodInfo method;
if (TryGetCollectionType(type, out type, out elementType, out method) == false)
{
throw new JsonException("Can not deserialize a JSON array to a type that doesnt support ICollection<T>.");
}
var collection = Activator.CreateInstance(type) as ICollection;
foreach (var jsonValue in jsonArray)
{
var value = serializer.DeserializeValue(elementType, jsonValue);
method.Invoke(collection, new[] { value });
}
return collection;
}
Might be a bit of a niche issue but Hypermedia.Json.Converters.PrimitiveConterter.DeserializeValue
falls over for the following case:
type: System.String
jsonValue: decimal 90503
Given that JsonValue
already comes with a .Stringify()
method, it seems to make sense to me to use that instead.
The API I'm working with has Latitude
and Longitude
fields encoded as strings. Ideally, I want these on my models as doubles.
So far, the best I've been able to come up with is to do:
//...
.Field(nameof(LaunchSite.Latitude)).Deserialization().Rename(nameof(LaunchSite.LatitudeAsString))
.Field(nameof(LaunchSite.Longitude)).Deserialization().Rename(nameof(LaunchSite.LongitudeAsString));
and then have this on my class:
internal string LongitudeAsString
{
init => Longitude = double.Parse(value);
}
internal string LatitudeAsString
{
init => Latitude = double.Parse(value);
}
This did require a slight change to the RuntimeFieldAccessor
to use Type.GetRuntimeProperties().Single(...)
rather than Type.GetRuntimeProperty(name)
to let it see the internal
properties but this still doesn't quite seem to work. I end up with doubled-up field names in JsonApiSerializer.DeserializeFields()
.
So I've had to result to adding internal string properties called Latitude
and Longitude
and then having public, expression bodied properties called LatitudeDegs
and LongitudeDegs
that both parse their relevant string fields but this feels like a bodge on a bodge at this point and I'd prefer a cleaner solution.
I think adding something that would allow us to go .Deserialize().Custom<TIn, TOut>(func<TIn, TOut> deserializeFunc)
would be nice.
Any thoughts on this or ideas for a workaround to my issue?
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.