2

I have been sitting on my seat for over an hour not knowing what's the error.. Could someone please assist?

Error

Error is said to be "When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object.

The field name "LastLoginTime" is a DATETIME datatype in my database.

These are the codes..

protected void Page_Load(object sender, EventArgs e)
{
    AuditNLoggingDAO al = new AuditNLoggingDAO();

    int result = 0;

    int resultLogout = 0;

    DateTime dateTimeOfLatestLogin = DateTime.MinValue;

    //Get IP Address of Client's Machine
    String externalIP = null;
    try
    {
        externalIP = (new WebClient()).DownloadString("http://checkip.dyndns.org/");
        externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")).Matches(externalIP)[0].ToString();
    }
    catch (Exception ex)
    {
        logManager log = new logManager();
        log.addLog("Retrieval of IP Address", "IP Address", ex);
    }

    if (!Page.IsPostBack)
    {
        if (!String.IsNullOrEmpty(Session["LoginUserName"].ToString()))
        {
            String loginUsername = Session["LoginUserName"].ToString();

            //Get latest Login time
            DataSet ds = new DataSet();

            ds = al.getAuditData(Session["LoginUserName"].ToString());

            foreach (DataRow r in ds.Tables[0].Rows)
            {
                dateTimeOfLatestLogin = Convert.ToDateTime(r["LastLoginTime"]);
            }

            result = al.trackLogout(loginUsername, DateTime.Now, externalIP, Convert.ToDouble(latitudeTB.Value), Convert.ToDouble(longitudeTB.Value));
            resultLogout = al.updateLLogoutT(loginUsername, DateTime.Now, externalIP);
        }

        loginDetails.InnerText = "You logged into your account at " + dateTimeOfLatestLogin.ToString("hh:mm:ss tt dd/MM/yyyy") + " SGT.";
        logoutDetails.InnerText = "You logged out from your session at " + (DateTime.Now).ToString("hh:mm:ss tt dd/MM/yyyy") + " SGT.";
    }
}

I can't seemt to be able to find the mistake.. I'm guessing it's my dateTimedateTimeOfLatestLogin variable..

al.trackLogout method,

//Track Logout Activity
public int trackLogout(String username, DateTime dateTimeActivity, String ipaddress, Double latitude, Double longitude)
{
    int result = 0;

    StringBuilder sqlCmd = new StringBuilder();
    sqlCmd.AppendLine("INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) ");
    sqlCmd.AppendLine("VALUES (@addUsername, @addDT, @addIPAddress, @addLat, @addLng, @addActivity)");

    try
    {
        SqlConnection myConn = new SqlConnection(DBConnectionStr);

        myConn.Open();

        SqlCommand cmd = new SqlCommand(sqlCmd.ToString(), myConn);

        cmd.Parameters.AddWithValue("@addUsername", username);
        cmd.Parameters.AddWithValue("@addDT", dateTimeActivity);
        cmd.Parameters.AddWithValue("@addIPAddress", ipaddress);
        cmd.Parameters.AddWithValue("@addLat", latitude);
        cmd.Parameters.AddWithValue("@addLng", longitude);
        cmd.Parameters.AddWithValue("@addActivity", "Logout");

        result = cmd.ExecuteNonQuery();

        myConn.Close();

        return result;
    }
    catch (SqlException ex)
    {
        logManager log = new logManager();
        log.addLog("AuditNLoggingDAO.trackLogout", sqlCmd.ToString(), ex);
        return 0;
    }
}
GoldBishop
  • 2,820
  • 4
  • 47
  • 82
domster
  • 556
  • 2
  • 8
  • 26
  • have you tried `dateTimeOfLatestLogin = (DateTime)r["LastLoginTime"];` – Nino Jul 31 '17 at 13:58
  • What does LastLoginTime look like when you put it into your watch window? – aquinas Jul 31 '17 at 13:59
  • If I had a guess at this, I think you may have a problem with string format of the date time value not being recognised due to the current culture value. The way I've always done datetime conversion is to use DateTime.ParseExact(). – Damon Jul 31 '17 at 14:01
  • @domster, what is the value of `LastLoginTime`? – Mauricio Arias Olave Jul 31 '17 at 14:03
  • @Mauricio The value is {31/07/2017 22:08:12}. – domster Jul 31 '17 at 14:09
  • @aquinas when i set a breakpoint to check my autos it looks like {31/07/2017 22:08:12}. – domster Jul 31 '17 at 14:09
  • @Damon i tried using that but i still got the same error which is odd.... – domster Jul 31 '17 at 14:14
  • Possible duplicate of [Retrieving a DateTime value from a DataRow (C#)](https://stackoverflow.com/questions/1106204/retrieving-a-datetime-value-from-a-datarow-c) – mjwills Jul 31 '17 at 14:17
  • Interesting, would have thought this would work: CultureInfo provider = CultureInfo.InvariantCulture; dateTimeOfLatestLogin = DateTime.ParseExact(r["LastLoginTime"], "dd/MM/yyyy HH:mm:ss", provider); – Damon Jul 31 '17 at 14:19
  • What is the signature of `al.trackLogout` – GoldBishop Jul 31 '17 at 14:24
  • @domster put a breakpoint within that method, it may be inside that method. If that method is in a Web-Service outside of the Solution, you may need to run Debugger in two sessions, to capture the breakpoint – GoldBishop Jul 31 '17 at 14:26
  • @Damon i used dateTimeOfLatestLogin = DateTime.ParseExact(r["LastLoginTime"].ToString(), "dd/MM/yyyy HH:mm:ss", provider); the r[ ] had to have ToString() – domster Jul 31 '17 at 14:28
  • @Damon the error persists.. – domster Jul 31 '17 at 14:29
  • @domster try: `r["LastLoginTime"].ToString();` – Mauricio Arias Olave Jul 31 '17 at 14:41
  • @domster is the `DateTimeActivity` field in table `AuditActivity` a DateTime or VarChar type? – GoldBishop Jul 31 '17 at 14:41
  • it's DateTime type.. – domster Jul 31 '17 at 14:43
  • i tried https://stackoverflow.com/questions/12417770/datetime-conversion-and-parsing still doesn't work.. it's so strange.... – domster Jul 31 '17 at 14:43
  • @domster put a break-point on the `r["LastLoginTime"]` conversion to DateTime to validate the conversion...It is in your SQL...you need to move out of `StringBuilder` and move to `SqlCommand` – GoldBishop Jul 31 '17 at 14:45
  • @GoldBishop i have come across only this error after so long of using StringBuilder. SB was taught in school.. What information you might actually require from the break-point? – domster Jul 31 '17 at 14:48
  • @domster....ahh the fallacy of school....great on theory, not so great in practice....going to refactor your method in VB, current environment i have. – GoldBishop Jul 31 '17 at 14:50
  • @GoldBishop you bet.. it's insufficient in practicality.. okay sure.. thank you – domster Jul 31 '17 at 14:51
  • You're saying when you add a watch on `r["LastLoginTime"]` it looks like this: `{31/07/2017 22:08:12}`? And it says the type of C# variable is a DateTime? – aquinas Jul 31 '17 at 14:52
  • @aquinas i'll upload an image – domster Jul 31 '17 at 14:54
  • @domster, regarding `aquinas` response, your date format generally needs to be in the Localization pattern of your time setup on the Database server. – GoldBishop Jul 31 '17 at 14:54
  • Ah my bad, I thought the error was happening here `dateTimeOfLatestLogin = Convert.ToDateTime(r["LastLoginTime"]); ` not in your al.trackLogout method. So...if it's happening in THAT method, Which line is it blowing up on? – aquinas Jul 31 '17 at 14:55
  • @aquinas it started the invalid data...it was blowing up at the SQL though....that was the source of the problem. – GoldBishop Jul 31 '17 at 14:57
  • @aquinas now im confused.. the error being in al.trackLogout method? I thought it's more of the conversion to be displayed for the later part. An example of the format of LastLoginTime in the database table is 31/07/2017 22:55:05 – domster Jul 31 '17 at 14:59
  • dateTimeOfLatestLogin = DateTime.ParseExact(r["LastLoginTime"].ToString(), "dd/MM/yyyy HH:mm:ss", provider); is this correct then? i'm currently using this. – domster Jul 31 '17 at 15:01
  • Try this: https://stackoverflow.com/questions/1068386/parsing-datetime-on-localized-systems – GoldBishop Jul 31 '17 at 15:02
  • Paste the COMPLETE stack trace of the error. As it stands, it's not obvious to me exactly which line is causing the error. – aquinas Jul 31 '17 at 15:04
  • @domster You need to bring your Application into consistency with your Database environment....your application seems to have one DateTime pattern and your Database is expecting another. By Default, MS-SQL defaults to `MM/dd/yyyy hh:mm:ss tt` – GoldBishop Jul 31 '17 at 15:07
  • what might actually be the exact reason for this error.. it makes me wonder. – domster Jul 31 '17 at 15:17
  • @domster what is the database product you are submitting to? What is that RDBMS datetime settings? Execute a simple `select getdate()` (For MS-SQL) to see the datetime format the RDBMS is expecting – GoldBishop Jul 31 '17 at 15:21
  • @domster Also, Execute a test SQL statement against the RDBMS with all the values as the Application will submit them to see if it likes the various values and stores them in the format you are expecting. – GoldBishop Jul 31 '17 at 15:32
  • You should REALLY paste the complete stack trace... – aquinas Jul 31 '17 at 18:11
  • I realised the error was actually "Convert.ToDouble(latitudeTB.Value), Convert.ToDouble(longitudeTB.Value)" The date is working well. – domster Jul 31 '17 at 18:31
  • The codes i posted in my question actually work too, but the Latitude and Longitude was affecting the whole process.. I added an answer at the bottom. – domster Jul 31 '17 at 18:33

2 Answers2

1

Not C# but don't have a C# project open to write in, so it is in VB.Net; minor syntax tweaks and changes but otherwise the same:

Public Function trackLogout(username As String, dateTimeActivity As DateTime, ipaddress As String, latitude As Double, longitude As Double) As Integer
    Dim result As Integer = 0

    Try
        Using conn As New SqlConnection(DBConnectionStr)
            Dim sb As New StringBuilder
            sb.AppendLine("INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) ")
            sb.AppendLine("VALUES (@addUsername, @addDT, @addIPAddress, @addLat, @addLng, @addActivity)")

            Using cmd As New SqlCommand() With {.CommandText = sb.ToString(), .Connection = conn, .CommandType = CommandType.Text}
                cmd.Parameters.AddWithValue("@addUsername", username)
                cmd.Parameters.AddWithValue("@addDT", dateTimeActivity)
                cmd.Parameters.AddWithValue("@addIPAddress", ipaddress)
                cmd.Parameters.AddWithValue("@addLat", latitude)
                cmd.Parameters.AddWithValue("@addLng", longitude)
                cmd.Parameters.AddWithValue("@addActivity", "Logout")

                result = cmd.ExecuteNonQuery
            End Using
        End Using
    Catch ex As Exception
        result = -1
        ' Whatever your current implementation is.
    End Try

    Return result
End Function

Unfortunately, doing inline sql execution requires StringBuilder. You were correct on that. I use Stored Procedures to execute structured SQL Statements, so I do not have to manage the SQL in the application.

GoldBishop
  • 2,820
  • 4
  • 47
  • 82
  • @domster this is a more readable approach....your error is between the Application DateTime value and the SQL expected DateTime format – GoldBishop Jul 31 '17 at 16:33
  • have you tried executing the SQL Statement with the values when it errors out? – GoldBishop Jul 31 '17 at 16:41
  • @domster effectively executing your inline sql statement with all the variables `@...` replace with the values. This will allow you to see how the Application is sending the data back and how the Database is reacting to those values – GoldBishop Jul 31 '17 at 16:46
  • @domster Try inserting `31/07/2017 22:08:12` into the DateTime field – GoldBishop Jul 31 '17 at 16:53
  • In the sql query statement it should be written like this? '31/07/2017 22:08:12' with the single quotations? – domster Jul 31 '17 at 16:57
  • I used this sqlquery statement to test "INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) VALUES ('abc@gmail.com', CONVERT(DateTime, '31/07/2017 22:08:12'), 'xxx.xxx.xxx.xxx', x.x, x.x, 'Logout')" and i get this error, The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. The statement has been terminated. – domster Jul 31 '17 at 17:01
  • I'm guessing it's the datatype that this datetime provided or the format itself is nvarchar/string? – domster Jul 31 '17 at 17:01
  • i've been saving the values of datetime as datetime with DateTime.Now being the value of the variables. I used to use nvarchar but for this website im using DateTime. – domster Jul 31 '17 at 17:02
  • @domster try inserting the datetime value as `'7/31/2017 22:08:12'` – GoldBishop Jul 31 '17 at 17:11
  • the database value ended up to be 31/07/2017 22:08:12 – domster Jul 31 '17 at 17:13
  • @domster execute this statement `INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) VALUES ('abc@gmail.com', '31/07/2017 22:08:12', 'xxx.xxx.xxx.xxx', x.x, x.x, 'Logout')` – GoldBishop Jul 31 '17 at 17:13
  • The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. The statement has been terminated. I received this error for the statement u requested to be executed – domster Jul 31 '17 at 17:14
  • @domster `INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) VALUES ('abc@gmail.com', '2017-07-31 22:08:12', 'xxx.xxx.xxx.xxx', x.x, x.x, 'Logout')` – GoldBishop Jul 31 '17 at 17:14
  • INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) VALUES ('abc@gmail.com', '2017-07-31 22:08:12', 'xxx.xxx.xxx.xxx', x.x, x.x, 'Logout') This one works – domster Jul 31 '17 at 17:15
  • @domster one more `INSERT INTO AuditActivity (Username, DateTimeActivity, IPAddressActivity, LatitudeActivity, LongitudeActivity, ActivityType) VALUES ('abc@gmail.com', '7/31/2017 22:08:12', 'xxx.xxx.xxx.xxx', x.x, x.x, 'Logout')` – GoldBishop Jul 31 '17 at 17:16
  • if i'm not wrong, the format of the DateTime follows my system datetime format? – domster Jul 31 '17 at 17:20
  • 1
    @domster ok....so .Net is more forgiving and will try all patterns; whereas SQl is less forgiving and will require a specific date-time pattern. SQL will ALWAYS accept UTC patterns but otherwise use this article as a reference https://learn.microsoft.com/en-us/sql/t-sql/data-types/datetime-transact-sql – GoldBishop Jul 31 '17 at 17:20
  • 1
    @domster .Net uses Localization in representing the datetime values; SQL does not use Localization, by default. If you want it to be attuned with your TimeZone's standard Date Time format, you will need to have it setup. You would think that SQL would extract the localization format but since the SQL Server could be in the UK and the application in Pakistan, they use a Universal DateTime format, by default. So, ISO-8601 is the default pattern – GoldBishop Jul 31 '17 at 17:23
  • I'll refer to it.. Will get back once i solve. My project mate is helping me out too.. Damn didn't know this minor error would cause so much hassle. – domster Jul 31 '17 at 17:23
  • 1
    @domster welcome to System Design and Developing...read up on DateTime formats and expectations ;) – GoldBishop Jul 31 '17 at 17:24
  • sorry just to clarify, i myself am a little lost.. the error lies in the conversion of the value retrieved from the database table column? – domster Jul 31 '17 at 17:25
  • Your application was passing the DateTime value as `dd/MM/yyy ....` but SQL was expecting either `MM/dd/yyy ...` or (ISO) `yyyy-MM-dd ...`. In either case, your applications value did not "jive" with SQL's expected format and "threw up" all over the execution. – GoldBishop Jul 31 '17 at 17:27
  • But using DateTime.Now to store this value into the database, SQL will automatically convert to the universal format of its own? – domster Jul 31 '17 at 17:30
  • @domster that is correct...although I am unsure how it will behave from a Inline SQL execution. In theory, it should work but no guarantees ;) – GoldBishop Jul 31 '17 at 17:52
  • alright.. i'll try my best to take it from here. thank you bishop! you're gold! – domster Jul 31 '17 at 17:53
0

My Revised Codes that i'm using right now..

protected void Page_Load(object sender, EventArgs e)
{
    AuditNLoggingDAO al = new AuditNLoggingDAO();

    int result = 0;

    int resultLogout = 0;

    //Get IP Address of Client's Machine
    String externalIP = null;
    try
    {
        externalIP = (new WebClient()).DownloadString("http://checkip.dyndns.org/");
        externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")).Matches(externalIP)[0].ToString();
    }
    catch (Exception ex)
    {
        logManager log = new logManager();
        log.addLog("Retrieval of IP Address", "IP Address", ex);
    }

    CultureInfo provider = CultureInfo.InvariantCulture;

    if (!String.IsNullOrEmpty(Session["LoginUserName"].ToString()))
    {
        String loginUsername = Session["LoginUserName"].ToString();

        //Get latest Login time
        DataSet ds = new DataSet();

        ds = al.getAuditData(Session["LoginUserName"].ToString());

        DateTime dateTimeOfLatestLogin = DateTime.MinValue;

        /*foreach (DataRow r in ds.Tables[0].Rows)
        {
            //dateTimeOfLatestLogin = DateTime.ParseExact(r["LastLoginTime"].ToString(), "dd-MM-yyyy hh:mm:ss", CultureInfo.InvariantCulture);
            String dtDBString = r["LastLoginTime"].ToString();
            dateTimeOfLatestLogin = Convert.ToDateTime(dtDBString);

            //Debug.WriteLine(dateTimeOfLatestLogin);
            //"MM-dd-yyyy HH:mm:ss tt"
        }*/

        String DBConnectionStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;

        SqlConnection connection = new SqlConnection(DBConnectionStr);
        string sql = "select LastLoginTime FROM AuditTrails WHERE Username=@USERID";
        SqlCommand command = new SqlCommand(sql, connection);
        command.Parameters.AddWithValue("@USERID", loginUsername);
        try
        {
            connection.Open();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    string timeTaken = reader["LastLoginTime"].ToString();
                    dateTimeOfLatestLogin = Convert.ToDateTime(timeTaken);
                }
            }
            connection.Close();
        }
        catch (SqlException ex)
        {
            logManager log = new logManager();
            log.addLog("LogoutWithDesc.aspx.cs", "PageLoad", ex);
        }

        resultLogout = al.updateLLogoutT(loginUsername, DateTime.Now, externalIP);
        result = al.trackLogout(loginUsername, externalIP, Convert.ToDouble(latitudeTB.Value), Convert.ToDouble(longitudeTB.Value));

        loginDetails.InnerText = "You logged into your account at " + dateTimeOfLatestLogin.ToString("hh:mm:ss tt dd/MM/yyyy") + " SGT.";
        logoutDetails.InnerText = "You logged out from your session at " + (DateTime.Now).ToString("hh:mm:ss tt dd/MM/yyyy") + " SGT.";
    }     
}
domster
  • 556
  • 2
  • 8
  • 26