Read file from database - sql

I am trying to download a file I have uploaded to an image field in my MS-SQL database. The problem is that when I try to open the file it just says System.Byte[] instead of containing the actual content.
UploadFiles is my class which contains the filename, id, filedata etc.
public void DownloadUploadedFile(Page sender, UploadFiles uf)
{
sender.Response.Clear();
sender.Response.ContentType = uf.FileType;
sender.Response.AddHeader("Content-Disposition",
"attachment; filename=" + uf.FileName);
sender.Response.BinaryWrite(uf.FileData); // the binary data
sender.Response.End();
}
Here I retrieve the data from my database:
while (reader.Read())
{
UploadFiles uf = new UploadFiles();
uf.FileData = encoding.GetBytes(reader["filedata"].ToString());
uf.FileName = reader["name"].ToString();
uf.FileType = reader["filetype"].ToString();
uf.FileId = Convert.ToInt32(reader["id"]);
return uf;
}

The
uf.FileData = encoding.GetBytes(reader["filedata"].ToString());
should be
uf.FileData = (byte[])reader["filedata"];
The data returned is a byte array, and you call ToString() on the byte array, which just defaults to returning the class name (system.byte[]) - which you then convert to a byte array. It should just be cast right away

Try uf.FileName.ToString(), otherwise you're getting the object type, not the FileName property text.

Related

SSRS/ASP.NET Setting all required report input parameters but still getting:One or more parameters required to run the report have not been specified

Although this has been asked before, none of the answers provided solve my issue. I AM passing in all of the required report parameters and all have HasValidValue set in the State property of the parameter array of ExecutionInfo. I am using ReportExecution2005.asmx in my ASP.NET web application. There is no GetParameters() call method to ReportExecution2005.ReportExecutionService object.
My report is calling a subreport so the input parameters are identical to the main report and the subreport. There are 4 single value inputs (two integer, two text) and then one Multivalue text input parameter which I supply multiple values for. I have double and tripled checked that the values I'm setting in the Multivalue input parameter match exactly one of the default parameters.
Here is the code that setups up the reports and renders/writes it out to a PDF file:
protected void btnPrintReq_Tests_Click(object sender, EventArgs e)
{
string query = string.Format("SELECT PatientFName, PatientLName, Address1 + ' ' + Address2 AS Address, City, Region AS State, PostalCode, Email, Phone, Gender, DOB, CONVERT(VARCHAR, ClinicID) AS ClinicID FROM Tbl_ShippingDropShip WHERE RequestID = {0}", giRequestID.ToString());
string sClinicID = string.Empty;
try
{
//get the drop ship test order details
SqlDataReader reader = default(SqlDataReader);
reader = o_cSQL.RunSQLReturnDataReader(query);
REService.ReportExecutionService rs_ext = new REService.ReportExecutionService();
rs_ext.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs_ext.Url = ConfigurationManager.AppSettings["ReportExecutionServer"];
List<string> ordereditems = new List<string> { };
ordereditems = GetOrderedItems(); //panels and profiles
int numordereditems = ordereditems.Count;
List<String> comments = new List<String>();
if (cbIce.Checked)
comments.Add("Ice");
if (cbKit.Checked)
comments.Add("Kit");
if (cbSwabs.Checked)
comments.Add("Swabs");
if (cbGoldTop.Checked)
comments.Add("Gold Top");
if (cbNeedlePack.Checked)
comments.Add("Needle Pack");
if (cbButterflyPack.Checked)
comments.Add("Butterfly Pack");
if (comments.Count == 0)
comments.Add("");
byte[] result = null;
string historyID = null;
string devInfo = null;
string encoding;
string mimeType;
string extension;
REService.Warning[] warnings = null;
string[] streamIDs = null;
//define the size of the parameter array to pass into the REService
REService.ParameterValue[] rValues = new REService.ParameterValue[4 + numordereditems];
while (reader.Read())
{
sClinicID = reader["ClinicID"].ToString();
rValues[0] = new REService.ParameterValue();
rValues[0].Name = "ClinicID";
rValues[0].Value = sClinicID;
rValues[1] = new REService.ParameterValue();
rValues[1].Name = "ReqFormID";
rValues[1].Value = giRequestID.ToString();
rValues[2] = new REService.ParameterValue();
rValues[2].Name = "DropShipID";
rValues[2].Value = giDropShipID.ToString();
rValues[3] = new REService.ParameterValue();
rValues[3].Name = "Comments";
rValues[3].Value = string.Join(",",comments.ToArray());
int j = 0;
for (int i = 4; i < rValues.Length; i++)
{
rValues[i] = new REService.ParameterValue();
rValues[i].Name = "PanelsNProfiles";
rValues[i].Label = "Panels and Profiles :";
rValues[i].Value = ordereditems[j++];
}
}
REService.ExecutionInfo res_info = new REService.ExecutionInfo();
res_info = rs_ext.LoadReport("/zReportSandbox/RequisitionDS", historyID);
res_info = rs_ext.SetExecutionParameters(rValues, "en-us");
res_info = rs_ext.GetExecutionInfo();
result = rs_ext.Render("PDF", devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
string pdfFile = "Requisition_" + giRequestID.ToString() + "_"+ txtPatientName_Edit.Text + ".pdf";
string sPDFSavePath = ConfigurationManager.AppSettings["Shipping_Requisitions"] + sClinicID;
//add the date pathing
sPDFSavePath = ReportHelper.CreateDateDirectories(sPDFSavePath);
//make sure the file doesn't already exist and if it does, delete it so we create a new one
ReportHelper.checkPDFfilesNDirectory(sPDFSavePath +#"\", pdfFile);
FileStream stream = File.Create(sPDFSavePath + #"\" + pdfFile, result.Length);
stream.Write(result, 0, result.Length);
stream.Close();
}
catch(Exception ex)
{
Common.CommonUtilities.FatalError(sPageName, "btnPrintReq_Tests_Click", query, ex.Message.ToString(), ex.ToString());
}
}
I have noticed that the ExecutionInfo item shows me all parameters in the array of the report, meaning the required INPUT parameters AND the INTERNAL parameters, but also noticed that for the INTERNAL parameters, the default value that was set in the report is satisfied and ExecutionInfo shows them with the State of HasValidValue.
The following list is what I know
the report works on its own, so the Main report that calls the Subreport has no issues creating the PDF
there report when run in SSRS does prompt for the 4 input parameters
I have tried the removal of the report in SSRS and redeployed it because there were many that suggested this somehow fixes issues like this.
I have tried the Insert a table, delete the columns and put subreport in one cell of table trick and still the same error.
It would be nice if the error would state what parameter it sees as not being satisfied, even if there are more than one, then simply listing the first one before erroring out would help a developer work through the issues.
The attached picture shows the values I'm passing in for the multivalue parameters (PanelsNProfiles). I'm also attaching my RDL files for the main report and the Subreport, but had to add a (.txt) file extension to them to be able to upload them.
Here is the error in the SSRS execution log:
library!ReportServer_0-57!5250!03/23/2022-09:06:27:: i INFO: RenderForNewSession('/zReportSandbox/RequisitionDS')
processing!ReportServer_0-57!5250!03/23/2022-09:06:27:: e ERROR: Throwing Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: , Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: One or more parameters required to run the report have not been specified.;
reportrendering!ReportServer_0-57!5250!03/23/2022-09:06:27:: e ERROR: Throwing Microsoft.ReportingServices.ReportProcessing.RenderingObjectModelException: , Microsoft.ReportingServices.ReportProcessing.RenderingObjectModelException: One or more parameters were not specified for the subreport, 'RequisitionTopDS', located at: /zReportSandbox/RequisitionTopDS.;
processing!ReportServer_0-57!5250!03/23/2022-09:06:27:: e ERROR: An error has occurred while processing a sub-report. Details: One or more parameters were not specified for the subreport, 'RequisitionTopDS', located at: /zReportSandbox/RequisitionTopDS. Stack trace:
at Microsoft.ReportingServices.OnDemandReportRendering.SubReport.FinalizeErrorMessageAndThrow()
at Microsoft.ReportingServices.OnDemandReportRendering.SubReport.RetrieveSubreport()

Index was out of range exception when attempting to access Worksheets object

I have an .XLSX created by a 3rd party. I can read it in Excel just fine, however if I try to read it with EPPlus, I get the following exception:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at OfficeOpenXml.Style.ExcelStyle..ctor(ExcelStyles styles, ChangedEventHandler ChangedEvent, Int32 positionID, String Address, Int32 xfsId)
at OfficeOpenXml.Style.XmlAccess.ExcelNamedStyleXml..ctor(XmlNamespaceManager NameSpaceManager, XmlNode topNode, ExcelStyles styles)
at OfficeOpenXml.ExcelStyles.LoadFromDocument()
at OfficeOpenXml.ExcelStyles..ctor(XmlNamespaceManager NameSpaceManager, XmlDocument xml, ExcelWorkbook wb)
at OfficeOpenXml.ExcelWorkbook.get_Styles()
at OfficeOpenXml.ExcelWorkbook.get_MaxFontWidth()
at OfficeOpenXml.ExcelWorksheet.get_DefaultColWidth()
at OfficeOpenXml.ExcelWorksheet.LoadColumns(XmlReader xr)
at OfficeOpenXml.ExcelWorksheet.CreateXml()
at OfficeOpenXml.ExcelWorksheet..ctor(XmlNamespaceManager ns, ExcelPackage excelPackage, String relID, Uri uriWorksheet, String sheetName, Int32 sheetID, Int32 positionID, eWorkSheetHidden hide)
at OfficeOpenXml.ExcelWorksheets..ctor(ExcelPackage pck, XmlNamespaceManager nsm, XmlNode topNode)
at OfficeOpenXml.ExcelWorkbook.get_Worksheets()
If I open the file in Excel and then save it as a new file, EPPlus can read the file just fine. Obviously, this is not a solution that is reasonable for the end users of my system.
I can send the file to the developers if they need, or I can provide more diagnostic information if needed and available.
I'm going to check in with the developers of the other app to try to figure out what API they are using to generate the .XLSX.
code:
using (var package = new ExcelPackage(importEquipmentFile.InputStream))
{
foreach (var ws in package.Workbook.Worksheets.Where(ws => ws.Hidden == eWorkSheetHidden.Visible))
...
and this simplified blows up too:
using (var package = new ExcelPackage(importEquipmentFile.InputStream))
{
foreach (var ws in package.Workbook.Worksheets)
...
Here's the problem. In the code below
positionID = -1 and _styles.CellStyleXfs list is empty, so the "else" gets called
internal ExcelStyle(ExcelStyles styles, OfficeOpenXml.XmlHelper.ChangedEventHandler ChangedEvent, int positionID, string Address, int xfsId) :
base(styles, ChangedEvent, positionID, Address)
{
Index = xfsId;
ExcelXfs xfs;
if (positionID > -1)
{
xfs = _styles.CellXfs[xfsId];
}
else
{
xfs = _styles.CellStyleXfs[xfsId];
}
and that throws an exception because the code that's called can't handle an empty list.
public T this[int PositionID]
{
get
{
return _list[PositionID]; // <<<--- this blows up because _list has no members
}
}
I tweaked the code to be this, and it worked OK, but I'm not sure of the best way to deal with that list being empty:
if (positionID > -1 || _styles.CellStyleXfs.Count == 0)

How to save Excel Table as a Picture using vb.net?

I'm trying to save tables from excel sheets as pictures. Is there a way to just put that table on the clipboard and save it? This is what I've got so far but the library referenced is not there?
Thank you in advance!
-Rueben Ramirez
Public Sub extract_excelTable(ByRef data_file As String, ByRef app1 As excel.Application, ByRef sheet_name As String)
'defining new app to prevent out of scope open applications
Dim temp_app As excel.Application = app1
Dim workbook As excel.Workbook = temp_app.Workbooks.Open(Path.GetFullPath(data_file))
temp_app.Visible = False
For Each temp_table As excel.DataTable In workbook.Worksheets(sheet_name)
temp_table.Select()
'temp_app.Selection.CopyAsPicture?
Next
End Sub
I'm not going to write any code here, but I will outline a solution for you that will work. Note that this will not reproduce the formatting of the excel document, just simply get the data from it, and put it on an image in the same column/row order as the excel file.
STEP 1:
My solution to this problem would be to read the data from the excel file using an OLEDB connection as outlined in the second example of this post: Reading values from an Excel File
Alternatively, you may need to open the document in excel and re-save it as a CSV if it's too large to fit in your computer's memory. I have some code that reads a CSV into a string list in C# that may help you:
static void Main(string[] args)
{
string Path = "C:/File.csv";
System.IO.StreamReader reader = new System.IO.StreamReader(Path);
//Ignore the header line
reader.ReadLine();
string[] vals;
while (!reader.EndOfStream)
{
ReadText = reader.ReadLine();
vals = SplitLine(ReadText);
//Do some work here
}
}
private static string[] SplitLine(string Line)
{
string[] vals = new string[42];
string Temp = Line;
for (int i = 0; i < 42; i++)
{
if (Temp.Contains(","))
{
if (Temp.Substring(0, Temp.IndexOf(",")).Contains("\""))
{
vals[i] = Temp.Substring(1, Temp.IndexOf("\",", 1) - 1);
Temp = Temp.Substring(Temp.IndexOf("\",", 1) + 2);
}
else {
vals[i] = Temp.Substring(0, Temp.IndexOf(","));
Temp = Temp.Substring(Temp.IndexOf(",") + 1);
}
}
else
{
vals[i] = Temp.Trim();
}
}
return vals;
}
STEP 2:
Create a bitmap object to create an image, then use a for loop to draw all of the data from the excel document onto the image. This post had an example of using the drawstring method to do so: how do i add text to image in c# or vb.net

WiX: Extracting Binary-string in Custom Action yields string like "???good data"

I just found a weird behavior when attempting to extract a string from the Binary table in the MSI.
I have a file containing Hello world, the data I get is ???Hello world. (Literary question mark.)
Is this as intended?
Will it always be exactly 3 characters in the beginning?
Sample code:
[CustomAction]
public static ActionResult CustomAction2(Session session)
{
View v = session.Database.OpenView("SELECT `Name`,`Data` FROM `Binary`");
v.Execute();
Record r = v.Fetch();
int datalen = r.GetDataSize("Data");
System.IO.Stream strm = r.GetStream("Data");
byte[] rawData = new byte[datalen];
int res = strm.Read(rawData, 0, datalen);
strm.Close();
String s = System.Text.Encoding.ASCII.GetString(rawData);
// s == "???Hello World"
return ActionResult.Success;
}
Wild guess, but if you created the file using Notepad, couldn't that just be your byte order mark?
Try
String s = System.Text.Encoding.UTF8.GetString(rawData);
if (s.Length > 0 && s[0] == '\uFEFF')
{
s = s.Substring(1);
}
instead of String s = System.Text.Encoding.ASCII.GetString(rawData);

How do I save RichTextBox content into SQL varbinary (byte array) column?

I want to save content of a RichTextBox to varbinary (= byte array) in XamlPackage format.
I need technicial advise on how to it.
I actually need to know how to convert between FlowDocument to byte array.
Is it even recommended to store it as varbinary, or this is a bad idea?
Update
Code snippet:
///Load
byte[] document = GetDocumentFromDataBase();
RickTextBox tb = new RickTextBox();
TextRange tr = new TextRange(tb.Document.ContentStart, tb.Document.ContentEnd)
tr.Load(--------------------------) //Load from the byte array.
///Save
int maxAllowed = 1024;
byte[] document;
RichTextBox tb = new RichTextBox();
//User entered text and designs in the rich text
TextRange tr = new TextRange(tb.Document.ContentStart, tb.Document.ContentEnd)
tr.Save(--------------------------) //Save to byte array
if (document.Length > maxAllowed)
{
MessageBox.Show((document.Length - maxAllowed) + " Exceeding limit.");
return;
}
SaveToDataBase();
TextRange
I can't find my full example right now, but you can use XamlReader and XamlWriter to get the document into and out of a string. From there, you can use UnicodeEncoding, AsciiEncoding or whatever encoder you want to get it into and out of bytes.
My shorter example for setting the document from a string...
docReader is my flow document reader
private void SetDetails(string detailsString)
{
if (docReader == null)
return;
if (String.IsNullOrEmpty(detailsString))
{
this.docReader.Document = null;
return;
}
using (
StringReader stringReader = new StringReader(detailsString))
{
using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(stringReader))
{
this.docReader.Document = XamlReader.Load(reader) as FlowDocument;
}
}
}