asp.net timestamp issue - asp.net

This i my code for storing record information from asp.net 2.0 webform
scmd.Connection = scon; //Connection string
SqlParameter p = scmd.CreateParameter();
recodName = txtrecordname.Text; //form field
todaysdate = DateTime.Parse(txtFrom.Text);
DateTime now = DateTime.UtcNow;
AddParameters("#record", recodName); //adding parameter to stored procedure
AddParameters("#date", todaysdate);
AddParameters("#timeinfo", now);
scmd.CommandText = "sp_InsertRecord";
scmd.CommandType = CommandType.StoredProcedure;
scon.Open();
int i=scmd.ExecuteNonQuery();
if (i > 0)
{
result.Text = "Record Inserted RecordName : " + recodName; //Label displaying recordinfo
dateinfo.Text = "Record inserted on (TimeStamp Info) : " + now; //label displaying time info when user inserted record
}
GridView1.DataBind();
This web application is hosted on server whose timezone is (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi,
Now user from another system access the application whose time zone is (UTC+01:00) West Central Africa,
As you can see i have inserted 'datetime now as Utcnow' but when user view the record inserted it must be in its local datetimeformat
i.e
dateinfo.Text = "TimeStamp Info : " + now; //This label should display local time info currently it displays server local time where the application is hosted
Thanxs for any help

When loading the DateTime from the Database (you said you store UTC there), you need to specifiy the Kind of this time explicitely:
DateTime dateTimeFromDatabase = LoadDateTimeValueFromDatabase();
DateTime utcDate = DateTime.SpecifyKind(dateTimeFromDatabase, DateTimeKind.Utc);
Then, as long as you have the Culture of the web site visitor set correctly, you can simply use .ToLocalTime() from the DateTime to display the Utc value as local time:
DateTime localTimeToDisplay = utcDate.ToLocalTime();
You then use the localTimeToDisplay variable for databinding and you're all set.
Update: To display the current time you can simply do:
dateinfo.Text = "TimeStamp Info : " + DateTime.UtcNow.ToLocalTime();
As UtcNow already sets the Kind of DateTime to UTC.
You need to set the correct culture for the client, though. So you would need to do that either manually or set this in the web.config:
<system.web>
<globalization culture="auto" />
<system.web>

Use javascript to get the current time in the client system and put that in a javascript variable.
How to do it can be found here: http://www.quackit.com/javascript/javascript_date_and_time_functions.cfm
Then assign the javascript variable value to a hidden field variable and access it in the server side.
How to access javascript variable in code behind http://codeasp.net/blogs/joydeep157/microsoft-net/81/accessing-javascript-variable-from-code-behind-and-accessing-code-behind-variable-from-javascript
Now you have the client time in your server variable.

Related

Configure that Newtonsoft serializer serializes a date respecting the local time

I send javascript dates to the server via:
let start = new Date().toISOString()
This date string is sent as UTC date string.
On server side I have convert this utc date everywhere to the local date (CH/DE/AT) via myDate.ToLocalTime() which I want to save in the database.
I do not want this manual conversion at many places.
How can I fix this with newtonsoft json serializer ?
That I get always the current local time I do:
var cultureInfo = new CultureInfo("de-DE");
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
in my Startup.cs
You can add the below in your ConfigureServices method:
services.AddMvc()
.AddJsonOptions(o =>
{
o.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
}
See DateTimeZoneHandling setting.
The DateTimeZoneHandling Enumeration defines DateTimeZoneHandling.Local as follows:
Local - Treat as local time. If the DateTime object represents a
Coordinated Universal Time (UTC), it is converted to the local time.

Exchange Web Services find item by unique id

I just started using Microsoft Exchange Web Services for the first time. Want I want to be able to do is the following:
Create Meeting
Update Meeting
Cancel/Delete Meeting
These meetings are created in an ASP.NET MVC application and saved into a SQL Server database. I simply wish to integrate this with the on site Exchange Server. So far, I'm able to created my meeting with the following code:
public static Task<string> CreateMeetingAsync(string from, List<string> to, string subject, string body, string location, DateTime begin, DateTime end)
{
var tcs = new TaskCompletionSource<string>();
try
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.Credentials = CredentialCache.DefaultNetworkCredentials;
//service.UseDefaultCredentials = true;
// I suspect the Service URL needs to be set from the user email address because this is then used to set the organiser
// of the appointment constructed below. The Organizer is a read-only field that cannot be manually set. (security measure)
service.AutodiscoverUrl(from);
//service.Url = new Uri(WebConfigurationManager.AppSettings["ExchangeServer"]);
Appointment meeting = new Appointment(service);
meeting.Subject = subject;
meeting.Body = "<span style=\"font-family:'Century Gothic'\" >" + body + "</span><br/><br/><br/>";
meeting.Body.BodyType = BodyType.HTML;
meeting.Start = begin;
meeting.End = end;
meeting.Location = location;
meeting.ReminderMinutesBeforeStart = 60;
foreach (string attendee in to)
{
meeting.RequiredAttendees.Add(attendee);
}
meeting.Save(SendInvitationsMode.SendToAllAndSaveCopy);
tcs.TrySetResult(meeting.Id.UniqueId);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
return tcs.Task;
}
This successfully creates my meeting, places it into the user's calendar in outlook and sends a meeting request to all attendees. I noticed the following exception when attempting to call meeting.Save(SendInvitationsMode.SendToAllAndSaveCopy); twice:
This operation can't be performed because this service object already has an ID. To update this service object, use the Update() method instead.
I thought: Great, it saves the item in exchange with a unique id. I'll save this ID in my application's database and use it later to edit/cancel the meeting. That is why I return the id: tcs.TrySetResult(meeting.Id.UniqueId);
This is saved nicely into my application's database:
Now, I am attempting to do the next part where I update the meeting, but I cannot find a way to search for the item based on the unique identifier that I'm saving. An example I found on code.msdn uses the service.FindItems() method with a query that searches the subject:
string querystring = "Subject:Lunch";
FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Calendar, querystring, view);
I don't like this. There could be a chance that the user created a meeting outside of my application that coincidentally has the same subject, and here come's my application and cancel's it. I tried to determine wether it's possible to use the unique id in the query string, but this does not seem possible.
I did notice on the above query string page that the last property you can search on is (property is not specified) that searches in "all word phase properties.". I tried thus simply putting the id into the query, but this returns no results:
FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Calendar, "AAMkADJhZDQzZWFmLWYxYTktNGI1Yi1iZTA5LWVmOTE3MmJiMGIxZgBGAAAAAAAqhOzrXRdvRoA6yPu9S/XnBwDXvBDBMebkTqUWix3HxZrnAAAA2LKLAAB5iS34oLxkSJIUht/+h9J1AAFlEVLAAAA=", view);
Use the Appointment.Bind static function, providing a service object and the ItemId saved in your database. Be aware with meeting workflow (invite, accept, reject) can re-create a meeting on the same calendar with a new ItemId. But if you are just looking at the meeting you make on your own calendar, you should be OK.

ASP Membership / Role Provider -> how to report the number of users currently logged in?

I'm using the ASP.NET Membership and Role provider. My question is about if there is a built in way to report the number of users who are currently logged in. The question is not get the information about the user who is logged in but from a high level view of everyone who is logged in.
I would like to create a user management dashboard and this metric would be great. also showing the usernames of users who are currently logged in would be useful.
thank you for any help you can provide.
Yes there's a built-in way, see Membership.GetNumberOfUsersOnline(). You can change the "window" for what's considered online, see Membership.UserIsOnlineTimeWindow. (you set the threshold in web.config)
UPDATE:
In response to your comment about getting a list of online usernames...
The Membership API is lacking what you want, so you have to roll your own. You can use the following as starter code, it's similar to what I've done in the past:
public static List<string> GetUsersOnline() {
List<string> l = new List<string>();
string CS = WebConfigurationManager
.ConnectionStrings[YOUR_WEB_CONFIG_KEY]
.ConnectionString
;
string sql = #"
SELECT UserName,LastActivityDate
FROM aspnet_Users
WHERE LastActivityDate > #window
ORDER BY LastActivityDate DESC"
;
using (SqlConnection c = new SqlConnection(CS) ) {
using (SqlCommand cmd = new SqlCommand(sql, c) ) {
DateTime window = DateTime.UtcNow.AddMinutes(
-Membership.UserIsOnlineTimeWindow
);
cmd.Parameters.AddWithValue("#window", window);
c.Open();
using (SqlDataReader r = cmd.ExecuteReader() ) {
while ( r.Read() ) {
l.Add(r.GetString(0));
}
}
}
}
return l;
}
A couple of notes:
Replace YOUR_WEB_CONFIG_KEY above with the key in your web.config <connectionStrings> section.
The LastActivityDate field in the aspnet_Users table (aspnetdb database) is stored as a GMT/UTC Datetime value, so that's why DateTime.UtcNow is used to calculate the window.
Not sure how your Membership database permissions are setup, but you may need to make permission changes, since above code is directly querying the database.

Finding midnight from a stored variable

I have a web page that will allow customers to enter a date/time and I want to be able to stored that variable and then add to that time until Midnight, store that as a second variable and pass it to my sql server. Is there an easy way to do that?
Sure you can do:
var midnightDateNExtDay = DateTime.Now.AddDays(1).Date;
//AddDays moves time to next day
// Date should omit the time and make it midnight
Do you mean midnight previous or next day? Then, using this param, pass it to the stored procedure or query.
If you want the difference, you can do something like this and pass in the total seconds to sql server. This depends how you want to store this though on the sql end?
TimeSpan span = DateTime.Now.Subtract(DateTime.Now.AddDays(1).Date);
//do whatever with span.TotalSeconds
EDIT
It seems you also want to know how to send this into your procedure:
note this assumes connection strings setup in your app's config file. If not replace ConfigurationManager.ConnectionStrings[0].ConnectionString with "server=whatever;uid;whatever;pwd=whatever;" for your testing (I recommend you dont embed them in code though)
using (SqlConnection connection = new
SqlConnection(ConfigurationManager.ConnectionStrings[0].ConnectionString))
{
var midnight = DateTime.Now.AddDays(1).Date;
using (SqlCommand command = new SqlCommand("Proc_Whatever", connection))
{
command.Parameters.Add(new SqlParameter("#MidnightDate", midnight));
command.CommandType = CommandType.StoredProcedure;
connection.Open();
command.ExecuteNonQuery();
}
}

Is asp.net caching my sql results?

I have the following method in an App_Code/Globals.cs file:
public static XmlDataSource getXmlSourceFromOrgid(int orgid)
{
XmlDataSource xds = new XmlDataSource();
var ctx = new SensusDataContext();
SqlConnection c = new SqlConnection(ctx.Connection.ConnectionString);
c.Open();
SqlCommand cmd = new SqlCommand(String.Format("select orgid, tekst, dbo.GetOrgTreeXML({0}) as Subtree from tblOrg where OrgID = {0}", orgid), c);
var rdr = cmd.ExecuteReader();
rdr.Read();
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<node orgid=\"{0}\" tekst=\"{1}\">",rdr.GetInt32(0),rdr.GetString(1));
sb.Append(rdr.GetString(2));
sb.Append("</node>");
xds.Data = sb.ToString();
xds.ID = "treedata";
rdr.Close();
c.Close();
return xds;
}
This gives me an XML-structure to use with the asp.net treeview control (I also use the CssFriendly extender to get nicer code)
My problem is that if I logon on my pc with a code that gives me access on a lower level in the tree hierarchy (it's an orgianization hierarchy), it somehow "remembers" what level i logon at. So when my coworker tests from her computer with another code, giving access to another place in the tree, she get's the same tree as me.
(The tree is supposed to show your own level and down.)
I have added a html-comment to show what orgid it passes to the function, and the orgid passed is correct. So either the treeview caches something serverside, or the sqlquery caches it's result somehow...
Any ideas?
Sql function:
ALTER function [dbo].[GetOrgTreeXML](#orgid int)
returns XML
begin RETURN
(select org.orgid as '#orgid',
org.tekst as '#tekst',
[dbo].GetOrgTreeXML(org.orgid)
from tblOrg org
where (#orgid is null and Eier is null) or Eier=#orgid
for XML PATH('NODE'), TYPE)
end
Extra code as requested:
int orgid = int.Parse(Session["org"].ToString());
string orgname = context.Orgs.Where(q => q.OrgID == orgid).First().Tekst;
debuglit.Text = String.Format("<!-- Id: {0} \n name: {1} -->", orgid, orgname);
var orgxml = Globals.getXmlSourceFromOrgid(orgid);
tvNavtree.DataSource = orgxml;
tvNavtree.DataBind();
Where "debuglit" is a asp:Literal in the aspx file.
EDIT:
I have narrowed it down. All functions returns correct values. It just doesn't bind to it. I suspect the CssFriendly adapter to have something to do with it.
I disabled the CssFriendly adapter and the problem persists...
Stepping through it in debug it's correct all the way, with the stepper standing on "tvNavtree.DataBind();" I can hover the pointer over the tvNavtree.Datasource and see that it actually has the correct data. So something must be faulting in the binding process...
I would normally suspect the issue is with orgid that is getting passed in to your method, but you say that you have checked to make sure the right code is being passed. Just to confirm, show us the code that assigns the value to that.
Additionally, there are a few problems with your code, SQL injection risk being one of them. orgid is an int, offering some protection, but if at some point orgid is changed to require characters by your organization, a developer may just change the data type to string, suddenly opening up the app to SQL injection. You should remove the String.Fotmat, and use a parameterized query instead.
I found the problem. The XmlDataSource component has a cache function, which by default is enabled. When I disabled this, everything works nicely.

Resources