Trouble with Time Formating in Asp.Net - asp.net

I'm developing a web app which is the transition from a previous desktop versión based in visual basic 6. I have to display times within a support ticket system of when the ticket first arrived,was first handled etc.
I'm running into certain problems when time formating since I seem to have to use several different methods to get what I want depending on the input and now I'm confused as to when I should use each.
For example, when using a system DateNow to get an answer in Hours, minutes and seconds this works fine:
Strings.Format(Date.Now, "HH:mm:ss")
But I have string values within the database, that are stored in a certain way and I cannot modify the database to have a timestamp field which I would prefer to store it, with the time, minutes and seconds scrunched up together as in where 13h,57mins,20secs ends in a string "135720". If I try the same
Dim info as string="135720"
Strings.Format(val(info),"HH:mm:ss)
The answer I get is the actual formating "HH:mm:ss", not the 13:57:20 I expected.
But if I use a transformed VB6 function in .net:
Microsoft.VisualBasic.Format(Val(Info), "##:##:##")
it works just fine.
I also have to use the Microsoft.VisualBasic.Format when trying to fix badly stored strings with partial times such as "1357" or just "135" to turn it into "13:57:00" or "13:50:00"using a case select based on the length of the string.
but I really don't want to be using old programming language in what is supposed to be a an updated app just because I don't finally understand how the new works and I have looked extensively into the documentation, but am none the wiser.
I did look within th comunity but didn't really find the answer either in such questions as:
Is there a way to programmatically convert VB6 Formatting strings to .NET Formatting strings?
A regular expression to validate .NET time format
Time format of datetime field in .net
Time format in asp.net page
Any help finding the new way I should be doing this and why would be greatly apreciated.
Thank You

You can use TimeSpan.
This Function will return a TimeSpan from your String-value.
Public Function GetTimeSpan(s As String)
Dim span As TimeSpan
s = s.Trim 'Trim spaces
'Check if string only contains numbers and if length is valid, else throw exception
If System.Text.RegularExpressions.Regex.IsMatch(s, "^[0-9]+$") AndAlso
s.Length >= 3 AndAlso
s.Length <= 6 Then
s = s.PadRight(6, "0")
Else
Throw New Exception("Invalid String!")
End If
TimeSpan.TryParseExact(s, "hhmmss", Globalization.CultureInfo.InvariantCulture, span)
Return span
End Function
And use it like this:
MessageBox.Show(GetTimeSpan("135700").ToString)
MessageBox.Show(GetTimeSpan("135").ToString)

Related

How can I get SignalR to stop changing my date/time values?

I have a simple class that contains a DateTime property. When I set the value of this property using DateTime.Now() the value is correct. However, when I pass this class object as a parameter via SignalR, on the receiving end SignalR has changed the DateTime so that it no longer matches the original DateTime. How can I get SignalR to stop manipulating my DateTime values? This issue seems to have started with a recent update to the latest SignalR nuget packages.
This seems to be a problem when the hub and the client are in two different time zones. It seems Microsoft is trying to help, by adjusting the date/time to the local time zone, but I want the original value, not the value Microsoft "thinks" I want.
When you want two systems to communicate with each other I would recommend using always the DateTime in UTC for various reasons. In your case you have two options here:
1 - Send the date as string string date = DateTime.Now.ToString(CultureInfo.InvariantCulture); so on the client side you just need to parse the datetime like DateTime.Parse(date, CultureInfo.InvariantCulture);.
2 - Send the date in UTC like DateTime.UtcNow; so event if the SignalR tries to change the date, it will have the DateTime.Kind as UTC. In this case or you will get the current date correctly, or you just adjust on the client side to the local time like receivedDate.ToLocalTime();
This one was a real head scratcher as I had the exact same issue. The client was storing the correct time but by the time it hit the Hub... it had changed. I'm really glad you posted this as I wouldn't have imagined this issue being possible. #Kiril1512 posted the correct resolution. In my case I used his second option as I didn't want to change my model... although simply converting to a string would have been simpler. While I did follow his suggestion and convert everything to DateTime.UtcNow()... I am thinking this was unnecessary as I noticed even previously stored dates converted correctly. This makes me think that either this isn't necessary to do, or dates are converted to Utc when they hit the Hub automatically which may be what the issue was to begin with?
Either way I posted this as I discovered that converting this date back to Local time was a little more involved. Here is how I ended up doing the conversion which resolved this issue for me that I gathered from this resource:
DateTime convertedDate = DateTime.SpecifyKind(
DateTime.Parse(msg.CreatedOn.ToString()),
DateTimeKind.Utc);
var kind = convertedDate.Kind;
DateTime dt = convertedDate.ToLocalTime();

Is the VB string function RIGHT$ still part of current VB.NET or is it left over from old vb?

I just found the below line of code in a project I am working on. I have never seen functions with the $
I found online that it is a vb string function. The page said the "Right$" is more efficient than simply writing "Right"
So is this still current with the most up to date vb language features or is it deprecated?
Right$(sNumToBeFormatted, 8)
I found online that it is a vb string function. The page said the "Right$" is more efficient than simply writing "Right"
VB6 had (and VBA still has) two versions of many string functions.
One version accepted and returned Strings, another one accepted and returned Variants. The string versions had $ in their name to make them stand out.
One cannot say that using Right$ is always better than using Right. It depends on the type of your source and result data.
If you receive data as Variants and send it out as Variants, like e.g. Excel does, using Right will result in fewer conversions between String and Variant.
If your data is originally a String, using Right$ is better.
So is this still current with the most up to date vb language features or is it deprecated?
VB.NET only includes the typed versions, but it does not show the $ anymore.
So Right$ is the up to date version, but it was renamed to simply Right. There is no choice anymore.
There is still choice in VBA, where both versions are valid and supported.
$ sign means that returned value of Right will be string
You can also do this
Dim someString$
which is equivalent to
Dim someString as String
For more go here
As to this question
So is this still current with the most up to date vb language features
or is it deprecated?
There is nothing stopping you from using it as it is supported, but because it is not popular at all it shouldn't be so next person reading code wont be going over it like you are at the moment.
This syntax was already optional in vb6.

ASP.Net - Function output shown before function called

I have the following line of code in ASP.Net (VB)
Response.Write("<td class=""tblRow""><strong>" & ITServiceRow.NAME & " </strong><br>" & funcRAGColour(ITServiceRow.RAGSTATUS) & Environment.NewLine)
This should output the Name from ITServiceRow.NAME followed by the result of the function funcRAGColour.
However this is not the case. ASP.Net is outputting the value of the function funcRAGColour. first followed by the value of ITServiceRow.NAME.
Just trying to understand why this might be happening? If I replace the function with static text it executes fine, but when I put the function in it outputs the function result immediately before the name.
The image here, in yellow shows the full output that comes from the function, it is shown before everything else?
Am I missing something obvious here?
Try using String.Format instead to guarantee placement.
Response.Write(string.Format("<td class=""tblRow""><strong>{0}</strong><br />{1}{2}</td>",funcRAGColour(ITServiceRow.RAGSTATUS),Environment.NewLine))
Always do whatever you can to avoid string concatenation. String concatenation is tough on a system and uses much more memory and resources to be garbage collected than you think because it's actually far more complicated. String.Format and StringBuilder help get around this.
I am very suspect of the function funcRAGColour() itself though and think that is the problem. My guess is the function is not returning the output as a string, but instead is using Response.Write() to output it's result. That would cause it's value to appear first since it is called while the string is being assembled.
Keep in mind, Response.Write is NOT the way to do things in ASP.Net. It was need in classic ASP, but ASP.Net has HtmlTextWriters that can be used during the rendering process, controls for result placement, etc.. It's the old school, non object-oriented way of doing things that can get into trouble.

non-standard value's for a new line in an asp.net textbox?

This is the strangest thing and I can not figure out how this is happening. Some how a user on my asp.net website is creating a multiline string but is not using the normal carriage return or linefeed.
I have tried to figure out how this is being accomplished.
It is a multiline textbox and when you press enter it goes to a new line.
In the aspx code I am using the following code to break the string into an array and count the lines in the array.
Dim text as String = txtMessage.Text.Trim
Dim Array as String() = text.split(vbNewLine)
Return Array.Length
I most normal situations when there is a line wrap it goes to the next line a CR/LF is entered and the code will break the string into a new line. Also pressing enter creates a new line and the split function works separating the lines and creates the dimensional array based on number of lines.
There is just one user that is some how creating a new line using a nonstandard CRLf. It is causing the split by vbnewline to not catch and break the string into an array. I have never seen this happen before.
I'm not asking how to fix this. I think I have a good idea how to keep this from happening by doing additional checks on the string through regex.
I am just completely puzzled as to how this is happening. If you have seen this before or have an idea of how this is accomplished then I would love to hear your thoughts.
Here are things I have tried: Inserting HTML into the string( didn't work )
: manually adding line breaks in the string such as \r, and using Hex codes to confuse the split function (didn't work)
:Injecting Script into the string(didn't work)
:Used access and excel to create strings without using a standard CRLF and copy and pasting (didn't work).
I have 5 yrs coding experience and am completely intrigued. Can you solve this?
What OS are you on? VbNewline is platform-dependent -- if your server is on Windows, that means \r\n. Since you're producing a web application, it's possible that not all of your users are on Windows -- and different OSes record line breaks differently -- they could well be VbCrLf (\r\n), VbLf (\n), or VbCr (\r), depending on whether your user is on Windows, Linux, or Mac respectively. You'll have to detect which one the user is transmitting and split your array on the appropriate combination of characters.
This answer from Karl Nicoll has more useful information for a user who experienced a very similar problem.

Downloading >10,000 rows from database table in asp.net

How should I go about providing download functionality on an asp.net page to download a series of rows from a database table represented as a linq2sql class that only has primitive types for members (ideally into a format that can be easily read by Excel)?
E.g.
public class Customer
{
public int CustomerID;
public string FirstName;
public string LastName;
}
What I have tried so far.
Initially I created a DataTable, added all the Customer data to this table and bound it to a DataGrid, then had a download button that called DataGrid1.RenderControl to an HtmlTextWriter that was then written to the response (with content type "application/vnd.ms-excel") and that worked fine for a small number of customers.
However, now the number of rows in this table is >10,000 and is expected to reach upwards of 100,000, so it is becoming prohibitive to display all this data on the page before the user can click the download button.
So the question is, how can I provide the ability to download all this data without having to display it all on a DataGrid first?
After the user requests the download, you could write the data to a file (.CSV, Excel, XML, etc.) on the server, then send a redirect to the file URL.
I have used the following method on Matt Berseth blog for large record sets.
Export GridView to Excel
If you have issues with the request timing out try increasing the http request time in the web.config
Besides the reasonable suggestion to save the data on server first to a file in one of the answers here, I would like to also point out that there is no reason to use a DataGrid (it’s one of you questions as well). DataGrid is overkill for almost anything. You can just iterate over the records, and save them directly using HtmlTextWriter, TextWriter (or just Response.Write or similar) to the server file or to a client output stream. It seems to me like an obvious answer, so I must be missing something.
Given the number of records, you may run into a number of problems. If you write directly to the client output stream, and buffer all data on server first, it may be a strain on the server. But maybe not; it depends on the amount of memory on the serer, the actual data size and how often people will be downloading the data. This method has the advantage of not blocking a database connection for too long. Alternatively, you can write directly to the client output stream as you iterate. This may block the database connection for too long as it depends on the download speed of the client. But again; it your application is of a small or medium size (in audience) then anything is fine.
You should definitely check out the FileHelpers library. It's a freeware, excellent utility set of classes to handle just this situation - import and export of data, from text files; either delimited (like CSV), or fixed width.
It offer a gazillion of options and ways of doing things, and it's FREE, and it works really well in various projects that I'm using it in. You can export a DataSet, an array, a list of objects - whatever it is you have.
It even has import/export for Excel files, too - so you really get a bunch of choices.
Just start using FileHelpers - it'll save you so much boring typing and stuff, you won't believe it :-)
Marc
Just a word of warning, Excel has a limitation on the number of rows of data - ~65k. CSV will be fine, but if your customers are importing the file into Excel they will encounter that limitation.
Why not allow them to page through the data, perhaps sorting it before paging, and then give them a button to just get everything as a cvs file.
This seems like something that DLinq would do well, both the paging, and writing it out, as it can just fetch one row at a time, so you don't read in all 100k rows before processing them.
So, for cvs, you just need to use a different LINQ query to get all of the rows, then start to save them, separating each cell by a separator, generally a comma or tab. That could be something picked by the user, perhaps.
OK, I think you are talking too many rows to do a DataReader and then loop thru to create the cvs file. The only workable way will be to run:
SQLCMD -S MyInstance -E -d MyDB -i MySelect.sql -o MyOutput.csv -s
For how to run this from ASP.Net code see here. Then once that is done, your ASP.Net page will continue with:
string fileName = "MyOutput.csv";
string filePath = Server.MapPath("~/"+fileName);
Response.Clear();
Response.AppendHeader("content-disposition",
"attachment; filename=" + fileName);
Response.ContentType = "application/octet-stream";
Response.WriteFile(filePath);
Response.Flush();
Response.End();
This will give the user the popup to save the file. If you think more than one of these will happen at a time you will have to adjust this.
So after a bit of research, the solution I ended up trying first was to use a slightly modified version of the code sample from http://www.asp.net/learn/videos/video-449.aspx and format each row value in my DataTable for CSV using the following code to try to avoid potentially problematic text:
private static string FormatForCsv(object value)
{
var stringValue = value == null ? string.Empty : value.ToString();
if (stringValue.Contains("\"")) { stringValue = stringValue.Replace("\"", "\"\""); }
return "\"" + stringValue + "\"";
}
For anyone who is curious about the above, I'm basically surrounding each value in quotes and also escaping any existing quotes by making them double quotes. I.e.
My Dog => "My Dog"
My "Happy" Dog => "My ""Happy"" Dog"
This appears to be doing the trick for now for small numbers of records. I will try it soon with the >10,000 records and see how it goes.
Edit: This solution has worked well in production for thousands of records.

Resources