Where in my app to default all time to UTC - asp.net

how to ensure all my datetime is stored as UTC without going through all code? Does this have to be set in db ? how?
thanks.

In a web app, there are two ways that a non UTC DateTime can get into your database.
1) You did it. Search for all occurrences of DateTime.Now. Those need to be DateTime.UtcNow. Still, a find and replace isn't going to cover it all, because you'll need to update every place in your code where you display these dates to your users to convert them to local time.
2) Your user sent you a date/time. There's no automated way to look for these. You need to manually review every page that the user can use to pass a date/time. Either as data to be saved to your database or as a filter to be used in a query. You'll need to know their UTC offset and apply it to these occurrences before using them.
Be sure to capture the user's UTC offset as soon as they enter your site. As of now, the only way to do this is through javascript. If you have a single entry point (ie a login page) then you can put it there. Otherwise, you'll need to do it in your master page, or, if you don't have a master page, every page that they could enter on.
to get the UTC Offset in javascript use the following code:
var now = new Date();
int Offset = now.getTimezoneOffset()
Then pass the offset back to the server. There you can create two functions to handle converting from/to UTC.
Where UtcOffset holds the javascript Offset:
public static DateTime ConvertFromUtcToClientTime(DateTime utcDateTime)
{
return utcDateTime.AddMinutes(-UtcOffset);
}
public static DateTime ConvertFromClientTimeToUtc(DateTime clientDateTime)
{
return clientDateTime.AddMinutes(UtcOffset);
}

Related

MVC - how can I store a variable for the duration that a user is logged in

I have a project in MVC. I would like to save a variable and have it accessible as long as the user is logged in, to get it or set it.
The reason for this is that the application uses the information I would put in there, to get data. I now need to add admin functions so an admin can see more then only his own results, and therefore I would need to change this ID, depending on what result he wants to see.
I have tried using a session, but the problem I have with that is that when the user closes the website, and at a later time returns, he is still logged in, but the session variable is null.
I also tried to add a property to my base class. I was able to set it, but when I tried to get it in a different controller, the property was null as well.
What is the best/fastest/correct way to do this? I would prefer to not use the database for this, if possible.
What you are looking for is a "Session". On login you can just do
Session["Key"] = "Value";
And on logout you can empty the field
Session["Key"] = String.Empty;
You can read more about sessions here: https://msdn.microsoft.com/en-us/library/ms178581.aspx

Play framework: How do I define the timezone for the date entered by a user?

In my play framework app the user has the choice to enter a date for a schedule, the date is then mapped to my model entity:
#InFuture
#As("dd/MM/yyyy HH:mm")
public Date validFrom;
This is the field in the form
<input type="text" name="schedule.validFrom" placeholder="dd/mm/yyyy hh:mm">
The problem is that our server is running in a non-local time zone and the timezone should be taken from the object where this schedule is being made for.
So I know upfront what the timezone is for this schedule and I don't want the user having to enter the timezone in the field.
A possible solution would be to submit the date as string and do manual validation and parsing but I wonder if there is a better solution.
Manual parsing is probably your best option.
You could possibly create your own object containing the date and the timezone.
Then implement your own validation check based on InFutureCheck and perform the timezone conversion.
The better option will be to give user a drop down list of timezones. For example:
String TIMEZONE_ID_PREFIXES ="^(Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific)/.*";
String[] ids = TimeZone.getAvailableIDs();
Timezone tz = null;
for (int i=0; i<ids.length; i++) {
if (ids[i].matches(TIMEZONE_ID_PREFIXES)) {
//add TimeZone.getTimeZone(ids[i]).getDisplayName() to a drop down list
}
}
The best practice here really depends on whether your users need to see multiple timezones.
If they do not need multiple timezones, then you can assume all times are 'zone-less' aka they are all UTC or GMT. This is by far the simplest option.
If users need to see multiple timezones, then you are best off passing the timezone with each date with the Z parameter: http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#rfc822timezone Meanwhile, in Javascript, you will probably want to use a library to create a date string with a timezone, such as: http://arshaw.com/xdate/#Formatting

Session ASP.NET

Session question in asp.net/c#
I have multiple asp.net pages and a class object.
e.g.
Class User object contains
public string Name { set; get; }
public string Address { set; get; }
etc.....
pg1.aspx: when button is clicked, the data is stored in the session and redirects to pg2.aspx
e.g. pg1.aspx
User u = new User();
u.Name = TextBox1.Text;
Session.Add("USERINFO", u);
Response.Redirect("pg2.aspx");
e.g. pg2.aspx //reading the data..
User u = ((User)Session["USERINFO"]);
Response.Write(u.Name + "<br/>");
..etc.. ( I have 5 pages and the data is passed around from page to page in a session) once the user reaches the last page it stores in the database otherwise I dont want to store incomplete data in the database.
It all works fine except if I use multiple tabs to run same web app, the data overwrites eachother... It works fine if I use separate browsers, but not with tabs...
How can I avoid a user to enter the data in tab1 get to page 3 and if the user opens tab2 and continues not to over the data was entered in tab1....
I hope it makes sense... what I am trying to accomplish... Thank you.
This is probably a duplicate question, so I'll simply redirect you to some answers that would solve your problem.
asp.net - session - multiple browser tabs - different sessions?
Unfortunately, the accepted answer won't work since it maintains a "unique" session identifier for each page, not your group of 5 pages.
Your browser version and the different methods of launching new tabs and windows in it determines whether sessions are shared across multiple tabs and windows. Controlling it could be done with
The modification to web.config as described in the linked article
Coming up with a unique session key prefix for each session value
Using some logic to prevent the same user from opening multiple sessions on the same machine
The simplest way to work around your current implementation would likely be to check whether or not you have the information you would expect from that page, and if the conditions aren't met then require the data to be input, or redirect appropriately depending on which stage in the process you are (based on the data that is available).
So, as well as adding to the session, you can get:
var value = Session[key] as string;
if (value != null)
{
//move on to the next appropriate page
//after determining which that is by other conditions
}
//we obviously need the page at which we get this data!
And you can build upon your conditions from there

ASP.NET MVC - Is there a way to simulate a ViewState?

I have the following situation... In a certain View, the user must select the initial hour, the final hour and the weekday. But, I can't save this informations to DB 'cause I need to save my whole page and I need the primary key of the primary table, but that's not the point.
So, while I don't save these data to DB, I'm saving to a Session. I was told to save to a cookie, but it appears that cookies have a size limit. So, I'm saving to a Session.
Buuuut, I was also told that I could save these informations (hours and weekday) to the user page, simulating a ASP.NET ViewState...
Does anyone know how to do this?? Does anyone know how to save temporarily these data withou using cookie or Session??
Thanks!!
Hidden input fields won't help?
<%= Html.Hidden(...) %>
Update (serializing an object to base64):
var formatter = new BinaryFormatter();
var stream = new MemoryStream();
formatter.Serialize(stream, myObject); // myObject should be serializable.
string result = Convert.ToBase64String(stream.ToArray());
When you want to fetch it back:
var formatter = new BinaryFormatter();
var stream = new MemoryStream(Convert.FromBase64String(hiddenFieldValue));
var myObject = (MyObjectType)formatter.Deserialize(stream);
Make sure you validate the data stored in the field when you use it as the client might change it. ViewState takes care of this automatically.
Side note: ASP.NET uses LosFormatter instead of BinaryFormatter to serialize ViewState as it's more efficient or ASCII based serialization. You might want to consider that too.
TempData["MyData"], mind you this will only last one round trip.
You could save a javascript array on the client... and then transmit all the information when the user ultimately saves.
You have to work a little more, but in the end it pays off.
I heavily use jQuery to do stuff like that, it's easier than it seems.
If you just want to save the data for that request and the next request I'd recommend using Tempdata, else I'd recommend using Mehrdad`s answer.

Best way to store commonly used values

In my Webforms 3.5 application, I have a GridView of users that displays the last time they logged in. This value is stored in the Users table in UTC. When an Administrator views the grid, I want them to view it the time zone the Administrator has selected in their preferences (also stored in the Users table).
I have this working properly for the GridView:
<ItemTemplate>
<%# TimeZoneInfo.ConvertTimeFromUtc(Eval("LastLoginDateTimeUTC"), TimeZoneInfo.FindSystemTimeZoneById(UserService.GetUser(HttpContext.Current.User.Identity.Name).DisplayTimeZone))%>
</ItemTemplate>
So in this case, every time a row is created, a user object is created.
What I would like to do is determine the best way to handle returning commonly used User specific data (such as user.DisplayTimeZone). I have several ideas in mind, but I wanted to get some input on how others are doing it. I was looking at using a User Specific Cache, but didn't want to implement until I had more ideas.
I would like to avoid the Session object, but it's not a requirement. I would prefer to use the HttpRuntime.Cache.
Also, once this is determined, where should the code for this go? In a BasePage class? In the MasterPage? In an MVP BasePresenter?
Thanks
~S
I've done the same using a user specific cache as you mentioned. I actually implemented it in a separate namespace though as static get properties. For example:
namespace MyWeb.Session
public static class CurrentUser {
public static int DisplayTimeZone {
get {
// Check cache first.
...
// Cache miss, load from database and store in cache.
...
}
}
}
}
That way every time I needed the value I simply call MyWeb.Session.CurrentUser.DisplayTimeZone.

Resources