I'm having an issue using Excel Data Reader's IExcelDataReader to read an HttpPostedFileBase Excel file in conjunction with the AWS SDK API to upload the same Excel file. Validation occurs to determine whether the file should be uploaded or merely used in a data table, and if validation passes, an empty Excel file of 0 Kb is always uploaded.
I've tried: closing and disposing the IExcelDataReader before using the file's InputStream; creating a new Stream and uploading that; resetting the position of the InputStream; and checking this site for similar questions. Also, placing the upload before the validation uploads the full document, but then the subsequent IExcelDataReader throws the "can't use a disposed object" error.
Does anyone know how to reuse the file InputStream? Thanks in advance!
//If save to bucket area is here, upload works, but later logic fails on disposed object
IExcelDataReader uploadReader;
switch (uploadExtension)
{
case ".xls":
uploadReader = ExcelReaderFactory.CreateBinaryReader(UploadedFile.InputStream);
break;
case ".xlsx":
uploadReader = ExcelReaderFactory.CreateOpenXmlReader(UploadedFile.InputStream);
break;
default:
uploadReader = ExcelReaderFactory.CreateBinaryReader(UploadedFile.InputStream);
break;
}
DataSet excelUploadDataSet = uploadReader.AsDataSet();
var resultSheets = from DataTable sheet in excelUploadDataSet.Tables select sheet.TableName;
var excelSheets = resultSheets.ToList();
DataTable excelUpload = excelUploadDataSet.Tables[0];
int excelRows;
if ((string)excelSheets[0] != "Info")
{
//Tried everything in the problem here, to no avail
//Save to bucket area
using (var client = new AmazonS3Client(Amazon.RegionEndpoint.USWest1))
{
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketLocation,
Key = UploadedFile.FileName,
InputStream = UploadedFile.InputStream
};
PutObjectResponse response = client.PutObject(request);
}
}
else
{
//Other logic using data table/IExcelDataReader
}
You have code that reads from UploadedFile.InputStream
(thus seeking it to the end) and then you try to pass that stream (with position set to the end and hence without anything to read from it) to some other method. As PutObject
is not able to read anything from stream and sends empty data.
Possible fix - set position to 0 (see Stream.Seek(0, SeekOrigin.Begin) or Position = 0), but note that in many cases streams are not seekable (i.e. uploaded files in ASP.Net) - in such case you need to either read stream once or copy it locally (i.e. to MemoryStream
) to read multiple times.