combining two textbox values - asp.net

i called a field from mysql into a readonly textarea and i made another textbox to allow users to add fields into the textarea. how do I combine the values from the textbox into the textarea?
an example of what i want to do is:
textarea
15/12: Nothing special today
16/12: another day
17/12: and so on
textbox
this is a new input
Result
15/12: Nothing special today
16/12: another day
17/12: and so on
18/12: this is a new input
The textarea is "log1" and the textbox is "txb1". I'm currently using
log = trim(request.form("log1"))
how do I do something like
log = trim(request.form("log1")) <br> date ": " trim(request.form("txb1"))

assuming date is a string variable, You would want to do the following:
log = trim(request.form("log1")) & "<br>" & [date] & ": " & trim(request.form("txb1"))
also, if date is a DateTime variable, you would want to use date.ToShortDateString() and instead of <br/> i would recommend using Environment.NewLine
and even better, you should use StringBuilder:
Dim SB As New StringBuilder()
SB.AppendLine(trim(request.form("log1")))
SB.AppendLine([date] & ": " & trim(request.form("txb1")))
log = SB.ToString()
UPDATE:
if you want to store the entire log in one record rather than a separate table, you better off saving it as a list of logs into a varbinary(MAX) column.
here is a full example of how to do it:
1. we start by creating a <div> element that will hold our pretty logs and will be handled by the server, and a text box for new logs:
<asp:TextBox ID="txb1" runat="server"></asp:TextBox>
<div id="Text_Div1" runat="server"></div>
2. now in the code behind, we create a class to hold 1 single line of log:
'create a log class and state that it serializable
<Serializable> _
Public Class MyLogRecord
Public Sub New(_msg As String)
[Date] = DateTime.Now
Message = _msg
End Sub
Public Property [Date]() As DateTime
Get
Return m_Date
End Get
Set
m_Date = Value
End Set
End Property
Private m_Date As DateTime
Public Property Message() As [String]
Get
Return m_Message
End Get
Set
m_Message = Value
End Set
End Property
Private m_Message As [String]
Public Function ToText() As String
Return [Date].ToShortDateString() & ": " & Convert.ToString(Message)
End Function
End Class
3. wherever you update the logs, whether its button_click or textbox_keydown, you do the following:
' create a list of logs
Dim MyLogs As List(Of MyLogRecord)
'check if we stored the logs already in the session,
'if yes, retrieve it from the session var,
'if not then create a new one.
If Session("MyLogs") IsNot Nothing Then
MyLogs = DirectCast(Session("MyLogs"), List(Of MyLogRecord))
Else
MyLogs = New List(Of MyLogRecord)()
End If
' create a new log record from the new textbox value
Dim _tempLog As New MyLogRecord(txb1.Text)
'add the new log to the list
MyLogs.Add(_tempLog)
'save it back in a session var:
Session("MyLogs") = MyLogs
4. in the part where you save the logs to the mysql db, you do it this way: first convert the list to a byte array and store it in a varbinary(MAX) column
'create a new binary formatter, include System.Runtime.Serialization.Formatters.Binary;
Dim formatter As New BinaryFormatter()
'create a byte array to store our logs list
Dim _logsBinary As Byte()
'create a memory stream to write the logs list into
Using _logStream As New MemoryStream()
'use the formatter to serialize the list in to an array of bytes
'directly into the memory stream
formatter.Serialize(_logStream, MyLogs)
'dump the memory stream into the byte array
_logsBinary = _logStream.ToArray()
End Using
' ... save the _logsBinary into mysql as a 'varbinary(max)' ...
5. in the place where you retrieve the logs from the mysql db, you de-serialize the byte array back to a logs list:
Dim MyLogs As New List(Of MyLogRecord)()
Dim formatter As New BinaryFormatter()
Using _logStream As New MemoryStream()
_logStream.Write(_logsBinary, 0, _logsBinary.Length)
_logStream.Position = 0
' de-serialize the byte array back into a logs list
MyLogs = DirectCast(formatter.Deserialize(_logStream), List(Of MyLogRecord))
End Using
6. in the place where you write the logs in your page, you do it this way:
Dim SB As New StringBuilder()
' create a temp date to compare against all the records,
' and initialize it with the first value or else you will have
' a orizontal line before the first row
Dim _prevDate As DateTime = MyLogs.First().[Date]
For Each _logRec As MyLogRecord In MyLogs
'take the date of the currently iterrated item and
'compare against the temp date, note that comparing months is not enough,
'month might be same/earlier but year can be higher
Dim _currentDate As DateTime = _logRec.[Date]
If _currentDate.Month > _prevDate.Month OrElse _currentDate.Year > _prevDate.Year Then
'append horizontal line
SB.AppendLine("<hr/>")
'update temp value
_prevDate = _currentDate
End If
'finally append the log: ToText() is the class custom
'function that we created above
SB.AppendLine(_logRec.ToText())
Next
'dump the logs into the server managed div:
Text_Div1.InnerHtml = SB.ToString()

Related

Website won't release file generated with openxml

Here is the situation:
Asp.Net Web Forms site using Open XML to read in a (via a stream) word document (docx). I then insert some text into the document and then write the file back out to a different location. It is then emailed to an end user. All of this works great.
The problem i am running into is that I can't the new file written by the site. I receive the following error:
"The process cannot access the file (file name here) because it is being used nt another process"
I have confirmed that it is the site (or IIS) that is holding on to the file.
Here is the code that reads the original file and generates the new file:
Private Function GetDocument(worddoc As String) As Integer
Dim byteArray As Byte() = File.ReadAllBytes("\\WEB-DEV-1\HR_Documents\" & worddoc)
Using Stream As New MemoryStream()
Stream.Write(byteArray, 0, CInt(byteArray.Length))
Try
'Set Row & Cell variables
Dim rowNum As Integer = 0
Dim cellNum As Integer = 0
'Set File Stream
Using doc As WordprocessingDocument = WordprocessingDocument.Open(Stream, True)
'Employee Name Insert
'Find first table in document
Dim tbl1 As Table = doc.MainDocumentPart.Document.Body.Elements(Of Table).First()
'First Row in tbl
Dim row As TableRow = tbl1.Elements(Of TableRow)().ElementAt(0)
'Find first cell in row
Dim cell As TableCell = row.Elements(Of TableCell)().ElementAt(0)
'Insert selected Employee Name
Dim p As Paragraph = cell.Elements(Of Paragraph)().First()
Dim r As Run = p.Elements(Of Run)().First()
Dim txt As Text = r.Elements(Of Text)().First()
txt.Text = "Employee Name: " & ddlEmployeeList.SelectedItem.Text
'Supervisor Name Insert
'Check for form
If ddlFormChoice.SelectedIndex <> 2 Then
'Reset row to supervisors row in table
row = tbl1.Elements(Of TableRow)().ElementAt(1)
ElseIf ddlFormChoice.SelectedIndex = 2 Then
'Reset row to supervisors row in table
row = tbl1.Elements(Of TableRow)().ElementAt(2)
End If
If ddlFormChoice.SelectedIndex <> 2 Then
'Reset cell to supervisor cell in row
cell = row.Elements(Of TableCell)().ElementAt(1)
ElseIf ddlFormChoice.SelectedIndex = 2 Then
'Reset cell to supervisor cell in row
cell = row.Elements(Of TableCell)().ElementAt(0)
End If
'Insert selected Employee Name
p = cell.Elements(Of Paragraph)().First()
r = p.Elements(Of Run)().First()
txt = r.Elements(Of Text)().First()
If ddlFormChoice.SelectedIndex <> 2 Then
txt.Text = "Supervisor: " & ddlSupervisorList.SelectedItem.Text
ElseIf ddlFormChoice.SelectedIndex = 2 Then
txt.Text = "Manager/Supervisor: " & ddlSupervisorList.SelectedItem.Text
End If
doc.Close()
End Using
'Save File to temp location
File.WriteAllBytes("\\WEB-DEV-1\HR_Documents\TempDocs\" & worddoc, Stream.ToArray())
Stream.Close()
Stream.Dispose()
Return 1
Catch ex As Exception
Return Nothing
End Try
End Using
End Function
I close the OpenXML doc and the stream as well dispose of the stream but when I try to delete the file from the main sub that called the function I get the error listed above.
What am I missing?? I closed the doc, the stream and disposed of the stream. Why is the site still holding the file?
Note here the line of code that trys to delete the file;
File.Delete("\\Web-Dev-1\HR_Documents\TempDocs\" & fileAttach)
So after most of the day i finally found out what the problem was. After the document was created, saved , and emailed it was being held by the email method. For some reason i thought that when the method finishes that it disposed of the Mail Message but this not the case.
Once I added the dispose line it all worked fine.
Only been Googling for almost two days. :|

Can i use a single session variable to store all the field values

I have 9 pages with 10 fields in each page. Can i use a single session variable to store all the field(textbox,drop downlist,radiobuttons) values of 9 pages? If so could you give me small example inorder to proceed. Im kind of stuck.
Could you? Yes. Should you? Most likely not - though I can't say for sure without understanding what problem you are intending to solve.
Update with one sample solution
OK, I'm going to assume you want to store the values from the controls and not the controls themselves. If so, the easiest solution is stuff them in using some meaningful token to separate them. Like:
Session("MyControlValueList") = "name='txt1',value='hello'|name='txt2', value'world'"
To retrieve you would split them into a string array:
myArray = Session("MyControlValueList").Split("|")
And then iterate through to find the control/value you want.
So strictly speaking that's an answer. I still question whether it is the best answer for your particular scenario. Unfortunately I can't judge that until you provide more information.
Create a custom class with all the fields you want to save, then populate an instance of that and save that instance as a session variable.
I have something similar, but not identical - I'm saving various shipping address fields for an order, and I'm allowing the admins to update the order, either the shipping information or the order line items. Since that information is kept on separate tables, I store the shipping information in a session variable, and then compare it to what's on the form when they hit the "Update" button. If nothing has changed, I skip the update routine on the SQL Server database.
The easiest way for me to do this was to create a "OrderInfo" class. I saved the shipping information to this class, then saved that class to a session variable. Here's the code showing the class -
Public Class OrderInfo
Private v_shipname As String
Private v_add1 As String
Private v_add2 As String
Private v_city As String
Private v_state As String
Private v_zipcd As String
Private v_dateneeded As Date
Private v_billingmeth As Integer
Public Property ShipName() As String
Get
Return v_shipname
End Get
Set(value As String)
v_shipname = value
End Set
End Property
Public Property Add1() As String
Get
Return v_add1
End Get
Set(value As String)
v_add1 = value
End Set
End Property
Public Property Add2() As String
Get
Return v_add2
End Get
Set(value As String)
v_add2 = value
End Set
End Property
Public Property City() As String
Get
Return v_city
End Get
Set(value As String)
v_city = value
End Set
End Property
Public Property State() As String
Get
Return v_state
End Get
Set(value As String)
v_state = value
End Set
End Property
Public Property ZipCd() As String
Get
Return v_zipcd
End Get
Set(value As String)
v_zipcd = value
End Set
End Property
Public Property DateNeeded() As Date
Get
Return v_dateneeded
End Get
Set(value As Date)
v_dateneeded = value
End Set
End Property
Public Property BillingMeth() As Integer
Get
Return v_billingmeth
End Get
Set(value As Integer)
v_billingmeth = value
End Set
End Property
End Class
Here's the code for when I tested the concept to see if I could store a custom class in a session variable. This routine gets the order record, populates the fields in an instance of the custom class, and on the web form, as well. I save that instance to a session variable, then I initialize another new instance of that custom class, load the session variable to it. I then display the field values from the "retrieved" custom class, and what showed on the label matched what it should be -
Protected Sub LoadOrderInfo(ByVal ordID As Integer)
Dim connSQL As New SqlConnection
connSQL.ConnectionString = ConfigurationManager.ConnectionStrings("sqlConnectionString").ToString
Dim strProcName As String = "uspGetOrderInfoGeneral"
Dim cmd As New SqlCommand(strProcName, connSQL)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("OrderID", ordID)
If connSQL.State <> ConnectionState.Open Then
cmd.Connection.Open()
End If
Dim drOrderInfo As SqlDataReader
drOrderInfo = cmd.ExecuteReader
If drOrderInfo.Read Then
Dim orgOrder As New OrderInfo
orgOrder.ShipName = drOrderInfo("shipName")
orgOrder.Add1 = drOrderInfo("ShipAdd1")
orgOrder.Add2 = drOrderInfo("ShipAdd2")
orgOrder.City = drOrderInfo("ShipCity")
orgOrder.State = drOrderInfo("ShipState")
orgOrder.ZipCd = drOrderInfo("ShipZip")
orgOrder.DateNeeded = drOrderInfo("DateNeeded")
orgOrder.BillingMeth = drOrderInfo("BillingMethodID")
If Session.Item("orgOrder") Is Nothing Then
Session.Add("orgOrder", orgOrder)
Else
Session.Item("orgOrder") = orgOrder
End If
' I could just as easily populate the form from the class instance here
txtShipName.Text = drOrderInfo("shipName")
txtAdd1.Text = drOrderInfo("ShipAdd1")
txtAdd2.Text = drOrderInfo("ShipAdd2")
txtCity.Text = drOrderInfo("ShipCity")
txtState.Text = drOrderInfo("ShipState")
txtZipCd.Text = drOrderInfo("ShipZip")
selDate.Value = drOrderInfo("DateNeeded")
ddlBillMeth.SelectedValue = drOrderInfo("BillingMethodID")
End If
cmd.Connection.Close()
Dim retOrder As New OrderInfo
retOrder = Session.Item("orgOrder")
lblWelcomeMssg.Text = retOrder.ShipName & ", " & retOrder.Add1 & ", " & retOrder.City & ", " & retOrder.DateNeeded.ToShortDateString & ", " & retOrder.BillingMeth.ToString
End Sub
This might not be practical or desirable, given the number of fields you are trying to hold onto that way, but I'm not here to judge, so this is one possibility. I've worked with other projects where you create a table, and save that table as a session variable, so whatever structure you put into an object is retained if you save that object as a session variable.

How does one set a property of a JsonObject dynamically?

I am using a method of passing Json to and from my markup using jquery and ajax. This can be described in more detail on this page: http://blogs.telerik.com/aspnet-ajax/posts/12-04-27/the-present-and-future-of-using-json-in-webforms.aspx
In this snippet of code, I try to set the object's value dynamically by setting a string variable named "test" to a business object's value:
Dim objOrder As Object = New JsonObject()
For Each Order As BoVendorOrder In Orders
Dim Vendor As New BoVendor(Order.VendorID)
Dim test As String = Order.VendorOrderID
objOrder.test = Vendor.VendorName + " - " + Order.VendorOrderPoNumber
Next
I left out some code for the sake of brevity. The goal is to get the objOrder.test to be equal to the VendorOrderID (a number in our SQL database) so that the JSON looks like this:
{
"123456": "VendorName - PONumber",
"678901": "VendorName - PONumber"
}
Any of you guys out there know how to do this?
Do you really need the order IDs to be properties of the object? It might be easier to just return a serialized Dictionary(Of String, String). You could still look up by order ID and it would be easier to loop over than the props of the Javascript object.
Here's an example of what you'd need to do using the dictionary approach:
Dim OrdersDict as New Dictionary(Of String, String)()
For Each Order as BoVendorOrder In Orders
If Not OrdersDict.ContainsKey(Order.VendorOrderID) Then
OrdersDict.Add(Order.VendorOrderID, Vendor.VendorName + " - " + Order.VendorOrderPoNumber)
End If
Next
' Serialize the dictionary object to JSON
' Using System.Web.Script.Serialization.JavascriptSerializer:
Dim Serializer As New JavaScriptSerializer
If MaxLength Then Serializer.MaxJsonLength = Int32.MaxValue
Dim x as String = Serializer.Serialize(OrdersDict) 'Return or response.write x as needed
'or
'Using JSON.net
Dim x as String = JsonConvert.SerializeObject(OrdersDict) 'Return or response.write x as needed

Decrypt a field from SQL Server via VB.NET and display in DataGridView

I am trying to decrypt two string fields that were encrypted upon insertion into the database.
They are simply name fields, so no, I won't be checking against a hashed password to ensure validity. I actually need to see the names.
The decryption method I am trying to use is from Microsoft (http://msdn.microsoft.com/en-us/library/ms172831.aspx) and works perfectly.
Say the user is searching for someone by first name or last name. How do I use the function to return plain text in the GridView?
See below:
SearchFirsttxt.Text = eFirst
SearchLastTxt.Text = eLast
If SearchFirsttxt.Text = "" Then
SqlCommand.CommandText = "Select * FROM PARTICIPANT WHERE LAST_NM_TXT = '" & eLast & "';"
ElseIf SearchLastTxt.Text = "" Then
SqlCommand.CommandText = "Select * FROM PARTICIPANT WHERE FIRST_NM_TXT = '" & eFirst & "';"
Else
SqlCommand.CommandText = "Select * FROM PARTICIPANT WHERE FIRST_NM_TXT = '" & eFirst & "' and LAST_NM_TXT = '" & eLast & "';"
End If
'SQL Command returns rows where values in database and textboxes are equal
dFirst = clsEncrypt.DecryptData(eFirst)
dLast = clsEncrypt.DecryptData(eLast)
SearchFirsttxt.Text = dFirst
SearchLastTxt.Text = dLast
Dim myAdapter As New SqlDataAdapter(SqlCommand) 'holds the data
myAdapter.Fill(dt) 'datatable that is populated into the holder (DataAdapter)
DataGridView1.DataSource = dt 'Assigns source of information to the gridview (DataTable)
SQLConnection.Close() 'Closes Connection for security measures
It all depends on how you are retrieving the data from your DB.
If you're populating a collection of your class, I'd extend the class to have a property that decrypts the field. So if you're encrypted column is called Name, I'd create a read only property called NameDecrypted that runs your decryption routine on the encrypted Name property.
If you're executing SQL directly via something like a stored procecure, you could do it via a binding event on the grid. I'm not sure what grid product you're using but the one we use has an event that is fired when a cell is bound to the datasource. You could then decrypt the encrypted value that is in the grid.
Here's what I used, which is just modified code from: How do I Iterate Through DataTable and Decrypt a field?
For i As Integer = 0 To dt.Rows.Count - 1
dt.Rows(i)("FIRST_NM_TXT") = clsEncrypt.DecryptData(dt.Rows(i)("FIRST_NM_TXT"))
dt.Rows(i)("LAST_NM_TXT") = clsEncrypt.DecryptData(dt.Rows(i)("LAST_NM_TXT"))
Next
I assume the ("FIRST_NM_TXT") must be the Column name of the particular field you're wanting to loop through and decrypt.
Edit: The format could also be dt.Rows(i)("Index"), not just ColumnName
For Each row As DataGridViewRow In DatagridView1.Rows
DatagridView1.Rows(0).Cells(0).Value = Encrypt(row.Cells("Password").Value.ToString)
Next
Here is the code for Encrypt()
Public Function Encrypt(ByVal clearText As String) As String
Dim EncryptionKey As String = "MAKV2SPBNI99212"
Dim clearBytes As Byte() = Encoding.Unicode.GetBytes(clearText)
Using encryptor As Aes = Aes.Create()
Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, _
&H65, &H64, &H76, &H65, &H64, &H65, _
&H76})
encryptor.Key = pdb.GetBytes(32)
encryptor.IV = pdb.GetBytes(16)
Using ms As New MemoryStream()
Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
cs.Write(clearBytes, 0, clearBytes.Length)
cs.Close()
End Using
clearText = Convert.ToBase64String(ms.ToArray())
End Using
End Using
Return clearText
End Function

How to deal with SqlDataReader null values in VB.net

I have the follwoing code that performs a query and returns a result. However, I looked around and found some examples to take care of null values but I get an error: "Invalid attempt to read when no data is present." I also got the error: "Conversion from type 'DBNull' to type 'Decimal' is not valid."
Can someone help me out with this code to prevent null values from crashing my program?
Private Sub EFFICIENCY_STACKRANK_YTD(ByVal EMPLOYEE As String)
Dim queryString As String = "SELECT " & _
" (SELECT CAST(SUM(TARGET_SECONDS) AS DECIMAL)/ CAST(SUM(ROUTE_SECONDS) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN WITH(NOLOCK) WHERE APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & EMPLOYEE & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1) AS RESULT1" & _
" FROM dbo.APE_BUSDRIVER_MAIN "
Using connection As New SqlConnection(SQLConnectionStr)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
If reader.Read Then
RESULT1 = reader("RESULT1")
Else
RESULT1 = 0
End If
End Using
End Sub
You have opened the reader, but have not asked it to actually read anything.
After this line:
Dim reader As SqlDataReader = command.ExecuteReader()
add
If reader.Read() Then
and wrap the result reading into this if statement, i.e.
If reader.Read() Then
Dim index As Integer = reader.GetOrdinal("RESULT1")
If reader.IsDBNull(index) Then
RESULT1 = String.Empty
Else
RESULT1 = reader(index)
End If
End If
Note that this works because your SQL should only return a single record. In the event that you were reading multiple records, you would need to call the Read statement in a loop until there were no more records, i.e.
Do While reader.Read()
Loop
I wanted to provide another, more-advanced, answer as an option. Many classes can be extended in .NET like this.
If you are regularly performing "Is NULL" checks like this in your applications, you can choose to extend the DataReader class once to have additional functions available everywhere in your application. Here is an example that creates an extension called "ReadNullAsString()" onto the data reader class. This makes a function that always returns String.Empty when a DbNull is encountered.
Part 1, place this module code in a new class file in App_Code if application is a website, otherwise place where ever you prefer. There are two overloads, one for the field's ordinal position (aka index), and one for the field's ColumnName.
Public Module DataReaderExtensions
''' <summary>
''' Reads fieldName from Data Reader. If fieldName is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadNullAsEmptyString(ByVal reader As IDataReader, ByVal fieldName As String) As String
If IsDBNull(reader(fieldName)) Then
Return String.Empty
Else
Return reader(fieldName)
End If
Return False
End Function
''' <summary>
''' Reads fieldOrdinal from Data Reader. If fieldOrdinal is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadString(ByVal reader As IDataReader, ByVal fieldOrdinal As Integer) As String
If IsDBNull(reader(fieldOrdinal)) Then
Return ""
Else
Return reader(fieldOrdinal)
End If
Return False
End Function
End Module
Step 2, call the new extension like so:
' no need to check for DbNull now, this functionality is encapsulated in the extension module.
RESULT1 = reader.ReadNullAsEmptyString(index)
'or
RESULT1 = reader.ReadNullAsEmptyString("RESULT1")

Resources