Upload a document after saving it with agility pack fails - asp.net

I've been struggling with some issue with an upload (thru FtpWebRequest) of a document after it's been saved with Html Agility pack.
I'm trying to edit a html file and then save it to a stringWriter and then upload it to a server.
I'm saving the document like this
...
doc.OptionAutoCloseOnEnd = True
doc.OptionWriteEmptyNodes = True
Dim sr As New StringWriter
doc.Save(sr)
And then upload it using asyncFtpUpload sub like the one on msdn but only with a few changes (instead of a filename I use the string)
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx#Y3024
The result of this is that the file beeing uploaded get's the last bytes cut off.
When I see the source code of that file on the server, it misses the <\html> tag.
i have debugged the code and the string created on the doc.save() is correct, then in the upload routine, when i use the getBytes() it's still correct, and the requestStream write method writes the correct length of the stream.
I can't figure out what's happening with this code.
Can anyone help me figuring this out?
Here's the code:
Dim outStream As MemoryStream = New MemoryStream(ASCIIEncoding.Default.GetBytes(str))
Dim uploader As AsynchronousFtpUpLoader = New AsynchronousFtpUpLoader
uploader.startUpload(pag, outStream)
And the class:
Public Class AsynchronousFtpUpLoader
Public Sub startUpload(ByVal pag As FtpPage, ByVal stream As Stream)
Try
Dim waitObject As ManualResetEvent
Dim target As New Uri(pag.currentUrl)
Dim state As New FtpState()
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(target), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.UseBinary = False
request.Credentials = New NetworkCredential(pag.login, pag.password)
state.Request = request
state.stream = stream
' Get the event to wait on.
waitObject = state.OperationComplete
' Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(New AsyncCallback(AddressOf EndGetStreamCallback), state)
' Block the current thread until all operations are complete.
waitObject.WaitOne()
' The operations either completed or threw an exception.
If state.OperationException IsNot Nothing Then
Throw state.OperationException
Else
End If
Catch ex As Exception
End Try
End Sub
Private Shared Sub EndGetStreamCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim requestStream As Stream = Nothing
Try
requestStream = state.Request.EndGetRequestStream(ar)
Const bufferLength As Integer = 2048
Dim buffer As Byte() = New Byte(bufferLength) {}
Dim readBytes As Integer = 0
Dim stream As MemoryStream = state.stream
Do
readBytes = stream.Read(buffer, 0, bufferLength)
If readBytes <> 0 Then
requestStream.Write(buffer, 0, readBytes)
End If
Loop While readBytes <> 0
requestStream.Flush()
state.stream.Close()
requestStream.Close()
state.Request.BeginGetResponse(New AsyncCallback(AddressOf EndGetResponseCallback), state)
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
Return
End Try
End Sub
Private Shared Sub EndGetResponseCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim response As FtpWebResponse = Nothing
Try
response = DirectCast(state.Request.EndGetResponse(ar), FtpWebResponse)
response.Close()
state.StatusDescription = response.StatusDescription
state.OperationComplete.[Set]()
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
End Try
End Sub

Related

ASP.net: How i can limit the load of remote images based on image weight, dimensions & types?

i've found this function for VB.net and i used in an .aspx page and works.
Private Sub LoadImageFromURL(URL As String, ByRef Img As Drawing.Bitmap)
Const BYTESTOREAD As Integer = 10000
Dim myRequest As WebRequest = WebRequest.Create(URL)
Dim myResponse As WebResponse = myRequest.GetResponse()
Dim ReceiveStream As Stream = myResponse.GetResponseStream()
Dim br As New BinaryReader(ReceiveStream)
Dim memstream As New MemoryStream()
Dim bytebuffer As Byte() = New Byte(BYTESTOREAD - 1) {}
Dim BytesRead As Integer = br.Read(bytebuffer, 0, BYTESTOREAD)
While BytesRead > 0
memstream.Write(bytebuffer, 0, BytesRead)
BytesRead = br.Read(bytebuffer, 0, BYTESTOREAD)
End While
Img = New Drawing.Bitmap(memstream)
End Sub
I would like to limit the loading of a remote imagebased on:
1) Image size limit in Bytes
2) Max Dimension of the pic x,y
3) Accepted image types (jpg, png)
I'm not so expert on image manipulation so I ask for a little help to improve the function if is possible and to enable some sort of protection on the image URL tio avoid malicious use.
EDIT: I must use the function on a .aspx page
Thanks
I transformed into a function to validate the url and works.
Don't know if i can make it lighter and faster or if there is a better solution to do that.
Public Function ChkImageFromURL(URL As String) As Boolean
Dim myRequest As WebRequest = WebRequest.Create(URL)
myRequest.Method = WebRequestMethods.Http.Head
Dim myResponse As WebResponse = myRequest.GetResponse()
Dim ImageLen As Integer = myResponse.ContentLength
Dim ImageType As String = myResponse.ContentType
If ( Lcase(ImageType) <> "image/jpeg" AND Lcase(ImageType) <> "image/png" ) Or ImageLen > 300000 Then
return false
Else
return true
End if
End Function

How to save an resized image to database which is uploaded to server in asp.net mvc 5

I want to save an image which is resized using Imageresizer plugin to database.
Here is my code.
<HttpPost()>
<ValidateAntiForgeryToken()>
Async Function Edit(ByVal employeeMaster As EmployeeMaster, ByVal upload As HttpPostedFileBase) As Task(Of ActionResult)
Try
If ModelState.IsValid Then
If upload IsNot Nothing Then
'Dim imageData As Byte()= New [Byte](upload.InputStream.Length - 1) {} // this section saving to database which is original file ----- start
'upload.InputStream.Read(imageData, 0, CInt(upload.InputStream.Length))
'employeeMaster.Photo = imageData // --- end
Dim guid1 As String = Guid.NewGuid().ToString()
Dim filename = guid1
Dim versions = New Dictionary(Of String, String)()
Dim path1 = Server.MapPath("~/Content/")
versions.Add("", "maxwidth=600&maxheight=600&format=jpg")
For Each suffix As String In versions.Keys
upload.InputStream.Seek(0, SeekOrigin.Begin)
ImageBuilder.Current.Build(New ImageJob(upload.InputStream, path1 + filename, New Instructions(versions(suffix)), False, True))
Next
Dim savedFileName = Path.Combine(path1, Path.GetFileName(filename))
Return File(savedFileName, "application/octet-stream", filename)
upload.SaveAs(savedFileName)
Dim imageData As Byte()= New [Byte](upload.InputStream.Length - 1) {} // trying to save new image to database ----- start
upload.InputStream.Read(imageData, 0, CInt(upload.InputStream.Length))
employeeMaster.Photo = imageData // -----end
Dim size1 = upload.ContentLength
Dim fullPath As String = Request.MapPath("~/Content/" + filename)
If System.IO.File.Exists(fullPath) Then
Dim ex = "ok"
System.IO.File.Delete(fullPath)
End If
End If
db.Entry(employeeMaster).State = EntityState.Modified
Await db.SaveChangesAsync()
Dim json1 = New With {Key .message = "Updated Successfully", Key .error = "False"}
Return Json(json1, JsonRequestBehavior.AllowGet)
Else
'logic for when that description exists
'for example, to add to ModelState
ModelState.AddModelError("EmployeeCode", "EmployeeCode Exists")
End If
Catch ex As DbEntityValidationException
End Try
End Function
The uploaded file can be directly save to database. But I am compressing that image using Imageresizer plugin. Then it is saving to a folder.I am trying to read that saved image which is in the folder and save newly formed image to database. How can be it done?
I have solved the problem.
Here is the code
Dim _fileInfo As New System.IO.FileInfo(savedFileName)
Dim _NumBytes As Long = _fileInfo.Length
Dim _FStream As New System.IO.FileStream(savedFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
'upload.SaveAs(savedFileName)
imageData = New [Byte](_FStream.Length - 1) {}
_FStream.Read(imageData, 0, CInt(_FStream.Length))
employeeMaster.Photo = imageData

Cross communication between two web applications using web requests: is this close to viable?

I am using the following code to try and learn how pages post, listen and respond between one another using web requests. I begin the process by issuing a request in the first of the two procedures, intending to have the second process retrieve the request and respond back to the calling process. My calling process is receiving a blank response.
Question: Why, and how close to viable is this test?
Here's my two page load events, located in two separate web applications.
Both apps are hosted on IIS:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sPostURL As String = "http://localhost/DDI_TXListener_Test/Listener_Page.aspx"
Dim dataToPost As String = String.Empty ' //This is the data for form posting
Dim HttpWebResponse As System.Net.WebResponse = Nothing
Dim StreamReader As System.IO.StreamReader = Nothing
Dim respString As String = String.Empty
Dim stOut As System.IO.Stream = Nothing
dataToPost = "Name"
Try
Dim httpReq As System.Net.WebRequest = System.Net.WebRequest.Create(sPostURL)
httpReq.Method = "POST"
httpReq.ContentType = "application/x-www-form-urlencoded"
Dim byte1 As Byte() = System.Text.Encoding.ASCII.GetBytes(dataToPost)
httpReq.ContentLength = byte1.Length
httpReq.Timeout = 10000
stOut = httpReq.GetRequestStream()
stOut.Write(byte1, 0, byte1.Length)
stOut.Dispose()
stOut = Nothing
HttpWebResponse = httpReq.GetResponse()
StreamReader = New System.IO.StreamReader(HttpWebResponse.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"))
respString = StreamReader.ReadToEnd()
Catch ex As Exception
Finally
If Not StreamReader Is Nothing Then
StreamReader.Dispose()
StreamReader = Nothing
End If
If Not HttpWebResponse Is Nothing Then
HttpWebResponse.Close()
HttpWebResponse = Nothing
End If
End Try
' <asp:label> control on the html form in front of this code page
returnedhit.Text = respString
End Sub
And I have this as what I hope to use as the receiving/fulfilling end of the above request at:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sPostURL As String = "http://localhost/DDI_TXRequester_Test/RequesterPage.aspx"
Dim dataToPost As String = String.Empty ' //This is the data for form posting
Dim HttpWebResponse As System.Net.WebResponse = Nothing
Dim StreamReader As System.IO.StreamReader = Nothing
Dim respString As String = String.Empty
Dim stOut As System.IO.Stream = Nothing
Try
Dim httpReq As System.Net.WebRequest = System.Net.WebRequest.Create(sPostURL)
HttpWebResponse = httpReq.GetResponse()
StreamReader = New System.IO.StreamReader(HttpWebResponse.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"))
respString = StreamReader.ReadToEnd()
If respString <> "" Then
Dim cnt As Integer = 0
Dim delim As Char() = {"&"c}
Dim bodpos As Integer = InStr(respString, "<body>") + 6
Dim respstr As String = Right$(respString, (Len(respString) - bodpos))
Dim strArr As String() = respstr.Split(delim)
For Each s As String In strArr
cnt += 1
Select Case cnt
Case 1
Session.Add("opRequested", Right$(Trim(s), (Len(Trim(s)) - 18)))
Case Else '
End Select
Next s
If CStr(Session("opRequested")) = "Name" Then dataToPost = "Name=Jones" Else dataToPost = "Error=Unknown Request"
httpReq.Method = "POST"
httpReq.ContentType = "application/x-www-form-urlencoded"
Dim byte1 As Byte() = System.Text.Encoding.ASCII.GetBytes(dataToPost)
httpReq.ContentLength = byte1.Length
httpReq.Timeout = 10000
stOut = httpReq.GetRequestStream()
stOut.Write(byte1, 0, byte1.Length)
stOut.Dispose()
stOut = Nothing
End If
Catch ex As Exception
Finally
If Not stOut Is Nothing Then
stOut.Dispose()
stOut = Nothing
End If
If Not StreamReader Is Nothing Then
StreamReader.Dispose()
StreamReader = Nothing
End If
If Not HttpWebResponse Is Nothing Then
HttpWebResponse.Close()
HttpWebResponse = Nothing
End If
End Try
End Sub

Creating an Excel file via OpenXML in ASP.NET/VB.NET and sending over Response

trying to just create a simple OpenXML document based on http://www.codeproject.com/Articles/371203/Creating-basic-Excel-workbook-with-Open-XML
i moved it over to asp.net (below) on my dev server but the file that is created is corrupted and will not open. am i doing something obviously stupid?
Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
Response.Clear()
Response.Buffer = False
Dim myoutputstream As New MemoryStream
Dim myPackage As SpreadsheetDocument = CreateWorkbook(myoutputstream)
AddWorksheet(myPackage, "Test")
myPackage.WorkbookPart.Workbook.Save()
Response.AddHeader("Content-Disposition", ("attachment") & "; filename=Report.xlsx")
Response.ContentType = "application/octet-stream"
Response.AddHeader("Accept-Header", myoutputstream.Length.ToString())
Response.AddHeader("Content-Length", myoutputstream.Length.ToString())
Response.BinaryWrite(myoutputstream.GetBuffer())
Response.End()
End Sub
Public Shared Function CreateWorkbook(ByVal MyMemoryStream As MemoryStream) As SpreadsheetDocument
Dim spreadSheet As SpreadsheetDocument = Nothing
Dim sharedStringTablePart As SharedStringTablePart
Dim workbookStylesPart As WorkbookStylesPart
Try
' Create the Excel workbook
spreadSheet = SpreadsheetDocument.Create(MyMemoryStream, SpreadsheetDocumentType.Workbook, False)
' Create the parts and the corresponding objects
' Workbook
spreadSheet.AddWorkbookPart()
spreadSheet.WorkbookPart.Workbook = New DocumentFormat.OpenXml.Spreadsheet.Workbook()
spreadSheet.WorkbookPart.Workbook.Save()
' Shared string table
sharedStringTablePart = spreadSheet.WorkbookPart.AddNewPart(Of SharedStringTablePart)()
sharedStringTablePart.SharedStringTable = New DocumentFormat.OpenXml.Spreadsheet.SharedStringTable()
sharedStringTablePart.SharedStringTable.Save()
' Sheets collection
spreadSheet.WorkbookPart.Workbook.Sheets = New DocumentFormat.OpenXml.Spreadsheet.Sheets()
spreadSheet.WorkbookPart.Workbook.Save()
' Stylesheet
workbookStylesPart = spreadSheet.WorkbookPart.AddNewPart(Of WorkbookStylesPart)()
workbookStylesPart.Stylesheet = New DocumentFormat.OpenXml.Spreadsheet.Stylesheet()
workbookStylesPart.Stylesheet.Save()
Catch exception As System.Exception
End Try
Return spreadSheet
End Function
Public Shared Function AddWorksheet(ByVal spreadsheet As SpreadsheetDocument, ByVal name As String) As Boolean
Dim sheets As DocumentFormat.OpenXml.Spreadsheet.Sheets = spreadsheet.WorkbookPart.Workbook.GetFirstChild(Of DocumentFormat.OpenXml.Spreadsheet.Sheets)()
Dim sheet As DocumentFormat.OpenXml.Spreadsheet.Sheet
Dim worksheetPart As WorksheetPart
' Add the worksheetpart
worksheetPart = spreadsheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
worksheetPart.Worksheet = New DocumentFormat.OpenXml.Spreadsheet.Worksheet(New DocumentFormat.OpenXml.Spreadsheet.SheetData())
worksheetPart.Worksheet.Save()
' Add the sheet and make relation to workbook
sheet = New DocumentFormat.OpenXml.Spreadsheet.Sheet With {
.Id = spreadsheet.WorkbookPart.GetIdOfPart(worksheetPart),
.SheetId = (spreadsheet.WorkbookPart.Workbook.Sheets.Count() + 1),
.Name = name}
sheets.Append(sheet)
spreadsheet.WorkbookPart.Workbook.Save()
Return True
End Function
Do you fill any data into spreadsheet?
My main reason why my generated excel files gets corrupted is really simple : excel start count from 1 but not from 0, and this is really important to remember.
Here is my example, but on c#
public void GetTemplate(Page page, DownloadExcelTemplateModel model)
{
// generating file
byte[] bytes = GetFile(model);
PutExcelFileToResponce(page, bytes);
}
private static void PutExcelFileToResponce(Page page, byte[] bytes)
{
// do clear
page.Response.Clear();
page.Response.ClearHeaders();
page.Response.ClearContent();
// add headers
page.Response.AddHeader("Content-Length", bytes.Length.ToString(CultureInfo.InvariantCulture));
page.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", "Template.xlsx"));
page.Response.AddHeader("Content-Type", "application/Excel");
// set content type
page.Response.ContentType = "application/vnd.xls";
// do write binary data to responce stream
page.Response.BinaryWrite(bytes);
// finish process
page.Response.Flush();
page.Response.End();
}
private byte[] GetFile(DownloadExcelTemplateModel model)
{
return WebService.GetData(model.Id);
}

CA2000: Object is not disposed along all exception paths

I am having trouble trying to figure out why I'm getting this warning in following code.
CA2000 : Microsoft.Reliability : In method 'Encryption64.Decrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.
CA2000 : Microsoft.Reliability : In method 'Encryption64.Encrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.
Public Class Encryption64
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Try
Dim inputByteArray(stringToDecrypt.Length) As Byte
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
ReturnValue = encoding.GetString(ms.ToArray())
Catch e As Exception
ReturnValue = e.Message
Finally
If des IsNot Nothing Then
des.Dispose()
End If
If ms IsNot Nothing Then
ms.Dispose()
End If
End Try
Return ReturnValue
End Function
Public Function Encrypt(ByVal stringToEncrypt As String, ByVal SEncryptionKey As String) As String
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(stringToEncrypt)
Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
ReturnValue = Convert.ToBase64String(ms.ToArray())
Catch e As Exception
ReturnValue = e.Message
Finally
If des IsNot Nothing Then
des.Dispose()
End If
If ms IsNot Nothing Then
ms.Dispose()
End If
End Try
Return ReturnValue
End Function
End Class
Since you are declaring (and instantiating) your des objects outside of the Try ... Finally blocks, it is possible for your code to raise an exception in the line Dim ms As New MemoryStream() and your .Dispose() will not be called.
When you are working with objects that implement IDisposable, it is much preferable where possible to wrap them in a Using block instead of a Try...Finally block. For example:
Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Dim inputByteArray(stringToDecrypt.Length) As Byte
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Using ms as New MemoryStream
Using des As New DESCryptoServiceProvider
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
End Using ' des
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
ReturnValue = encoding.GetString(ms.ToArray())
End Using ' ms
Catch e As Exception
ReturnValue = e.Message
End Try
Return ReturnValue
End Function
Just a guess, but maybe it's not smart enough to realize that this code line will always be true:
If des IsNot Nothing Then
In other words, it might assume that because there is a conditional statement, the Dispose() call might not be executed.
To check, you can try commenting out the "if" and see if the warning goes away.

Resources