Perform conversions on all datetimes on get/set? - c#

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).

Related

StackExchange.Redis Send Structs

I am new to redis and I wonder how to send a class or a struct with StackExchange.Redis.
So lets assume I want to write
var redis = ConnectionMultiplexer.Connect("localhost");
var db = redis.GetDatabase();
db.StringSet(key, value);
This is actually only possible if my value is primitive. So is there any other way to achieve sending complex types without serializing them as json?
Since Redis is not aware of your class or struct, you'll need to define how to store it. A recommended way is to store the object as a hash, where the key is the property name, and the value is the property value. Note that this does not support object graphs, e.g. nested collections or complex types.
As per the documentation on data types:
A hash with a few fields (where few means up to one hundred or so) is stored in a way that takes very little space, so you can store millions of objects in a small Redis instance.
Alternatively, you could serialize the object yourself and store it as a string/byte[]. Json is one format, which includes the property names in the data, which is great for versioning. E.g. if a new property is added, you wouldn't need to go and change all existing data. The downside is that it takes up a lot of space. You could use any other form of serialization as well, e.g. binary serialization.

Custom JSON converter for Noda Time

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.

Dynamic form with no real OOP or objects?

I am tacking a large refactor of a project, and I had asked this question to confirm/understand the direction I should go in and I think I got the answer that I wanted, which is not to throw away years worth of code. So, now begins the challenge of refactoring the code. I've been reading Martine Fowler and Martin Feathers' books, and they have a lot of insight, but I am looking for advice on the ultimate goal of where I want the application to be.
So to reiterate the application a little bit, its a dynamic forms system, with lots of validation logic and data logic between the fields. The main record that gets inserted is the set of form fields that is on the page. Another part of it is 'Actions' that you can do for a person. These 'Actions' can differ client by client, and there are hundreds of 'Actions'. There is also talk that we can somehow make an engine that can eventually take on other similar areas, where a 'person' can be something else (such as student, or employee). So I want to build something very de-coupled. We have one codebase, but different DBs for different clients. The set of form fields on the page are dynamic, but the DB is not - it is translated into the specific DB table via stored procs. So, the generic set of fields are sent to the stored proc and the stored proc then decides what to do with the fields (figure out which table it needs to go to). These tables in fact are pretty static, meaning that they are not really dynamic, and there is a certain structure to it.
What I'm struggling specifically is how to setup a good way to do the dynamic form control page. It seems majority of the logic will be in code on the UI/aspx.cs page, because its loading controls onto the webpage. Is there some way I can do this, so it is done in a streamlined fashion, so the aspx.cs page isn't 5000 lines long? I have a 'FORM' object, and one of the properties is its' 'FIELDS'. So this object is loaded up in the business layer and the Data layer, but now on the fron end, it has to loop through the FIELDS and output the controls onto the page. Also, someway to be able to control the placement would be useful, too - not sure how do get that into this model....
Also, from another point of view - how can I 'really' get this into an object-oriented-structure? Because technically, they can create forms of anything. And those form fields can represent any object. So, for example, today they can create a set of form fields, that represent a 'person' - tomorrow they can create a set of form fields that represent a 'furniture'. How can I possibly translate this to to a person or a furniture object (or should I even be trying to?). And I don't really have controls over the form fields, because they can create whatever....
Any thought process would be really helpful - thanks!
How can I possibly translate this to to a person or a furniture object
(or should I even be trying to?)
If I understand you correctly, you probably shouldn't try to convert these fields to specific objects since the nature of your application is so dynamic. If the stored procedures are capable of figuring out which combination of fields belongs to which tables, then great.
If you can change the DB schema, I would suggest coming up with something much more dynamic. Rather than have a single table for each type of dynamic object, I would create the following schema:
Object {
ID
Name
... (clientID, etc.) ...
}
Property {
ID
ObjectID
Name
DBType (int, string, object-id, etc.)
FormType ( textbox, checkbox, etc.)
[FormValidationRegex] <== optional, could be used by field controls
Value
}
If you can't change the database schema, you can still apply the following to the old system using the stored procedures and fixed tables:
Then when you read in a specific object from the database, you can loop through each of the properties and get the form type and simple add the appropriate generic form type to the page:
foreach(Property p in Object.Properties)
{
switch(p.FormType)
{
case FormType.CheckBox:
PageForm.AddField(new CheckboxFormField(p.Name, p.Value));
break;
case FormType.Email:
PageForm.AddField(new EmailFormField(p.Name, p.Value));
break;
case FormType.etc:
...
break;
}
}
Of course, I threw in a PageForm object, as well as CheckboxFormField and EmailFormField objects. The PageForm object could simply be a placeholder, and the CheckboxFormField and EmailFormField could be UserControls or ServerControls.
I would not recommend trying to control placement. Just list off each field one by one vertically. This is becoming more and more popular anyway, even with static forms who's layout can be controlled completely. Most signup forms, for example, follow this convention.
I hope that helps. If I understood your question wrong, or if you'd like further explanations, let me know.
Not sure I understand the question. But there's two toolboxes suitable for writing generic code. It's generics, and it's reflection - typically in combination.
I don't think I really understand what you're trying to do, but a method using relfection to identify all the properties of an object might look like this:
using System.Reflection;
(...)
public void VisitProperties(object subject)
{
Type subjectType = subject.GetType();
foreach (PropertyInfo info in subjectType.GetProperties()
{
object value = info.GetValue(subject, null);
Console.WriteLine("The name of the property is " + info.Name);
Console.WriteLine("The value is " + value.ToString());
}
}
You can also check out an entry on my blog where I discuss using attributes on objects in conjunction with reflection. It's actually discussing how this can be utilized to write generic UI. Not exactly what you want, but at least the same principles could be used.
http://codepatrol.wordpress.com/2011/08/19/129/
This means that you could create your own custom attributes, or use those that already exists within the .NET framework already, to describe your types. Attributes to specify rules for validation, field label, even field placement could be used.
public class Person
{
[FieldLabel("First name")]
[ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)]
[FormColumn(1)]
[FormRow(1)]
public string FirstName{get;set;}
[FieldLabel("Last name")]
[ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)]
[FormColumn(2)]
[FormRow(1)]
public string LastName{get;set;}
}
Then you'd use the method described in my blog to identify these attributes and take the apropriate action - e.g. placing them in the proper row, giving the correct label, and so forth. I won't propose how to solve these things, but at least reflection is a great and simple tool to get descriptive information about an unknown type.
I found xml invaluable for this same situation. You can build an object graph in your code to represent the form easily enough. This object graph can again be loaded/saved from a db easily.
You can turn your object graph into xml & use xslt to generate the html for display. You now also have the benefit of customising this transform for differnetn clients/versions/etc. I also store the xml in the database for performance & to give me a publish function.
You need some specific code to deal with the incoming data, as you're going to be accessing the raw request post. You need to validate the incoming data against what you think you was shown. That stops people spoofing/meddling with your forms.
I hope that all makes sense.

What is the difference between HttpContext.Current.Application.Get([some enum]) and just enum?

I have:
HttpContext.Current.Application.Get(KeyNames.EncodedKey).ToString()
Where KeyNames is an enum.
I can't use HttpContext. What should I check before I just use KeyNames.EncodedKey instead of HttpContext.Current.Application.Get(KeyNames.EncodedKey).ToString() ? (or is there another way?)
Thanks.
You can store data in the Application object, just like you can store stuff in the Session or in the ViewState. This data is stored in a dictionary-like data structure, so you have a key as well as a value.
Now, the two things you mentioned are two fundamentally different things:
KeyNames.EncodedKey is just an enum value.
HttpContext.Current.Application.Get(KeyNames.EncodedKey).ToString() returns the value stored in the Application object whose key is KeyNames.EncodedKey. The value is then converted to a string.
So, just using KeyNames.EncodedKey is in no way a replacement for HttpContext...etc..
Just tell us what you want to do and why you cannot use HttpContext, then someone might be able to suggest a solution to your problem.

How to avoid dependencies between Enum values in code and corresponding values in a database?

I have a number of user permissions that are tested throughout my ASP.NET application. These permission values are referenced in an Enum so that I can conveniently test permissions like so:
btnCreate.Enabled = PermissionManager.TestPermission(Permission.AllowCreate);
However, I also have these permissions stored in the database because I need hold more info about them than just their Id. But this creates a horrible dependency between the enum values and those in the database, an ill considered change to either and I have problems throughout my application. Is there a better way around this issue? Has anyone dealt with this before?
I do not know what the best solution is, I would like to hear that.
Our solution is to explicitly type the enum like
public enum MyEnum : int
{
None =0,
Value = 1,
AnotherValue =2
}
And save the integer value to the database. When for instance the Value 1 is removed, you will still be able to use the enumeration and AnotherValue still has the value 2 in the database.
Or maybe store the enumvalues as string in the DB. ToString();
Using enum values is acceptable to do as long as you never change the already assigned values. If you were using the standard role-based authorization in .NET you would still be relying on the exisistence of certain text strings in the corresponding role table in the database.
We use a small application that generates enum code (example: NorthwindEnums.cs) from the database. We make sure to run it and update affected libraries whenever the database changes.
We also try to keep our enums starting at 0 and sequential to avoid issues with web service references in C#.
A while back I built a little tool to do this for my company that would use attributes on the enum fields to allow "synchronisation" with the table in the database.
The tool could scan an assembly and generate appropriate INSERT/UPDATE SQL commands that would sync the database with the enum definition in the code.
I add an extended property on any table that I will need to access in code as an enum. I then use code generation software (codesmith, T4, whatever) to generate all my enum's for me by looking up any table with this property. Any table that is to be used for this abides by some basic rules (must have a Name column, etc.) so the code generator knows which column to use as the name for the enum's elements.
Once values are added to those tables we take care to virtually never change them to avoid breaking the build.

Categories