GithubHelp home page GithubHelp logo

cosullivan / hypermedia Goto Github PK

View Code? Open in Web Editor NEW
47.0 3.0 12.0 1.95 MB

Hypermedia library for .NET

Home Page: http://cainosullivan.com/Hypermedia

License: MIT License

C# 98.00% Batchfile 0.03% JavaScript 1.03% HTML 0.36% Handlebars 0.26% Less 0.32%

hypermedia's Issues

Can't Cast `JsonNumber` to `Double`

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'

Unicode support

I tried the formatter with non-Latin characters and it serialize it as '????'

JSON API conformity

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

Setup CD

Whenever we merge to master we want to be building and publishing new versions of the package to nuget.

Ideally, this should use conventional commit messages to semver the package.

We don't want to be doing this before #43 #44 and #45 are all entirely resolved though.

Decimal to String conversion fails

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.

IField.Is bug?

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.

.NET 6 Upgrade and Killing of .NET Framework Support

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:

  • True cross-platform support
  • Access to System.Text.Json
  • Will make #53 and #54 a lot easier if we don't have any Windows projects.

My suggested course of action would be:

  • Update readme to indicate that the current version is the last which will support .NET Framework and do a major version number bump.
  • Delete Hypermedia.Sample.WebApi
  • Delete Hypermedia.WebApi
  • Delete Hypermedia.JsonApi.WebApi
  • Upgrade all .NET Standard 1.4 Libs to .NET 6
  • Hypermedia.AspnetCore will probably need a rewrite the API has changed so much
  • Refactor these projects to be more canonically .NET 6-like... Things like adding file-scoped namespeaces.
  • Look into replacing Newtonsoft with System.Text.Json everywhere but I'd recommend waiting for #42 to be completed first or there will be a nightmare regression testing it.

Example for PostAsync

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.

Upgrade to .NET 6

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

C#9 Record Support

As it stands, we get an error when we attempt to use a record object in our map.

"EqualityContract" property not found on type

Fetching Recursively

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)

Support `JsonPropertyNameAttribute` on Enum Deserialization

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

Custom Recasting During Deserialization

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?

Example for serializing client POST content

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

Problem with update Hypermedia.Jsonapi.client

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.

Integration Tests

Will need to create a suite of integration tests.

This will require a mock server that conforms to the JSON API standard.

Debugging Difficulties and Documentation Improvements

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.

Can't deserialize collections

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;
        }

PATCH request with the Hypermedia

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

Hypermedia.JsonApi.AspNetCore is not formatting class attributes for .NET Core 2.2

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

Setup CI

The test suite should be run before a PR can be merged.

CodeQL should also be run to check for greivous errors.

Sample links are all broken

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

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.