DTD validation issue - vb.net

I'm using the following code to validate an XML file:
'DTD validation
Dim doc As XmlDocument = New XmlDocument()
Dim dtdDoc As String = ftpPath & "\" & dtdDocument
AppendText(vbCrLf)
Try
doc.Load(fileName)
Catch ex As Exception
AppendText(ex.Message)
ShowFailMessage()
End Try
Dim isXmlValid As Boolean = True
Dim xmlValMsg As New StringBuilder()
Dim sw As New StringWriter()
doc.Save(sw)
doc.Save(fileName)
Dim stream As Stream = New FileStream(fileName, FileMode.Open)
Dim settings As New XmlReaderSettings()
settings.ValidationType = ValidationType.DTD
settings.DtdProcessing = DtdProcessing.Parse
AddHandler settings.ValidationEventHandler, AddressOf ValidationCallBack
Dim r As XmlReader = XmlReader.Create(stream, settings, "R:\ftproot\graphics\" & dtdDocument)
While r.Read()
End While
r.Close()
stream.Close()
stream.Dispose()
Private Shared Sub ValidationCallBack(sender As Object, e As ValidationEventArgs)
AppendText("DTD Validation Error: " & e.Message)
isDTDValidated = False
End Sub
I am getting the following error from this validation code:
"The element 'MarketDate' has invalid child element 'Date'. List of possible elements expected: 'DateFormat'."
Here's the relevant XML:
<MarketDate>
<MarketDateRole>01</MarketDateRole>
<Date>20150202</Date>
</MarketDate>
Here's what's in the DTD:
<!ELEMENT MarketDate (MarketDateRole,DateFormat,Date)>
So 'Date' is a valid child element. I am guessing it's not that Date is invalid but that DateFormat is missing. Am I correct with this assumption?

Related

VB.net Crystal report export to html and send as html mail body using outlook

I am trying to send contents of a crystal report as email body using outlook application.
Here is my code in VB.net
Imports outlook = Microsoft.Office.Interop.Outlook
Dim a As String = something.ConnectionString
Dim cryRpt As ReportDocument
Dim username As String = a.Split("=")(3).Split(";")(0) 'get username
Dim password As String = a.Split("=")(4).Split(";")(0) 'get password
cryRpt = New ReportDocument()
Dim Path As String = Application.StartupPath
Dim svPath As String = Application.StartupPath & "\PDF"
If Not Directory.Exists(svPath) Then
Directory.CreateDirectory(svPath)
End If
cryRpt.Load(Path & "\Reports\dr.rpt")
CrystalReportViewer1.ReportSource = cryRpt
cryRpt.SetDatabaseLogon(username, password)
CrystalReportViewer1.Refresh()
Dim myExportOptions As ExportOptions
myExportOptions = cryRpt.ExportOptions
myExportOptions.ExportDestinationType = ExportDestinationType.DiskFile
myExportOptions.ExportFormatType = ExportFormatType.HTML40 'i tried HTML32 also
Dim html40FormatOptions As HTMLFormatOptions = New HTMLFormatOptions()
html40FormatOptions.HTMLBaseFolderName = svPath
html40FormatOptions.HTMLFileName = "dr.htm"
html40FormatOptions.HTMLEnableSeparatedPages = False
html40FormatOptions.HTMLHasPageNavigator = False
html40FormatOptions.UsePageRange = False
myExportOptions.FormatOptions = html40FormatOptions
cryRpt.Export()
Try
Dim oApp As outlook.Application
oApp = New outlook.Application
Dim oMsg As outlook.MailItem
oMsg = oApp.CreateItem(outlook.OlItemType.olMailItem)
oMsg.Subject = txtSubject.Text
oMsg.BodyFormat = outlook.OlBodyFormat.olFormatHTML
oMsg.HTMLBody = ""
oMsg.HTMLBody = getFileAsString(svPath & "\PoPrt\QuotPrt.html")
oMsg.To = txtEmailId.Text
Dim ccArray As New List(Of String)({txtCC1.Text, txtCC2.Text, txtCC3.Text})
Dim cclis As String = String.Join(",", ccArray.Where(Function(ss) Not String.IsNullOrEmpty(ss)))
oMsg.CC = cclis
oMsg.Display(True)
Catch ex As Exception
MsgBox("Something went wrong", vbExclamation)
End Try
SvFormPanel3.Visible = False
the function
Private Function getFileAsString(ByVal file As String) As String
Dim reader As System.IO.FileStream
Try
reader = New System.IO.FileStream(file, IO.FileMode.Open)
Catch e As Exception
MsgBox("Something went wrong. " + e.Message, vbInformation)
End Try
Dim resultString As String = ""
Dim b(1024) As Byte
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Do While reader.Read(b, 0, b.Length) > 0
resultString = resultString & temp.GetString(b)
Array.Clear(b, 0, b.Length)
Loop
reader.Close()
Return resultString
End Function
The report will get exported to the specified location as html. And when we manually open that html file it displays perfectly with border lines and all.
But when its getting added as html body of outlook application, the formatting will be gone, and looks scattered.
can anyone help
Did you try this?
Open outlook, go to, File>Options>Mail
go to section MessageFormat and untick "Reduce message size by removing format..."
I have solved the issue by exporting it into PDF and then convert to Image and embed in email body.

vb.net proper way to thread this application

My application is a web scraper (for the most part) that stores information in a database. I have 2 classes so far:
clsSpyder - This essentially rolls-up the scraper processes
clsDB - This does any database processes
My test program looks over all the URLs, scrapes, pushes into the database. It is pretty simple sequentially, but I would like to have say N number of threads running those processes (scrape and store). My sequential code is this:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
'Grab List
Dim tDS As New DataSet
Dim tDB As New clsTermsDB
Dim tSpyder As New clsAGDSpyder
Dim sResult As New TermsRuns
'Grab a list of all URLS
tDS = tDB.GetTermsList(1)
Try
For Each Row As DataRow In tDS.Tables(0).Rows
rtbList.AppendText(Row("url_toBeCollected") & vbCrLf)
sResult = tSpyder.SpiderPage(Row("url_toBeCollected"))
'If nothing is found, do not store
If sResult.html <> "" And sResult.text <> "" Then
tDB.InsertScrape(Now(), sResult.html, sResult.text, Row("url_uid"), 1)
End If
Next
Exit Sub
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
With that in mind and noting that I am passing variables to the SpiderPage and InsertScrape methods.. How could I implement threading? It's gotta be simple, but I feel like I have been googling and trying things for days without success :(
*** ADDED: SpiderPage method:
Public Function SpiderPage(PageURL As String) As TermsRuns
Dim webget As New HtmlWeb
Dim node As HtmlNode
Dim doc As New HtmlDocument
Dim docNOHTML As HtmlDocument
Dim uri As New Uri(PageURL)
Dim wc As HttpWebRequest = DirectCast(WebRequest.Create(uri.AbsoluteUri), HttpWebRequest)
Dim wcStream As Stream
wc.AllowAutoRedirect = True
wc.MaximumAutomaticRedirections = 3
'Set Headers
wc.UserAgent = "Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4"
wc.Headers.Add("REMOTE_ADDR", "66.83.101.5")
wc.Headers.Add("HTTP_REFERER", "66.83.101.5")
'Set HTMLAgility Kit Useragent Spoofing (not needed, I don't think)
webget.UserAgent = "Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4"
'Certification STuff
wc.UseDefaultCredentials = True
wc.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
'Create Cookie Jar
Dim CookieJar As New CookieContainer
wc.CookieContainer = CookieJar
'Keep Alive Settings
wc.KeepAlive = True
wc.Timeout = &H7530
'Read the web page
Dim wr As HttpWebResponse = Nothing
Try
wcStream = wc.GetResponse.GetResponseStream
doc.Load(wcStream)
'Remove HTML from the document
docNOHTML = RemoveUnWantedTags(doc)
'Grab only the content inside the <body> tag
node = docNOHTML.DocumentNode.SelectSingleNode("//body")
'Output
SpiderPage = New TermsRuns
SpiderPage.html = node.InnerHtml
SpiderPage.text = node.InnerText
Return SpiderPage
Catch ex As Exception
'Something goes here when scraping returns an error
SpiderPage = New TermsRuns
SpiderPage.html = ""
SpiderPage.text = ""
End Try
End Function
*** Added InsertScrape:
Public Function InsertScrape(scrape_ts As DateTime, scrape_html As String, scrape_text As String, url_id As Integer, tas_id As Integer) As Boolean
Dim myCommand As MySqlClient.MySqlCommand
Dim dt As New DataTable
'Create ds/dt for fill
Dim ds As New DataSet
Dim dtbl As New DataTable
Try
'Set Connection String
myConn.ConnectionString = myConnectionString
'Push Command to Client Object
myCommand = New MySqlClient.MySqlCommand
myCommand.Connection = myConn
myCommand.CommandText = "spInsertScrape"
myCommand.CommandType = CommandType.StoredProcedure
myCommand.Parameters.AddWithValue("#scrape_ts", scrape_ts)
myCommand.Parameters("#scrape_ts").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#scrape_html", scrape_html)
myCommand.Parameters("#scrape_html").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#scrape_text", scrape_text)
myCommand.Parameters("#scrape_text").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#url_id", url_id)
myCommand.Parameters("#url_id").Direction = ParameterDirection.Input
myCommand.Parameters.AddWithValue("#tas_id", tas_id)
myCommand.Parameters("#tas_id").Direction = ParameterDirection.Input
'Open Connection
myConn.Open()
myCommand.ExecuteNonQuery()
'Close Connection
myConn.Close()
InsertScrape = True
Catch ex As Exception
'Put Message Here
InsertScrape = False
MessageBox.Show(ex.Message)
End Try
End Function
thanks in advance.

VB.Net Merge multiple pdfs into one and export

I have to merge multiple PDFs into a single PDF.
I am using the iText.sharp library, and collect converted the code and tried to use it (from here)
The actual code is in C# and I converted that to VB.NET.
Private Function MergeFiles(ByVal sourceFiles As List(Of Byte())) As Byte()
Dim mergedPdf As Byte() = Nothing
Using ms As New MemoryStream()
Using document As New Document()
Using copy As New PdfCopy(document, ms)
document.Open()
For i As Integer = 0 To sourceFiles.Count - 1
Dim reader As New PdfReader(sourceFiles(i))
' loop over the pages in that document
Dim n As Integer = reader.NumberOfPages
Dim page As Integer = 0
While page < n
page = page + 1
copy.AddPage(copy.GetImportedPage(reader, page))
End While
Next
End Using
End Using
mergedPdf = ms.ToArray()
End Using
End Function
I am now getting the following error:
An item with the same key has already been added.
I did some debugging and have tracked the problem down to the following lines:
copy.AddPage(copy.GetImportedPage(reader,
copy.AddPage(copy.GetImportedPage(reader, page)))
Why is this error happening?
I have a console that monitors individual folders in a designated folder then needs to merge all of the pdf's in that folder into a single pdf. I pass an array of file paths as strings and the output file i would like.
This is the function i use.
Public Shared Function MergePdfFiles(ByVal pdfFiles() As String, ByVal outputPath As String) As Boolean
Dim result As Boolean = False
Dim pdfCount As Integer = 0 'total input pdf file count
Dim f As Integer = 0 'pointer to current input pdf file
Dim fileName As String
Dim reader As iTextSharp.text.pdf.PdfReader = Nothing
Dim pageCount As Integer = 0
Dim pdfDoc As iTextSharp.text.Document = Nothing 'the output pdf document
Dim writer As PdfWriter = Nothing
Dim cb As PdfContentByte = Nothing
Dim page As PdfImportedPage = Nothing
Dim rotation As Integer = 0
Try
pdfCount = pdfFiles.Length
If pdfCount > 1 Then
'Open the 1st item in the array PDFFiles
fileName = pdfFiles(f)
reader = New iTextSharp.text.pdf.PdfReader(fileName)
'Get page count
pageCount = reader.NumberOfPages
pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1), 18, 18, 18, 18)
writer = PdfWriter.GetInstance(pdfDoc, New FileStream(outputPath, FileMode.OpenOrCreate))
With pdfDoc
.Open()
End With
'Instantiate a PdfContentByte object
cb = writer.DirectContent
'Now loop thru the input pdfs
While f < pdfCount
'Declare a page counter variable
Dim i As Integer = 0
'Loop thru the current input pdf's pages starting at page 1
While i < pageCount
i += 1
'Get the input page size
pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(i))
'Create a new page on the output document
pdfDoc.NewPage()
'If it is the 1st page, we add bookmarks to the page
'Now we get the imported page
page = writer.GetImportedPage(reader, i)
'Read the imported page's rotation
rotation = reader.GetPageRotation(i)
'Then add the imported page to the PdfContentByte object as a template based on the page's rotation
If rotation = 90 Then
cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(i).Height)
ElseIf rotation = 270 Then
cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(i).Width + 60, -30)
Else
cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0)
End If
End While
'Increment f and read the next input pdf file
f += 1
If f < pdfCount Then
fileName = pdfFiles(f)
reader = New iTextSharp.text.pdf.PdfReader(fileName)
pageCount = reader.NumberOfPages
End If
End While
'When all done, we close the document so that the pdfwriter object can write it to the output file
pdfDoc.Close()
result = True
End If
Catch ex As Exception
Return False
End Try
Return result
End Function
the code that was marked correct does not close all the file streams therefore the files stay open within the app and you wont be able to delete unused PDFs within your project
This is a better solution:
Public Sub MergePDFFiles(ByVal outPutPDF As String)
Dim StartPath As String = FileArray(0) ' this is a List Array declared Globally
Dim document = New Document()
Dim outFile = Path.Combine(outPutPDF)' The outPutPDF varable is passed from another sub this is the output path
Dim writer = New PdfCopy(document, New FileStream(outFile, FileMode.Create))
Try
document.Open()
For Each fileName As String In FileArray
Dim reader = New PdfReader(Path.Combine(StartPath, fileName))
For i As Integer = 1 To reader.NumberOfPages
Dim page = writer.GetImportedPage(reader, i)
writer.AddPage(page)
Next i
reader.Close()
Next
writer.Close()
document.Close()
Catch ex As Exception
'catch a Exception if needed
Finally
writer.Close()
document.Close()
End Try
End Sub
I realize I'm pretty late to the party, but after reading the comments from #BrunoLowagie, I wanted to see if I could put something together myself that uses the examples from his linked sample chapter. It's probably overkill, but I put together some code that merges multiple PDFs into a single file that I posted on the Code Review SE site (the post, VB.NET - Error Handling in Generic Class for PDF Merge, contains the full class code). It only merges PDF files right now, but I'm planning on adding methods for additional functionality later.
The "master" method (towards the end of the Class block in the linked post, and also posted below for reference) handles the actual merging of the PDF files, but the multiple overloads provide a number of options for how to define the list of original files. So far, I've included the following features:
The methods return a System.IO.FileInfo object if the merge is successful.
Provide a System.IO.DirectoryInfo object or a System.String identifying a path and it will collect all PDF files in that directory (including sub-directories if specified) to merge.
Provide a List(Of System.String) or a List(Of System.IO.FileInfo) specifying the PDFs you want to merge.
Identify how the PDFs should be sorted before the merge (especially useful if you use one of the MergeAll methods to get all PDF files in a directory).
If the specified output PDF file already exists, you can specify whether or not you want to overwrite it. (I'm considering adding the "ability" to automatically adjust the output PDF file's name if it already exists).
Warning and Error properties provide a way to get feedback in the calling method, whether or not the merge is successful.
Once the code is in place, it can be used like this:
Dim PDFDir As New IO.DirectoryInfo("C:\Test Data\PDF\")
Dim ResultFile As IO.FileInfo = Nothing
Dim Merger As New PDFManipulator
ResultFile = Merger.MergeAll(PDFDir, "C:\Test Data\PDF\Merged.pdf", True, PDFManipulator.PDFMergeSortOrder.FileName, True)
Here is the "master" method. As I said, it's probably overkill (and I'm still tweaking it some), but I wanted to do my best to try to make it work as effectively as possible. Obviously it requires a Reference to the itextsharp.dll for access to the library's functions.
I've commented out the references to the Error and Warning properties of the class for this post to help reduce any confusion.
Public Function Merge(ByVal PDFFiles As List(Of System.IO.FileInfo), ByVal OutputFileName As String, ByVal OverwriteExistingPDF As Boolean, ByVal SortOrder As PDFMergeSortOrder) As System.IO.FileInfo
Dim ResultFile As System.IO.FileInfo = Nothing
Dim ContinueMerge As Boolean = True
If OverwriteExistingPDF Then
If System.IO.File.Exists(OutputFileName) Then
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
ContinueMerge = False
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("Could not delete existing output file.")
Throw
End Try
End If
End If
If ContinueMerge Then
Dim OutputPDF As iTextSharp.text.Document = Nothing
Dim Copier As iTextSharp.text.pdf.PdfCopy = Nothing
Dim PDFStream As System.IO.FileStream = Nothing
Dim SortedList As New List(Of System.IO.FileInfo)
Try
Select Case SortOrder
Case PDFMergeSortOrder.Original
SortedList = PDFFiles
Case PDFMergeSortOrder.FileDate
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.LastWriteTime).ToList
Case PDFMergeSortOrder.FileName
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.Name).ToList
Case PDFMergeSortOrder.FileNameWithDirectory
SortedList = PDFFiles.OrderBy(Function(f As System.IO.FileInfo) f.FullName).ToList
End Select
If Not IO.Directory.Exists(New IO.FileInfo(OutputFileName).DirectoryName) Then
Try
IO.Directory.CreateDirectory(New IO.FileInfo(OutputFileName).DirectoryName)
Catch ex As Exception
ContinueMerge = False
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("Could not create output directory.")
Throw
End Try
End If
If ContinueMerge Then
OutputPDF = New iTextSharp.text.Document
PDFStream = New System.IO.FileStream(OutputFileName, System.IO.FileMode.OpenOrCreate)
Copier = New iTextSharp.text.pdf.PdfCopy(OutputPDF, PDFStream)
OutputPDF.Open()
For Each PDF As System.IO.FileInfo In SortedList
If ContinueMerge Then
Dim InputReader As iTextSharp.text.pdf.PdfReader = Nothing
Try
InputReader = New iTextSharp.text.pdf.PdfReader(PDF.FullName)
For page As Integer = 1 To InputReader.NumberOfPages
Copier.AddPage(Copier.GetImportedPage(InputReader, page))
Next page
If InputReader.IsRebuilt Then
'If Warnings Is Nothing Then
' Warnings = New List(Of String)
'End If
'Warnings.Add("Damaged PDF: " & PDF.FullName & " repaired and successfully merged into output file.")
End If
Catch InvalidEx As iTextSharp.text.exceptions.InvalidPdfException
'Skip this file
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("Invalid PDF: " & PDF.FullName & " not merged into output file.")
Catch FormatEx As iTextSharp.text.pdf.BadPdfFormatException
'Skip this file
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("Bad PDF Format: " & PDF.FullName & " not merged into output file.")
Catch PassworddEx As iTextSharp.text.exceptions.BadPasswordException
'Skip this file
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("Password-protected PDF: " & PDF.FullName & " not merged into output file.")
Catch OtherEx As Exception
ContinueMerge = False
Finally
If Not InputReader Is Nothing Then
InputReader.Close()
InputReader.Dispose()
End If
End Try
End If
Next PDF
End If
Catch ex As iTextSharp.text.pdf.PdfException
ResultFile = Nothing
ContinueMerge = False
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("iTextSharp Error: " & ex.Message)
If System.IO.File.Exists(OutputFileName) Then
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
System.IO.File.Delete(OutputFileName)
End If
Throw
Catch other As Exception
ResultFile = Nothing
ContinueMerge = False
'If Errors Is Nothing Then
' Errors = New List(Of String)
'End If
'Errors.Add("General Error: " & other.Message)
If System.IO.File.Exists(OutputFileName) Then
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
System.IO.File.Delete(OutputFileName)
End If
Throw
Finally
If Not OutputPDF Is Nothing Then
OutputPDF.Close()
OutputPDF.Dispose()
End If
If Not PDFStream Is Nothing Then
PDFStream.Close()
PDFStream.Dispose()
End If
If Not Copier Is Nothing Then
Copier.Close()
Copier.Dispose()
End If
If System.IO.File.Exists(OutputFileName) Then
If ContinueMerge Then
ResultFile = New System.IO.FileInfo(OutputFileName)
If ResultFile.Length <= 0 Then
ResultFile = Nothing
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
Throw
End Try
End If
Else
ResultFile = Nothing
Try
System.IO.File.Delete(OutputFileName)
Catch ex As Exception
Throw
End Try
End If
Else
ResultFile = Nothing
End If
End Try
End If
Return ResultFile
End Function
Some may have to make a change to the code at "writer = PdfWriter.GetInstance(pdfDoc, New FileStream(outputPath, FileMode.OpenOrCreate))" as iTextSharp may not support
Change to:
Dim fs As IO.FileStream = New IO.FileStream(outputPath, IO.FileMode.Create)
writer = iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, fs)

Unable to cast object of type 'System.Data.DataTable' to type 'System.Collections.IEnumerable'

So I created an object called Report. A Report object has several different properties, including a DataSet. This DataSet is supposed to contain at least one DataTable. Report is serializable. In a Unit Test I instantiate a Report object, give its properties values, then serialize it, then deserialize it.
After adding a method to populate the DataSet, the Deserialization function gives me Error: Unable to cast object of type 'System.Data.DataTable' to type 'System.Collections.IEnumerable'.
Shouldn't it be getting serialized as a DataSet...not a DataTable? I'm not sure exactly what is causing me this error. Code snippets are below. Any help is appreciated!
<Serializable> Public Class Report
Private titleStr As String
Private startDateTime As DateTime
Private endDateTime As DateTime
Private numIntervalsShort As Short
Private binnedDataSet As DataSet
...property gets and sets...namely:
Property BinnedData As DataSet
Get
Return binnedDataSet
End Get
Set(ByVal value As DataSet)
binnedDataSet = value
End Set
End Property
End Class
<TestClass()> Public Class ReportObjectTest
<TestMethod()> Public Sub TestCreateReport()
Dim testReport As New Project.Report
testReport.Title = "Test Title"
testReport.StartDate = "1/1/2015 1:00 AM"
testReport.EndDate = "1/2/2015 6:00 PM"
testReport.NumIntervals = 41
PopulateDataSet(testReport)
Serialize(testReport)
Deserialize()
End Sub
Private Sub PopulateDataSet(ByRef report As Project.Report)
report.BinnedData = New DataSet()
Dim DT1 As DataTable = New DataTable("Test Table1")
report.BinnedData.Tables.Add(DT1)
DT1.Columns.Add(New DataColumn("Column1", GetType(Int32)))
DT1.Columns.Add(New DataColumn("Column2", GetType(Int32)))
DT1.Columns.Add(New DataColumn("Column3", GetType(Int32)))
Dim Row1 As DataRow = DT1.NewRow()
Dim Row2 As DataRow = DT1.NewRow()
Dim Row3 As DataRow = DT1.NewRow()
Row1("Column1") = 32
Row1("Column2") = 15
Row1("Column3") = 9
Row2("Column1") = 3
Row2("Column2") = 27
Row2("Column3") = 98
Row2("Column1") = 1
Row2("Column2") = 12
Row2("Column3") = 65
End Sub
Private Sub Serialize(ByRef report As Project.Report)
Dim stream As New FileStream("TestReport.xxx", FileMode.Create)
Dim mySerializer As BinaryFormatter = New BinaryFormatter()
Try
mySerializer.Serialize(stream, report)
Catch ex As SerializationException
Console.WriteLine("Error saving the report. " & ex.Message)
Throw
Finally
stream.Close()
End Try
End Sub
Private Sub Deserialize()
Dim readTestReport As New Project.Report()
Dim stream As New FileStream("TestReport.xxx", FileMode.Open)
Dim myDeserializer As BinaryFormatter = New BinaryFormatter()
Try
readTestReport = DirectCast(myDeserializer.Deserialize(stream), Project.Report)
Catch ex As SerializationException
Console.WriteLine("Error opening the report. " & ex.Message)
Throw
Finally
stream.Close()
End Try
Console.WriteLine(Environment.NewLine & "Values after Deserialization:")
Console.WriteLine("Title = " & readTestReport.Title)
Console.WriteLine("Start Date = " & readTestReport.StartDate)
Console.WriteLine("End Date = " & readTestReport.EndDate)
Console.WriteLine("Number of Intervals = " & readTestReport.NumIntervals)
For Each Table In readTestReport.BinnedData.Tables
For Each Row In Table
Console.WriteLine("Table Row = " & Row.ToString)
For Each DataColumn In Row
Console.WriteLine(DataColumn.ToString)
Next
Next
Next
End Sub
End Class
I was right...figured it out. The issue lay in how I was trying to display the values of the table after deserializing. DataTables and DataRows are not enumerable, but the way I was trying to display it was by looping through the way you only can with an enumerable type.
I modified that block to assign the table to a View instead:
Dim tableView As DataView = New DataView(readTestReport.BinnedData.Tables(0))
Console.WriteLine("Table = ")
Dim rowView As DataRowView
Dim i As Integer
For Each rowView In tableView
For i = 0 To tableView.Table.Columns.Count - 1
Console.Write(rowView(i) & vbTab)
Next
Console.WriteLine()
Next
These articles helped:
https://msdn.microsoft.com/en-us/library/23a0aths%28v=vs.110%29.aspx
https://msdn.microsoft.com/en-us/library/bb669099%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Deserialize json string and insert in SQL DB

I have a function which gets json string from jsonblob, deserializers it and returns in dataview. I want to know how can i insert the data from the dataview into my sql database using vb.net
My function is as follows
Public Function GetJsonString() As DataView
Dim dsContactMeta As DataSet = Nothing
Dim dv As DataView = Nothing
'url declaration for REST_ContactMeta
Dim REST_ContactMetaURL As Uri = New Uri("http://jsonblob.com/api/jsonBlob/5420df11e4b00ad1f05ed29b")
Dim strJSONData As String = ""
Dim response As HttpWebResponse
Dim reader As StreamReader
Try
Dim httpWebRequest As HttpWebRequest = WebRequest.Create(REST_ContactMetaURL)
httpWebRequest.Method = WebRequestMethods.Http.Get
httpWebRequest.ContentType = "application/json"
response = httpWebRequest.GetResponse()
reader = New StreamReader(response.GetResponseStream)
strJSONData = reader.ReadToEnd
strJSONData = "[" & strJSONData & "]" 'had to wrap the raw JSON data with brackets for parsing purposes
Dim myXmlNode As System.Xml.XmlNode = JsonConvert.DeserializeXmlNode("{""root"":" + strJSONData + "}", "root") 'error is thrown if the JSON does not have a root element
' Dim myXmlNode As System.Xml.XmlNode = JsonConvert.DeserializeXmlNode(strJSONData)
dsContactMeta = New DataSet("Test")
Try
dsContactMeta.ReadXml(New XmlNodeReader(myXmlNode))
If dsContactMeta.Tables("root") Is Nothing Or dsContactMeta.Tables("root").Rows.Count = 0 Then
Return Nothing 'in case of error return nothing
Else
dsContactMeta.Tables("root").Columns("job_id").SetOrdinal(0) 'setting the field name as the first column
dv = New DataView
dv.Table = dsContactMeta.Tables("root")
Return dv
End If
Catch ex As Exception
Return Nothing
End Try
Catch ex As Exception
Return Nothing 'if for any reason the API has failed connecting to the server or other unknown error then return nothing
End Try
End Function
Insert record into database from DataView, for that you need to read DataView:
For Each rowView As DataRowView In dataView
Debug.Write(item & " ")
Dim row as DataRow = rowView.Row;
// Do something //
//insert into tablename(col1,col2,..) values(row['col1'],row['col2'],..)
Next