Custom JSON converter for Noda Time - c#

I'm developing for .NET Core, so I'm using the unstable latest alpha of Noda Time (2.0.0-alpha20160729). Data is being handled with JSON.
I will be accepting user input for a date of birth field, and I want to support multiple input formats in case the user can't follow directions gets confused. For example, I want to accept both MM-dd-yyyy and M/d/yy, among others.
The serialization docs specifically state the following:
Custom converters can be created easily from patterns using NodaPatternConverter.
I cannot for the life of me figure out how to do this though. From what I understand, I will need to implement both NodaPatternConverter<LocalDate> itself, IPattern<LocalDate> for parsing, and Action<T> for validation.
I started writing IPattern.Parse<LocalDate>, but that function returns ParseResult<LocalDate> which is apparently inaccessible. It cannot be instantiated or used in any way that I have found. I'm therefore stuck.
How do I properly create a custom JSON converter for Noda Time?

Firstly, this doesn't sound like the right thing to do in a JSON converter. If you're accepting user input directly in your JSON, that should be treated as a string, and parsed later, IMO. JSON is a machine-to-machine format, not a human-to-machine format. Assuming this is a web app, you might want to use moment.js to parse the data at the client and reformat it as ISO-8601. Alternatively, deserialize it as a string and then convert it in your server-side code.
Anyway, for a JSON converter you only need to implement IPattern<LocalDate> - you don't need to implement NodaPatternConverter<LocalDate> as that already exists. You just need:
var pattern = ...;
var converter = new NodaPatternConverter<LocalDate>(pattern);
Now, to implement your pattern, you probably want to actually create it out of existing patterns - write an implementation which delegates to one IPattern<LocalDate> after another until the result is a ParseResult<T> which is successful - or return the final unsuccessful ParseResult<T>. Note that ParseResult<T> isn't inaccessible - but you can't (currently) create your own instance of it. That's something I should probably address, but in this case you don't really need to.
The code you need already exists but isn't exposed - you want the Parse part of CompositePattern. To implement the Format part, you could just use the first of your patterns to format the value... if you even need to.

Related

Perform conversions on all datetimes on get/set?

I have a database first ASP.NET MVC (C#) project with EF6, which uses a lot of DateTime objects.
They are stored in the database as my local Time-Zone(TZ), however some users are in different TZs (also stored in the database) and I would like to present them with DateTimes for their own TZ.
I have set up some functions accessible from all relevant controllers to do the conversions, but I'm hoping there is a quicker way to apply them in all cases than finding and explicitly converting each instance of each DateTime where needed to display on every view and converting them back again after form POSTs.
On loading a view, the TZ needs to be converted to the User's TZ.
On saving a form, any DateTimes in the form need to be converted back again.
The functions which perform the conversions first check whether it is required according to the User's recorded TZ.
Is there some way I can put all DateTime objects through the conversion when getting and setting them, or something along those lines?
This largely depends on how you access your database. Let's take the Entity Framework example
There, you have the Value Converters
Value converters allow property values to be converted when reading from or writing to the database. This conversion can be from one value to another of the same type (for example, encrypting strings) or from a value of one type to a value of another type (for example, converting enum values to and from strings in the database.)
So in this example, you would create your own DBContext with the TZ in the constructor and pass it to the converter
var converter = new LocalToTZConverter<DateTime>(timezone);
modelBuilder
.Entity<DateEnabled>()
.Property(e => e.Created)
.HasConversion(converter);
Assuming that you use some kind of ORM, pretty much everyone has it's own conversion. If this is something you implement yourself, then you'd handle it in your repositories and have it as a coding practice to never access data directly (only though the repos).

Displaying a formatted 'DateTime' in a WPF 'TextBlock'

In my WPF application, I have a static List<Guest>. Guest has properties like Name, Lastname, Birthday, etc.
My question concerns Birthday. I would like to display Birthday, which is of type DateTime, in a TextBlock. The output format that I want is something like DD/MM/YYYY. I've thought of using a parsing approach like this:
DateTime.ParseExact(s, "yyyyMMdd").ToLocalTime()
Is there a better way to go that avoids this kind of parsing? For instance, does C# have a converter for DateTime? Note that I need to do this conversion only for output.
The painful way is to make it manually with formatting and parsing. The elegant way is to bind your form to an object containing your properties. When using object-data binding you can specify formats. The conversions in both ways are carried out automatically.
Besides the advantage of having an automatic conversion to and from strings, you have the advantage that you can separate the business logic from your form. You can apply any logic to a property called guest.DateOfBirth (or just DateOfBirth if the logic is inside the Guest class), for instance, instead of applying it to a construct like DateTime.Parse(textBox13.Text), which makes it a lot easier to understand and maintain the code.
See:
Data Binding for Windows Forms (on developerfusion)
Data binding concepts in .NET windows forms (on CodeProject)

Deserializing JSON object to runtime type in WinRT (C#)

I have a small WinRT client app to my online service (Azure Web Service). The server sends a JSON encoded object with (with potential additional metadata) to the client and the client's responsibility would be to deserialize this data properly into classes and forward it to appropriate handlers.
Currently, the objects received can be deserialized with a simple
TodoItem todo = JsonConvert.DeserializeObject<TodoItem>(message.Content);
However, there can be multiple types of items received. So what I am currently thinking is this:
I include the type info in the header serverside, such as "Content-Object: TodoItem"
I define attributes to TodoItem on the client side (see below)
Upon receiving a message from the server, I find the class using the attribute I defined.
I call the deserialization method with the resolved type
(Example of the attribute mentioned in 2.)
[BackendObjectType="TodoItem"]
public class TodoItem
My problem with this approach however is the Type to Generics in the deserialization as I can't call:
Type t = ResolveType(message);
JsonConvert.DeserializeObject<t>(message.Content);
I tried finding some solutions to this and getting method info for the DeserializeObject and calling it using reflection seemed to be the way to go. However, GetMethod() does not exist in WinRT and I was not able to find an alternative I could use to retrieve the generic version of the DeserializeObject (as fetching by the name gives me the non-generic overload). I don't mind using reflection and GetMethod as I can cache (?) the methods and call them every time a message is received without having to resolve it every time.
So how do I achieve the latter part and/or is there another way to approach this?
Alright, I feel like this was not really a problem at all to begin with as I discovered the DeserializeObject(string, Type, JsonSerializerSettings) overload for the method. It works splendidly. However, I would still like to hear some feedback on the approach. Do you think using attributes as a way to resolve the type names is reasonable or are there better ways? I don't want to use the class names directly though, because I don't want to risk any sort of man-in-the-middle things be able to initialize whatever.
Just a few minutes ago we have posted the alternative way to do what you want. Please look here, if you will have any questions feel free to ask:
Prblem in Deserialization of JSON
Try this
http://json2csharp.com/
Put your Json string here it will generate a class
then
public static T DeserializeFromJson<T>(string json)
{
T deserializedProduct = JsonConvert.DeserializeObject<T>(json);
return deserializedProduct;
}
var container = DeserializeFromJson<ClassName>(JsonString);

Building a string representation of an object using a "mask" or user supplied Format String

I'm not really sure what tags should be on this sort of question so feel free to give me some suggestions if you think some others are more suited.
I have a dynamic object with an unknown number or properties on it, it's from a sort of dynamic self describing data model that lets the user build the data model at runtime. However because all of the fields holding relevant information to the user are in dynamic properties, it's difficult to determine what should be the human readable identifier, so it's left up to the administrator. (Don't think it matters but this is an ASP.NET MVC3 Application). To help during debugging I had started decorating some classes with DebuggerDisplayAttribute to make it easier to debug. This allow me to do things like
[DebuggerDisplay(#"\{Description = {Description}}")]
public class Group
to get a better picture of what a specific instance of an object is. And this sort of setup would be perfect but I can't seem to find the implementation of this flexibility. This is especially useful on my dynamic objects because the string value of the DebuggerDisplayAttribute is resolved by the .NET framework and I have implementations of TryGetMember on my base object class to handle the dynamic aspect. But this only makes it easier for development. So I've added a field on what part of my object is still strongly typed and called it Title, and I'd like to let the administer set the implementation using their own format, so to speak. So for example they might build out a very simplistic rental tracking system to show rentals and they might specify a format string along the lines of
"{MovieTitle} (Due: {DueDate})"
I would like that when they save the record to add some logic to first update the Title property by resolving the format string to substitute each place holder with the value of the appropriate property on the dynamic object. So this might resolve to a title of
"Inception (Due: May 21, 2011)", or a more realistic scenario of a format string of
"{LastName}, {FirstName}"
I don't want the user to have to update the title of a record when they change the first name field or the last name field. I fully realize this will likely use reflection but I'm hoping some one out there can give me some pointers or even a working example to handle complex format strings that could be a mix if literal text and placeholders.
I've not had much luck looking for an implementation on the net that will do what I want since I'm not really sure what keywords would give me the most relevant search results?
You need two things:
1) A syntax for formatting strings
You have already described a syntax where variables are surrounded by bracers, and if you want to use that you need to build a parser that can parse that. Perhaps you also want to add ways to specify say a date or a number format.
2) Rules for resolving variables
If there is a single context object you can use reflection and match variable names to properties but if your object model is more complex you can add conventions for searching say a hierarchy of objects.
If you are planning to base your model objects on dynamic chances are that you will find the Clay library on CodePlex interesting.

How to design to prompt users for new values for properties of deserialized objects?

Right now, I'm currently serializing a class like this:
class Session
{
String setting1;
String setting2;
...etc... (other member variables)
List<SessionAction> actionsPerformed;
}
Where SessionAction is an interface that just has one method. All implementations of the SessionAction interface have various properties describing what that specific SessionAction does.
Currently, I serialize this to a file which can be loaded again using the default .Net binary serializer. Now, I want to serialize this to a template. This template will just be the List of SessionActions serialized to a file, but upon loading it back into memory at another time, I want some properties of these SessionActions to require input from the user (which I plan to dynamically generate GUI controls on the fly depending on the property type). Right now, I'm stuck on determining the best way to do this.
Is there some way I could flag some properties so that upon using reflection, I could determine which properties need input from user? Or what are my other options? Feel free to leave comments if anything isn't clear.
For info, I don't recommend using BinaryFormatter for anything that you are storing long-term; it is very brittle between versions. It is fine for short-lived messages where you know the same version will be used for serialization and deserialization.
I would recommend any of: XmlSerializer, DataContractSerializer (3.0), or for fast binary, protobuf-net; all of these are contract-based, so much more version tolerant.
Re the question; you could use things like Nullable<T> for value-types, and null for strings etc - and ask for input for those that are null? There are other routes involving things like the ShouldSerialize* pattern, but this might upset the serialization APIs.
If you know from start what properties will have that SessionAction, you must implement IDeserializationCallback and put to those props the attribute [NonSerialized]. When you implement the OnDeserialization method you get the new values from the user.

Categories