C# ASP.NET Retrieving file address in string - c#

I am building a method that will build an XLS file and uploading it on user's computer.
I am using this guide:
http://csharp.net-informations.com/excel/csharp-create-excel.htm
So code that will define my destination address is:
xlWorkBook.SaveAs("C:\\Something\\csharp-Excel.xls", Excel.XlFileFormat.xlWorkbookNormal);
Now it is default, but i want to allow user to define it by him self, so as far as i understand, i need an html field, which will open common "browse window" and save file path to string, which will be later used in xlWorkBook.SaveAs function. I have read a bit about FileUpload, but i don't really sure that it is what i am looking for.

The code that you have there will save the file on the web server itself, not on the user's computer. You'll need to stream the file down to the user via the browser, and then they will be able to choose where to save it.
You could save the file on the server and then stream it to the user using Response.WriteFile, or you could stream it from memory if you don't want to keep a copy of the file on the server.

This code will create a file on the server, not on the users/clients computer. If you want the user to be able to download the file to his/her computer and select the location where the file is stored, you need to create a file (.aspx file or controller method, depending on wether you are using webforms or MVC) and have it stream the file to the user's browser. The browser will then take care of displaying the "Save as" dialog where the user can select the destination location.

Related

Automatically uploading a file to Google Drive File Stream with a Windows Service

I have made a Windows service that;
Downloads a CSV file from a regularly updated internal database through a WebClient every hour.
Put that CSV file into a designated folder.
In the original test case, it was put into a local folder on my desktop (C:).
The test case worked perfectly.
The CSV would replace the old file with the newly downloaded one with the same name.
As listed above. This works perfectly on a local folder. However, we intend for it to work through Google Drive File Stream. As we have a Google Sheet that manipulates and sought the data for us for any CSV file that is under the given name.
This is the current method of downloading and placing the file.
public void CSVDownload()
{
string url = #"YOUR_CSV_URL_HERE";
WebClient client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(url), #"YOUR_GOOGLE_DRIVE_FILE_STREAM_FOLDER_HERE\NAME.csv");
void client_DownloadFileCompleted(object CSVDownload, AsyncCompletedEventArgs e)
{
eventLog1.WriteEntry("CSV File (NAME.csv) downloaded");
}
}
My question is why can't I currently automatically upload a file to Google Drive File Stream through a Windows Service? Is it because Google Drive File Stream requires certain permissions or actions? Is it because the drive is "virtual" and not physical (H:)? Below is the folder I am trying to upload to in Google Drive File Stream (H:\My Drive\Test).
The code also runs through completely as the log files show that the methods are used. However, there seems to be some block between the download and placing of the CSV file in a Google Drive File Stream folder.
Update: There has been little progress so far. One of my colleagues maybe suggests that there needs to be some sought of user permission to push. Like a username and password. If this is true does anyone know how I could achieve this?
Update #2: In the 'Registry Editor' I found some interesting info.
Press Windows + R
Type regedit.exe
HKEY_CURRENT_USER -> SOFTWARE -> Google -> DriveFS -> Share
As you can see there are two values. 'MountPoint = H' is obviously the drive letter it is mapped to and 'ShellIpcPath = \\.\Pipe\GoogleDriveFSPipe_user.name_shell' which might be useful. I played around with ShellcpPath but to no prevail.
Update #3: #Ben Voigt mentioned to use DriveInfo.GetDrives() to see if the drive is found by the service. I run the code and it looks like it does exist.
Here is what the console spit out:
Drive H:\
Drive type: Fixed
Volume label: Google Drive File Stream
File system: FAT32
Available space to current user: 15987068928 bytes
Total available space: 15987068928 bytes
Total size of drive: 16106127360 bytes
As you can see it exists however it uses File system: FAT32 instead of File system: NTFS which all my other drives use (C:),(D:),etc. So it seems that only Google Drive File Stream uses FAT32.
Test Case:
Works perfectly when placing the CSV files into a local folder.
client.DownloadFileAsync(new Uri(url), #"C:\Users\user.name\Desktop\Test\designtasks.csv");
client.DownloadFileAsync(new Uri(url), #"C:\Users\user.name\Desktop\Test\designjobs.csv");
Does not work when placing into a Google Drive File Stream folder.
client.DownloadFileAsync(new Uri(url), #"H:\My Drive\Test\designtasks.csv");
client.DownloadFileAsync(new Uri(url), #"H:\My Drive\Test\designjobs.csv");
To clarify about the test case. I am actually getting two CSV files. However, the code is basically the same. So I only mention getting one in my original question to keep it cleaner and more straightforward.
I found the solution! It might not be optimal for all cases however it works in my case.
Here is what I did;
Make a project installer with InstallerProjects.vsiz. Obviously, if you are using a different version of VS, this might change. Some of the older version already come with it installed and the newer versions do not automatically include it. You will have to also find the correlating version as the one linked is for VS2017. Here is a tutorial on how to implement an installer on a windows service.
Once you have implemented the installer, right click on serviceProcessInstaller1 (or whatever you decided to call it) and select properties.
In the properties window, look a for the 'Account' field and set it to 'User'.
Save and build you project. That's it.
What does's this actually do? In plain English; It basically makes the service impersonate a user so it can read and write files on the system.
When installing on a different computer from which the service was built on, 'Windows Defender Shield' will block the service from installing. This is just Windows bring cautious. Obviously, if you built the service without ill intent this will not harm your computer.
To continue installation click "More info" on the 'Windows Defender Shield' screen and click "Run anyway".
Before the Service finishes installing, it will stall and ask for user information. In most use cases, giving it your own user information ill suffice.
If you are a user on a domain or anything along those lines. You will need to add the domain prefix to the 'Username' field. Example: DOMAIN\user.name.

How do you open a file that is stored as blob in the db (SQL server) in new browser window?

When opening a file in new browser window that is stored in the file system with the url stored in the database, the solution is simple with the javascript method:
[var windowObjectReference = window.open(strUrl, strWindowName\[, strWindowFeatures\]);][1]
However, when storing files as blob in the database (SQL Server) there is no url pointing to the file. What is the best practice for retrieving the file for the user? Do I need to copy the file to a temp folder and then provide the url dynamically? Then delete the file after a certain point?
I know that storing the file in the file system would be easier to code, but I have chosen to store it as a blob for all the benefits that come with a DBMS.
Thanks for your help
Your web server will have to write the BLOB's bytes to a response stream, plus an appropriate Content-Type and Content-Length header so that the browser knows how to treat those bytes. Use a tool like Fiddler and browse to google.com. You can see what Google's responses contains for images on the page. Your goal is to generate a response in a similar fashion.

How to get file path and name to save this file?

I use open XML to export excel file. SpreadsheetDocument.Create requires a file destination.
I want to get this file destination from user similar to a SaveFileDialog in Winforms.
How I get file destination from user? I use Asp.Net 4.0 and OpenXML SDK 2.5 .
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);
For this functionality even if you use open/save dialog, it would show the client locations not the server locations. So here question is, do you want to save that file to the client machine or at the server machine?
If you want to save it to client machine then first save it on the server by any name and location you want and then initiate a download after that. It will automatically prompt download dialog in the client browser and there user would be able to select the location and filename (depending on the client browser settings).
If you want to save it only on server then just before generating the spreadsheet, prompt user for entering the filename (on the page from where the request is generated). If some of your folders are accessible to user then you can also prompt user to select one of the folders, otherwise choose one as per your choice/requirement. Use the filename and the location to generate the spreadsheet.
when a webserver is streaming a file down to the client, you don't have control of the destination folder. All you can do is:
specify the contents type (to aid client in determining how to handle)
specify filename
(I think) tell the client browser to save the file vs. displaying it automatically in the registered application (for example, PDFs usually display in the browser, but setting up the streaming correctly could force Save File dialog instead)
If you need to "cache" the file ion the web server, you export to a server folder that your server process has write permissions to. Then you stream to the client - the client will get the prompt from their browser and save where they want.
Look at Server.MapPath for example - it'll map virtual path to physical on your server. the question of permissions remains.
Depending on your particular case, you may be able to avoid saving to the server, if the export library has a way of returning a byte array or a stream, instead of saving to a file. In that case you just stream the return result to requester.
I am not familiar with the SDK you're using, but quick googling reveals this method of returning the document in a stream:
using (MemoryStream stream = new MemoryStream())
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook, true))
{
... work with the spreadsheetDocument, if needed
... prepare and stream to browser
}
}
Here's one of the references to your SDK I found
Use Environment.SpecialFolder enumerations. If you are looking for my documents then:
var destination = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);

C# Upload Files on another partition of the server

I'm using FileUpload.SaveAs() function of C# to upload files to the server but I want to save the files on another partition. Let us say, save the files on Drive D of the server instead on the current drive which is Drive C. Please share your thoughts. Thanks is advance.
I have learned that using full path such as
FileUpload.SaveAs("D:\FileUpload");
will save the file outside the web server.
Check this out.
To simplify the question, how can I upload files on the other partition of the server that hosts my web app?
Based on the documentation from http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.saveas.aspx, the String filename is the full path name of the location to save. Meaning you should be able to do so e.g:
FileUpload.SaveAs("D:\where_you_want_to_save")
By the way what have you tried and what error did you get?
Looking at the example on MSDN, it would appear that .SaveAs() accepts a fully qualified file name as a parameter. You could potentially use a Path object to cleanly build a path for the file, or just specify one directly as a string:
uploader.SaveAs("d:\\someFolder\\someFile.ext");
Resolved this by using Virtual Directory of IIS and providing admin credentials for authentication

How to check if a file exists on the web server

I have a file stored on the server and the web page I am populating depends on the fatc that the file exists or not.
How do I test if the file is available on the server?
The file comes on the web page as:
http://main.server.com/PGT/Reports/ObjectsReport.xml
I have to test the existence of this file and if it is available I will display a link otherwise I want to hide the link.
The actual path to the server is
//main.server.com/inetpub/wwwroot/PGT/Reports/ObjectsReport.xml
but I don't have access to the server (and therefore to the file) on the network. I can only access it using the web page. Is there a way to test that the server has the file or not display the link? (hlObjectsReport.Visible = false;)
I have tried to use the following:
Uri validatedUri;
Uri.TryCreate(uri, UriKind.RelativeOrAbsolute, out validatedUri);
But it returns a valid address even if the file is not there.
Thanks
Tony.
use System.IO.File.Exists() (Documentation)
if(System.IO.File.Exists([path goes here]))
{
// do something
}
If you're not sure of the physical path, you can substitute the following for [path goes here] above:
Server.MapPath(/PGT/Reports/ObjectsReport.xml)
(Documentation)

Categories