Reputation: 2205
I am making a prototype project of NodaTime compared to BCL's DateTime, but executing this result gives me recursionLimit exceeded error.
This is the function I am using to JSONify my viewmodel. The error happens after this function returns.
[HttpPost]
public JsonResult GetDates(int numOfDatesToRetrieve)
{
List<DateTimeModel> dateTimeModelList = BuildDateTimeModelList(numOfDatesToRetrieve);
JsonResult result = Json(dateTimeModelList, JsonRequestBehavior.AllowGet);
return result;
}
My view model is built properly when I inspected it. Here is the code for my view model.
public class DateTimeModel
{
public int ID;
public LocalDateTime NodaLocalDateTimeUTC;
public LocalDateTime NodaLocalDateTime
{
get
{
DateTimeZone dateTimeZone = DateTimeZoneProviders.Bcl.GetZoneOrNull(BCLTimezoneID);
//ZonedDateTime zonedDateTime = NodaLocalDateTimeUTC.InUtc().WithZone(dateTimeZone);
OffsetDateTime offsetDateTime = new OffsetDateTime(NodaLocalDateTimeUTC, Offset.Zero);
ZonedDateTime zonedDateTime = new ZonedDateTime(offsetDateTime.ToInstant(), dateTimeZone);
return zonedDateTime.LocalDateTime;
}
}
public OffsetDateTime NodaOffsetDateTime;
public DateTime BclDateTimeUTC;
public DateTime BclLocalDateTime
{
get
{
DateTime utcDateTime = DateTime.SpecifyKind(BclDateTimeUTC, DateTimeKind.Utc);
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(BCLTimezoneID);
DateTime result = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
return result;
}
}
public DateTimeOffset BclDateTimeOffset;
//public int Offset;
public string OriginalDateString;
public string BCLTimezoneID;
}
I am sure that the NodaTime objects are not serializing correctly because when I comment the code from the viewModel the JsonResult is able to execute.
I read this off this page NodaTime API Reference
Code in this namespace is not currently included in Noda Time NuGet packages; it is still deemed "experimental". To use these serializers, please download and build the Noda Time source code from the project home page.
So I downloaded and built the source code and replaced the dll's my project references but I don't know how to implement the JsonSerialization classes.
Can someone explain to me how to use NodaTime.Serialization.JsonNet classes to make my NodaTime objects serializable?
Upvotes: 6
Views: 7505
Reputation: 21135
Serialization is supported for JSON.NET in Noda Time 2.0+.
You'll need to install the package with NuGet:
> Install-Package NodaTime.Serialization.JsonNet
And then configure your serializer settings to use it. This won't work with the default serializer/deserializer - you need to configure one explicitly.
We chose to use one statically. Your usage may be different. Here is an example:
using Newtonsoft.Json;
using NodaTime;
using NodaTime.Serialization.JsonNet; // << Needed for the extension method to appear!
using System;
namespace MyProject
{
public class MyClass
{
private static readonly JsonSerializerSettings _JsonSettings;
static MyClass()
{
_JsonSettings = new JsonSerializerSettings
{
// To be honest, I am not sure these are needed for NodaTime,
// but they are useful for `DateTime` objects in other cases.
// Be careful copy/pasting these.
DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
};
// Enable NodaTime serialization
// See: https://nodatime.org/2.2.x/userguide/serialization
_JsonSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
}
// The rest of your code...
}
}
Upvotes: 3
Reputation: 1502076
We don't currently have any support for JavaScriptSerializer
: I suspect you'll have to use Json.NET for all your JSON serialization. The user guide page on serialization gives a little bit more information, but it does mostly assume you already know about Json.NET.
The good news is that Json.NET is pretty easy to use - you may well find it's as simple as:
var settings = new JsonSerializerSettings();
settings.ConfigureForNodaTime();
string json = JsonConvert.SerializeObject(model, settings);
(Or use JsonSerializer
.)
As an aside, the way you're using the Noda Time types is a little odd to say the least - it may well be worth asking another question with details of what you're trying to achieve, and we can work out a more idiomatic way of doing it :)
Upvotes: 12