simple-odata-client / Simple.OData.Client

MIT License
331 stars 197 forks source link

Serialization Error Uploading DateTime->DateTimeOffset #546

Open NetTecture opened 6 years ago

NetTecture commented 6 years ago

Sadly I need to have DateTime defined in my model classes as on the backend I otherwise run into serious issues projecting.

A property defined as

DateTime{}

serializes nicely down into Simple.Odata.Client, but fails upward with an exception:

System.NotSupportedException: 'Conversion is not supported from type System.DateTime to OData type [Edm.DateTimeOffset Nullable=False Precision=0]'

Trace

at Simple.OData.Client.V4.Adapter.RequestWriter.GetPropertyValue(IEdmTypeReference propertyType, Object value, ODataResource root) at Simple.OData.Client.V4.Adapter.RequestWriter.<>c__DisplayClass21_0.b__6(KeyValuePair2 x) at System.Linq.Enumerable.WhereSelectEnumerableIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Simple.OData.Client.V4.Adapter.RequestWriter.CreateODataEntry(String typeName, IDictionary2 properties, ODataResource root) at Simple.OData.Client.V4.Adapter.RequestWriter.WriteEntryContentAsync(String method, String collection, String commandText, IDictionary2 entryData, Boolean resultRequired) at Simple.OData.Client.RequestWriterBase.CreateInsertRequestAsync(String collection, String commandText, IDictionary2 entryData, Boolean resultRequired) at Simple.OData.Client.RequestBuilder.InsertRequestAsync(Boolean resultRequired, CancellationToken cancellationToken) at Simple.OData.Client.ODataClient.InsertEntryAsync(FluentCommand command, Boolean resultRequired, CancellationToken cancellationToken) at Simple.OData.Client.BoundClient`1.InsertEntryAsync(Boolean resultRequired, CancellationToken cancellationToken)

NetTecture commented 6 years ago

@object Missing write permissions and no idea how to add this to a unit test, so here is my workaround:

RequestWriter.cs, please add

                else if ((targetType == typeof(DateTimeOffset) || targetType == typeof(DateTimeOffset?)) && value is DateTime dt2)
                {
                    result = new DateTimeOffset(dt2);
                    return true;
                }

to TryConvert, lines 523 after the }

Basically another convert. I am not sure that i like the IF there - the more you get, it may make sense to turn around and use switch and new syntax. And I miss unit test (sorry, how to write?) and I definitely miss possible edge cases, but this is better than what we have so far (which is an exception).

object commented 6 years ago

Thanks for the repro. I am extremely busy with other projects, but I see what I can do.

NetTecture commented 5 years ago

@object Is there a way to submit a patch? Do I have o fork the repository and then submit a pull request? Because I can not push a separate branch, so I can not try to fix it and then push and make a pull request. Never submitted bugs to Github, so bear with me or offload me to a site with explanations ;)

phatcher commented 5 years ago

@NetTecture Yes, basically make a fork and then typically take a feature branch from the v5 branch as that's the current development branch

object commented 5 years ago

@NetTecture sending pull request is a standard way of submitting patches. Will appreciate a PR from you.

glconti commented 2 years ago

@NetTecture @object

Tested with version 5.26.0

I had the same issue in my code and I would like to point out that if the DateTime values are expressed in UTC (DateTime.Kind == DateTimeKind.Utc) the conversion works perfectly, so for me this can be overcome very easily. I even prefer this behavior that forces me to use UTC dates.

Probably I would still have a better error message maybe, so people won't be frustrated.