I'm trying to fix an issue with an application I'm supporting (I didn't write the code). The code takes an SSRS report and renders it in pdf format. Users are sporadically getting the error indicated in the title. There is no rhyme or reason to when the error is generated (a particular report will run one time and throw the error the next). The code is below.
Public Sub OpenReport()
Dim MyParms As New Generic.List(Of ReportParameter)
Dim mimeType As String = Nothing
Dim encoding As String = Nothing
Dim extension As String = Nothing
Dim deviceInfo As String = Nothing
Dim streamids() As String = Nothing
Dim warnings As Microsoft.Reporting.WebForms.Warning() = Nothing
Dim bytes() As Byte
Dim format As String = "PDF" ''#to open the report in pdf; report viewer invisible
Try
If dropReports.SelectedItem.Value = "1" Then
If Session("IsBDAP") = True Then
MyParms.Add(New ReportParameter("SCAId", dropSCA.SelectedItem.Value, False))
Else
MyParms.Add(New ReportParameter("SCAId", Server.UrlEncode(Session("SCAId")), False))
End If
MyParms.Add(New ReportParameter("ProviderId", dropProvider.SelectedItem.Value, False))
If dropVisit.Visible = True Then
MyParms.Add(New ReportParameter("VisitId", dropVisit.SelectedItem.Value, False))
End If
MyParms.Add(New ReportParameter("FY", dropContractFY.SelectedItem.Value, False))
ReportViewer1.ProcessingMode = ProcessingMode.Remote
ReportViewer1.ServerReport.ReportServerUrl = New Uri(System.Configuration.ConfigurationManager.AppSettings("ReportServerURI"))
ReportViewer1.ServerReport.ReportPath = Session("ReportsFolder") & "MReport"
ReportViewer1.ServerReport.ReportServerCredentials = New MyReportServerCredentials()
ReportViewer1.ServerReport.SetParameters(MyParms)
''#Code to convert the report to pdf
deviceInfo = "<DeviceInfo>" + "<SimplePageHeaders>True</SimplePageHeaders>" + "</DeviceInfo>"
bytes = ReportViewer1.ServerReport.Render(format, deviceInfo, mimeType, encoding, extension, streamids, warnings)
Dim size As Integer = bytes.Length
ReportViewer1.ServerReport.Refresh()
Response.Buffer = True
Response.Clear()
Response.ContentType = mimeType
Response.AddHeader("content-disposition", "attachment; filename=MReport." + extension)
Response.BinaryWrite(bytes)
ElseIf dropReports.SelectedItem.Value = "2" Then
If Session("IsBDAP") = True Then
MyParms.Add(New ReportParameter("SCAId", dropSCA.SelectedItem.Value, False))
Else
MyParms.Add(New ReportParameter("SCAId", Server.UrlEncode(Session("SCAId")), False))
End If
MyParms.Add(New ReportParameter("ProviderId", dropProvider.SelectedItem.Value, False))
If dropVisit.Visible = True Then
MyParms.Add(New ReportParameter("FollowUpVisitId", dropVisit.SelectedItem.Value, False))
End If
MyParms.Add(New ReportParameter("FY", dropContractFY.SelectedItem.Value, False))
ReportViewer1.ProcessingMode = ProcessingMode.Remote
ReportViewer1.ServerReport.ReportServerUrl = New Uri(System.Configuration.ConfigurationManager.AppSettings("ReportServerURI"))
ReportViewer1.ServerReport.ReportPath = Session("ReportsFolder") & "FReport"
ReportViewer1.ServerReport.ReportServerCredentials = New MyReportServerCredentials()
ReportViewer1.ServerReport.SetParameters(MyParms)
''#Code to convert the report to pdf
deviceInfo = "<DeviceInfo>" + "<SimplePageHeaders>True</SimplePageHeaders>" + "</DeviceInfo>"
bytes = ReportViewer1.ServerReport.Render(format, deviceInfo, mimeType, encoding, extension, streamids, warnings)
ReportViewer1.ServerReport.Refresh()
Response.Buffer = True
Response.Clear()
Response.ContentType = mimeType
Response.AddHeader("content-disposition", "attachment; filename=FReport." + extension)
Response.BinaryWrite(bytes)
I read that the default length limit is 4MB. None of the reports by themselves are even over 350K. I'm wondering if this could be caused by a caching issue. I'm not an expert, so I need some guidance as to how best to solve the problem. I also want to understand why the issue is happening. Please note that only 2 reports are shown in the snippet - there are about 30+ reports in the full sub.
Thanks for your help.
edit - I tried the proposed solution, but it didn't help (I also tried the Fiddler route, but did not see anything glaring). I thought it might be best to clarify. The reports will run fine for a while, but the execution time gradually gets slower and slower until the application eventually displays the error. Does this shed any light on the problem?
TIA
try increasing the following values in your web.config:
<httpRuntime maxRequestLength="204800" requestLengthDiskThreshold="204800" />
Ok, I figured it out...finally. Here's the cause (for anyone with a similar problem). The issue is viewstate. The reportviewer on the page is adding millions of bytes to viewstate, causing the issue. I disabled viewstate for the hidden reportviewer and no longer have the issue. Thank you to everyone for your help and suggestions.
Have you tried logging the Request URLs to see if they are growing? Perhaps it is somewhere in that "ReportsFolder" session value or the extension that is being misset somewhere would be my guess.
Related
I have found good information on how to automatically download a file to the client advertised as a solution of how to print using code
(https://forums.asp.net/t/1233841.aspx?How+do+I+print+from+Reporting+Services+AUTOMATICALLY+in+VB+Net+web+app+)
but what I need to do is have the code print the document without the user interacting.
From what I have found it appears this can not be done as one might casually think. ReportViewer for example does not have a 'print' method.
The only two solutions appears to be to use ProcessStart (which then means saving the file to the file system before printing which I dont want to do)
or maybe (will be researching this today) create a subscription using code and then delete it later.
You are not able to print a report directly from your asp.net page. The reason for this is security. If it allowed you to send a file through the network and onto the clients computer, and then search the computer for a printer, this could cause major security issues. The report viewer does have a print icon, but this disappears when you deploy the project and run the page remotely. I have faced the same issue in the past and found it best to just export the report to say PDF and allow the user to Download it. I have used the below code to accomplish this task in the past:
Private Sub CreatePDFMatrix(fileName As String)
' ReportViewer1.LocalReport.DataSources.Clear()
Dim adapter As New ReportDataSetTableAdapters.vwPrintTagsTableAdapter
Dim table As New ReportDataSet.vwPrintTagsDataTable
Dim month = MonthName(Date.Today.Month)
Dim year = Date.Today.Year
Dim p(1) As ReportParameter
Dim warnings() As Warning
Dim streamIds As String()
Dim mimeType As String = String.Empty
Dim encoding As String = String.Empty
Dim extension As String = String.Empty
Dim adpt2 As New ReportDataSetTableAdapters.vwPrintTagsTableAdapter
adapter.FillForMainReport(table, DropDownList1.SelectedValue, g_Company, g_Division)
Me.ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("DataSet1", CType(table, DataTable))) 'Add(New ReportDataSource("ReportingData", CType(table, DataTable)))
Me.ReportViewer1.DataBind()
Dim viewer = ReportViewer1
viewer.ProcessingMode = ProcessingMode.Local
viewer.LocalReport.ReportPath = "Report1.rdlc"
p(0) = New ReportParameter("MonthYear", month & "-" & year)
Dim check = DropDownList1.SelectedValue
ReportViewer1.LocalReport.SetParameters(p(0))
p(1) = New ReportParameter("Location", DropDownList1.SelectedValue)
ReportViewer1.LocalReport.SetParameters(p(1))
Try
Dim bytes As Byte() = viewer.LocalReport.Render("PDF", Nothing, mimeType, encoding, ".pdf", streamIds, warnings)
Response.Buffer = True
Response.Clear()
Response.ContentType = mimeType
Response.AddHeader("content-disposition", Convert.ToString((Convert.ToString("attachment; filename=") & fileName) + ".") & extension)
Response.BinaryWrite(bytes)
' create the file
Response.Flush()
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
This question already has answers here:
Zip file is getting corrupted after downloading from server in C#
(3 answers)
Closed 4 years ago.
I am trying to allow authenticated users to upload pictures to the server through FTP. The code works for the most part. The part that doesn't is that there is an issue in uploading the file. I have tried to upload a few different pictures and all of them are larger on the server and therefore, not properly constructed.
One picture I tried is 4.56MB on my computer and 8.24MB on the server. When I load the picture in Photo, it states "We can't open this file." The page location is at http://troop7bhac.com/pages/slideshowedit.aspx. The following is the VB.NET code behind the upload:
Sub uploadFile_Click(sender As Object, e As EventArgs)
lblUploadErrors.InnerHtml = ""
If (lstSlideshowChoose.SelectedValue = "") Then
lblUploadErrors.InnerHtml = "<p>A slideshow must be selected.</p>"
Else
If (FileUpload1.HasFile) Then
Dim nameList() As String
Dim successList() As String
Dim i As Integer = 0
For Each file As HttpPostedFile In FileUpload1.PostedFiles
Dim fileBytes() As Byte = Nothing
Dim fileName As String = Path.GetFileName(file.FileName)
Dim photoRE As New Regex("^[A-z0-9 _]{1,}\.jpg|JPG|jpeg|JPEG|png|PNG+$")
Dim photoSuccess As Boolean = photoRE.Match(fileName).Success
ReDim Preserve nameList(i)
ReDim Preserve successList(i)
If (photoSuccess = True) Then
Using fileStream As New StreamReader(file.InputStream)
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd())
fileStream.Close()
End Using
Try
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(ftpPath & lstSlideshowChoose.SelectedValue & "/" & fileName), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.Credentials = New NetworkCredential(ftpUser, ftpPass)
Using uploadStream As Stream = request.GetRequestStream()
uploadStream.Write(fileBytes, 0, fileBytes.Length)
uploadStream.Close()
End Using
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
response.Close()
successList(i) = "Success "
Catch ex As Exception
successList(i) = "Failed "
End Try
Else
successList(i) = "Failed "
End If
nameList(i) = fileName
i += 1
Next
For x As Integer = 0 To nameList.Count - 1
lblUploadErrors.InnerHtml += "<p>" & successList(x) & nameList(x) & "</p>"
Next
Else
lblUploadErrors.InnerHtml = "<p>You have not selected a picture to upload.</p>"
End If
End If
End Sub
The files are obtained through an ASP.NET FileUpload control. The control has been set to allow multiple files at once.
Any help to figure out why the pictures are not uploading properly would be greatly appreciated.
EDIT: I tried Martin Prikryl's possible duplicate solution. Had to change it from C# to VB.NET. It failed. I tried David Sdot's solution and it also failed. Both solutions returned the same errors.
If the page was ran on my local machine, it returned "C:\Program Files (x86)\IIS Express\PictureName.JPG." If the page was ran on the server, it returned "C:\Windows\SysWOW64\inetsrv\PictureName.JPG." Both errors are of the System.IO.FileNotFoundException class.
Your Problem is here:
Using fileStream As New StreamReader(file.InputStream)
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd())
fileStream.Close()
Using
Your image is read as text. From this text you get the bytes UTF8 byte values, thats why your image is nearly twice the size when uplaoded. You need the bytes from the image, without converting them to something else.
fileBytes = File.ReadAllBytes(file.FileName)
On a few of the Classic ASP websites I manage for the last few days I have been getting some error notifications (with no error number) that always show an error on a line number where a cookie value is being requested.
Looking at the request for each of these errors, they all have unusual cookies, and look like some sort of hack attempt.
The lines that are indicated as causing the error are all like this:
strCookieCart = Request.Cookies("cart")
Here's a couple of samples of the cookies being sent (truncated)... Note the =true (no name, just a value).
HTTP_COOKIE:=true; yuv=u97Yoe-o0UWp7ho_vaB2csT-xxaQ37gMWzhB1MARTSNk1QKpjJTXmZYMRQ095rM96MaNbhx1tEdJ
HTTP_COOKIE:pll_language=en; =true; yandexuid=6536735381437958890; st=6c9838994ffb
Is Classic ASP incapable of handling these? Is there any way to avoid these errors and ignore the bad values? Are these always likely to be hack attempts or could there be legitimate requests without cookie names?
I suppose I could check for these looking at Request.ServerVariables("HTTP_COOKIE") by manually parsing or using a regular expression check of some sort. Does anyone else do this? Any code to share?
A second answer to my own question and the solution I have now implemented is to add the following code to my common include file.
It tests whether Classic ASP can read the cookies and, using error trapping, ends the response if an error is detected.
On Error Resume Next
Request.Cookies("test")
If Err.Number <> 0 Then Response.End
On Error Goto 0
This is a better solution to my other answer as there is no point in generating a page for what is obviously an attack of some sort so ending the script as soon as possible is a better choice.
My proposed answer to my own question is to create a class that extracts all the valid keys and values for the cookies on initialisation, and has a function to return a value for a specified key.
Unfortunately it doesn't work for cookies that contain a collection of multiple values, but I don't generally use these anyway.
Here is the class:
<%
Class MyRequest
Private m_objCookies
Private Sub Class_Initialize()
Dim strCookies, i, strChar, strName, strValue, blnInValue
strCookies = Request.ServerVariables("HTTP_COOKIE")
Set m_objCookies = Server.CreateObject("Scripting.Dictionary")
i = 1
strName = ""
strValue = ""
blnInValue = False
Do
strChar = Mid(strCookies, i, 1)
If strChar = ";" Or i = Len(strCookies) Then
strValue = Trim(strValue)
If strName <> "" And strValue <> "" Then
If m_objCookies.Exists(strName) Then
m_objCookies.Item(strName) = strValue
Else
m_objCookies.Add strName, strValue
End If
End If
If i = Len(strCookies) Then Exit Do
strName = ""
strValue = ""
blnInValue = False
ElseIf strChar = "=" Then
strName = Trim(strName)
blnInValue = True
ElseIf blnInValue Then
strValue = strValue & strChar
Else
strName = strName & strChar
End If
i = i + 1
Loop
End Sub
Public Function Cookies(strKey)
Cookies = m_objCookies.Item(strKey)
End Function
End Class
%>
The changes to my code to use this class are minimal. Where I currently have...
strCookieCart = Request.Cookies("cart")
I will need to change to...
Dim objMyRequest : Set objMyRequest = New MyRequest
strCookieCart = objMyRequest.Cookies("cart")
I have tested the above with many of the bad requests I have logged and it works fine.
Add three line codes for #johna is answer, after this line:
If strChar = ";" Or i = Len(strCookies) Then
add these lines:
If i = Len(strCookies) And strChar <> ";" Then
strValue = strValue & strChar
End If
i'm trying to generate a report and export it to pdf in a loop, the report will receive a new parameter in each loop and prompt the client to download a PDF, in other words, the client may need to download 2 or 3 (or more) PDFs at the same time, the problem is that the prompt to accept the download only appears for the first pdf, dont know why. I can export to disk (server side) without any problems.
Code:
Sub PrintReport(ByVal Cod As Integer)
Dim CTableLogInfo As TableLogOnInfo
Dim ConnInfo As CrystalDecisions.Shared.ConnectionInfo = New ConnectionInfo()
ConnInfo.Type = ConnectionInfoType.SQL
ConnInfo.ServerName = ConfigurationManager.AppSettings("SQLSERVERNAME")
ConnInfo.DatabaseName = ConfigurationManager.AppSettings("SQLDBNAME")
ConnInfo.UserID = ConfigurationManager.AppSettings("SQLSERVERUSER")
ConnInfo.Password = ConfigurationManager.AppSettings("SQLSERVERPASSWORD")
ConnInfo.AllowCustomConnection = False
ConnInfo.IntegratedSecurity = False
For Each CTable As Table In CrystalReportSource1.ReportDocument.Database.Tables
CTable.LogOnInfo.ConnectionInfo = ConnInfo
CTableLogInfo = CTable.LogOnInfo
CTableLogInfo.ReportName = CrystalReportSource1.ReportDocument.Name
CTableLogInfo.TableName = CTable.Name
CTable.ApplyLogOnInfo(CTableLogInfo)
Next
Dim pField As ParameterField = CrystalReportSource1.ReportDocument.ParameterFields(0)
Dim val1 As ParameterDiscreteValue = New ParameterDiscreteValue
val1.Value = Cod
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
Dim PDFName As String = "PDF Nº " & Cod
CrystalReportSource1.ReportDocument.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Page.Response, True, PDFName)
End Sub
EDIT:
Tried to zip the reports with DotNetZip but i get an broken zip.
Can you tell me whats wrong? (Solved: code bellow is corrected now)
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/zip"
Response.AppendHeader("content-disposition", "attachment; filename=AllPDFs.zip")
Using zipFile As New ZipFile()
For i = 0 To Cod.Length - 1
If Cod(i) > 0 Then
val1.Value = Cod(i)
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
val2.Value = Cod(i)
pField2.CurrentValues.Clear()
pField2.CurrentValues.Add(val2)
Dim PDFNameAs String = "PDF Nº " & Cod(i) & ".pdf"
Dim s As New System.IO.MemoryStream
s =CrystalReportSource1.ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat)
zipFile.AddEntry(PDFName, s)
End If
Next
zipFile.Save(Response.OutputStream)
End Using
Response.Clear()
Probably the response ends after the first one, therefore there's no response to write to for the 2nd and 3rd attempts.
Instead, you can have the client download the reports via AJAX Request (move your report generation into an .ashx generic handler), or have the user click the button 3 times to initiate new requests.
Or zip the PDF's up until a single file and allow the client to download that.
i have an interactive aspx dialog with some address data (like name, email, address,...). Now i want the user to be able by clicking a button to download the address data as vcf file.
Now, generating the vcf compatible string isn't the problem. But saving it to the client is.
While it returns the vcf string just fine, it does not open a "Save AS"-dialog. Below i attached my logic for the file download.
What am i doing wrong?
(Maybe it's worth mentioning that the code-behind function calls come from java script,...)
Thanks for any helpfull answers in advance.
Public Sub SaveText(ByVal Text As String)
Dim FileName As String = System.IO.Path.GetRandomFileName()
Using sw As New System.IO.StreamWriter(Server.MapPath(FileName + ".txt"))
sw.WriteLine(Text)
sw.Close()
End Using
Dim fs As System.IO.FileStream = Nothing
fs = System.IO.File.Open(Server.MapPath(FileName + ".txt"), System.IO.FileMode.Open)
Dim btFile(fs.Length) As Byte
fs.Read(btFile, 0, fs.Length)
fs.Close()
With HttpContext.Current.Response
.Clear()
.Buffer = True
.Expires = 0
.AddHeader("Content-disposition", "attachment;filename=" + FileName)
.AddHeader("Content-Length", btFile.Length.ToString)
.ContentType = "application/octet-stream"
.BinaryWrite(btFile)
'.OutputStream.Write(btFile, 0, btFile.Length())
.Flush()
.End()
End With
End Sub
Ok, the problem was not the above mentioned logic itself. The way i handeled the response on the client side was just wrong. The calling java script function expected something else.
I would elaborate in more detail, but this stuff here is so home grown and proprietary, it wouldn't make any sense.
Cheers.