Okay, this is different than other posts I'm seeing. I'm not trying to first open an Excel file and parse the contents into a Json object. I'm trying to take the file and convert it to a stream object of some sort or byte[] and then convert that to Json so I can use it as an input parameter to a POST method for a WebAPI.
Here is the full scenario.
I have clients that will use an internal-only website to select one or more Excel files. The workstations the users work on may or may not have Excel installed, thus, all of my Excel processing has to be done on the server. Once the Excel files are processed, they are combined into a System.Data.DataTable and the values are aggregated into one master report. This aggregated report needs to be returned to the client system so it can be saved.
I currently have this site working just fine in ASP.NET using C#. However, I need the "guts" of the website to be a WebAPI so that automation programs I have can make calls directly to the WebAPI and accomplish the same task that the internal-only website does. This will allow all processing for this sort of task to run through one code base (right now, there are about 4 versions of this task and they all behave differently, providing differing output).
The way I thought to do this was to, from the client, convert the Excel files to an array of System.IO.MemoryStream objects, then serialize the full array as a Json.NET stream and upload the stream to the webserver where it will be deserialized back into an array of MemoryStream. Once that is done, I can iterate the array and process each Excel file by the MemoryStream.
My problem is I can't figure out how to convert the MemoryStream[] into Json and then deserialize that up on the server.
Rather than trying to pass the excel file around as JSON let the user upload the file to the server and then process it from there.
In the JSON rather than giving the content of the file put a link to the file.
Related
As far as I know, in C#, Excel is sent over the wire as a binary array, along with some metadata that identifies it to the frontend/browser as an excel file:
return File(resultStream.ToArray(), contentType);
But is there a way I can return an excel spreadsheet AND an array of strings? The object would look something like this:
response {
document: [130,200,31,7,35,92...],
strings: ["alpha", "bravo", "charlie"...]
}
And then I suppose the frontend would have to take that document, parse it to an excel spreadsheet (?) and "give it to the browser" so it will actually download to the client's computer?
I considered having these be separate requests, but would rather keep it all in one request/response if possible.
I ended up sending the strings with some other data required to create the spreadsheet in the front end. Ideal? Maybe not. But it works(tm)
I've been given the task of writing automated tests that check our own API. Part of this process involves testing an end point that generates an Excel template that the recipient is then supposed to fill back out and submit back to us.
From the looks of things this template gets sent back to the user from within the browser using a FileContentResult object that also specifies the content type (application/vnd.ms-excel.sheet.macroEnabled.12; the intended file format is .xlsm).
The problem I have is this: whilst getting the file in terms of a byte array works without issue with regards to the call to the end point is concerned I have yet to successfully take that byte array returned and use it for anything useful. Creating an excel file from that seems to be problematic. Just using File.WriteAllBytes() doesn't seem to work for example nor does using a BinaryWriter.
Does anybody have any idea how to achieve this from within C# code that isn't running as part of a website?
We have a process that has SQL Server Reporting Services create a pdf file via
ReportExecutionService.Render
from data in the database. Then we save the byte array that Render returns to the database. Later I get the byte array and do a
File.WriteAllBytes
to write it to disk before attaching it to an email and sending it. The problem I'm running into is that after writing the file to disk, it is corrupt somehow. I'm not sure what to look at, can anyone help?
Thanks
EDIT:
I can write the file from SSRS to disk before saving the byte array to the database and I can view that fine.
If you work with the byte[] returned by render, then things are fine, but if once you write that to the DB and read it back, you have problems, correct?
Why don't you compare the array written in to the DB with the one you retrieve to find the problem? Then start looking into your DB write and read routines, finally your DB storage.
I've done similar things without problems, such as taking the results of a Reporting Services call into a bytestream and attaching that directly to an email, both using a memorystream and an on-disk file. So the basics of this are sound and should work.
Not sure if this is your issue or not, but if the PDF file itself is corrupt you might want to look at how it's being written. If Windows Preview can view the PDF but Adobe cannot, it may have to do with the fact that Adobe is expecting %PDF in the first 1024 bytes of the file (otherwise it will consider it corrupt).
I am writing an application that would download and replace a pdf file only if the timestamp is newer than that of the already existing one ...
I know its possible to read the time stamp of a file on a local computer via the code line below,
MessageBox.Show(File.GetCreationTime("C:\\test.pdf").ToString());
is it possible to read the timestamp of a file that is online without downloading it .. ?
Unless the directory containing the file on the site is configured to show raw file listings there's no way to get a timestamp for a file via HTTP. Even with raw listings you'd need to parse the HTML yourself to get at the timestamp.
If you had FTP access to the files then you could do this. If just using the basic FTP capabilities built into the .NET Framework you'd still need to parse the directory listing to get at the date. However there are third party FTP libraries that fill in the gaps such as editFTPnet where you get a FTPFile class.
Updated:
Per comment:
If I were to set up a simple html file with the dates and filenames
written manually , I could simply read that to find out which files
have actually been updated and download just the required files . is
that a feasible solution ..
That would be one approach, or if you have scripting available (ASP.NET, ASP, PHP, Perl, etc) then you could automate this and have the script get the timestamp of the files(s) and render them for you. Or you could write a very simple web service that returns a JSON or XML blob containing the timestamps for the files which would be less hassle to parse than some HTML.
It's only possible if the web server explicitly serves that data to you. The creation date for a file is part of the file system. However, when you're downloading something over HTTP it's not part of a file system at that point.
HTTP doesn't have a concept of "files" in the way people generally think. Instead, what would otherwise be a "file" is transferred as response data with a response header that gives information about the data. The header can specify the type of the data (such as a PDF "file") and even specify a default name to use if the client decides to save the data as a file on the client's local file system.
However, even when saving that, it's a new file on the client's local file system. It has no knowledge of the original file which produced the data that was served by the web server.
I am working on an application which has to retrieve data from a CSV file online
and display it with a click of a button. However, how can I automatically store
the CSV file in a safe place where I can access the information? I am working with Visual Studio C#.
Thank you.
You want to use the WebClient class to make an http request to the server for the csv file. It should read the whole contents as a string which you can then parse and manipulate at your leisure.
http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.100).aspx
Use System.IO.File to write the contents to a file.
http://msdn.microsoft.com/en-us/library/system.io.file.aspx
The FileHelpers are a free and easy to use .NET library to import/export data from fixed length or delimited records in files, strings or streams.
The FileHelpers Library
http://www.filehelpers.com/