download link give me filenotfound exception - asp.net

in my controller, this is the code i have
public FileResult Download(string file)
{
var vFullFileName = HostingEnvironment.MapPath("~/App_Data/Files/");
var files = uploadedfileRepository.AllIncluding();
string filename = (from f in files
select f.FileName).First();
return File(Path.Combine(vFullFileName, filename), "application/csv", filename);
}
I put the breakpoint and the file point to the right directory, but why still give me File not found exception?
and in my view this is what i have
<td>
#Html.ActionLink("Download", "Download", new { id = item.FileName})
</td

Your action method have a parameter with name file. But your are HTML will have a parameter/ query string called id, instead od file, So change your view code to
#Html.ActionLink("Download", "Download", new { file= item.FileName})
Also to get the path, try this
string fullFilePath=Path.Combine(Server.MapPath("~/App_Data"),filename)
return File(fullFilePath,"application/csv",filename);

App_Data is for database files that are accessed by MS SQL Server, and possibly your application's own data files (like a Lucene index).
IIS (and ASP.NET) are configured to block any client requests to that directory.
The solution is just to move the files to another directory. Just create a new folder in your site's root (say "CsvFiles") and link to that.
That said, why don't you serve up a HTTP 301 Redirection (or even a direct link) to the CSV files instead of serving them via your application?
UPDATE: This answer is incorrect because by serving the file contents via an MVC File response the user's browser doesn't acutally access the App_Data directory.

Related

How to retrieve asp.net media / resources based on logged in user?

I have an asp.net web api project using token based authentication. my app uploaded and retrieve images and I keep file path in table_myfiles along with the uploaded user ID.
I would like the user to access only the files he have uploaded, which I can identify from the table.
How to protect my resources to restrict access to only to the user based on table_myfile ? And not to anyone without logging in or direct link / path ?
I have been searching for any possible solution for a week now , I think I should implement a middleware to manage access. But I couldn’t find any resources on how to implement the same.
Currently my api shows all resources just by directly accessing the file path/link.
The simple apporach is to remove the vitural folder, or that folders from the web site folders. That way, no simple URL exists for any of the files.
So, for a user to get/see/use/download a file? You present say a listview or some kind of grid (or repeater) that displays and lists out the files.
Then, when they want to download or view a file?
You use response.write and stream the file down to the client side.
Remember, on the server, code behind uses 100% clean and correct windows file paths. For any web based URL, then that folder must be in a valid path of the web site. When they type in a valid URL, it eventually gets translated to that given folder in the site (or a external folder provided when you create a mapped "virtual" folder in IIS. However, if you don't provide that virtual folder, or the folder is NOT in the web site file/folder sets, then no valid URL's exist. However, that folder can be directly used and hit with code behind - any valid server path/folder name is allowed in code behind.
Because when streaming the file, you need path name, file name, AND ALSO the "mine" type. Thankfully, .net 4.5 or later has this ability.
so, from a database (table) I display the file names like this:
But, if you click on the preview image, that is a image button.
The code behind simply gets/grabs the file name from the database.
I then download (stream) the file to the browser side like this:
if (File.Exists(strInternalFullPath))
{
string strConType = MimeMapping.GetMimeMapping(strInternalFullPath);
binFile = File.ReadAllBytes(strInternalFullPath);
Response.ContentType = strConType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strWebUrl));
Response.BinaryWrite(binFile);
Response.End();
}
else
MyToast2(this, btnLink.ClientID.ToString, "File Not found", "We no longer have this file avaiable.");
so, this buttion behaves 100% like a link, but there are no existing URL's or path name that points to the files folder from a web based URL.
Remember:
Web based URLs - they auto map from the web site URL to a existing folder.
You can use server.MapPath("some url to file") to "translate" this to a internal file name.
Code based files:
In your .net code (code behind) ANY file name is a standard plane, jane file name that points to a file on the server.
so, once we have that file name from the database, you can steam the file as if the user clicked on a link. But you never have to expose the actual file name, or file path. And no such valid URL's exist on the web site, since you do NOT have that files folder in the web site folder hierarchy - but placed that folder outside of the web site.
As long as that folder is outside of the web folders, and as long as you don't setup a virtual folder that points to that folder outside the web folders?
Then code behind can STILL get/grab/see/use any file on the server. that code uses a full valid windows file name, - but the web site will have no mapping to such a folder - hence no valid URL's will exist or can be typed in.

Access to files on a server (asp.net, webmatrix)

I want to read a *.txt file and edit this file. I use Webmatrix and it works on my computer. But after publishing it to a server (Web deploy) it doesn't work anymore.
string transmission;
string path;
path = "E:\\Documents\\My Web Sites\\Trackercontrol v2\\backup.txt";
public int insert()
{
using (StreamReader sr = File.OpenText(path))
{
while ((transmission = sr.ReadLine()) != null)
{
// etc.
}
}
}
I published this, adjusted the path to the .txt file, but the try/cath method told me that the access to the path is denied. I think reading out the file isnt the problem but editing or clearing the file makes this problem.
How can I fix this? Thank you very much!
You gave the path of your local drive, which may be or sure does not exist on the server. First upload the file on the server and then read it. You can get the correct path as
string path;
path = Server.MapPath("~/filename.txt"); // Considered file is placed at Root of your site
Check what account is the application pool running under?
Make sure that this account has read/write access to the file in concern.
Also, it would be a good idea to use
var path = Server.MapPath(relativePathToFile);

download unknown file from Url

In my application I need to download a .fec file from an Url and save it to another location.
I am using the C# Web Client for this.
But when I try to download a .fec file(we cannot view this file in IE or FF) Its downloading
404 page not found file and saving it to myfolder.
I dont know why its downloading a 404 page not found file when the file is existing at specified location.
Is this because .Fec files require a separate program to view it(you need Fec Viewer in order to view .fec files).
If I download a .txt file or .pdf file my program is working fine. I am able to download the
file and save it to my folder.
Any help is appreciated.
Here is my code
public void downloadFile(string url, string saveas)
{
try
{
System.Net.WebClient webclient = new System.Net.WebClient();
webclient.DownloadFile(url, saveas);
}
catch (Exception e)
{
this.ErrorLog(e.Message.ToString());
}
}
You need to set up that extension/mime-type in IIS or add a wilcard for serving unknown file types. By default, IIS won't serve 'unknown files'.
IIS6 - http://support.microsoft.com/kb/326965
IIS7 - http://blogs.iis.net/bills/archive/2008/03/25/how-to-add-mime-types-with-iis7-web-config.aspx
Does a regular browser at least let you download the file if it can't display it directly? If not, then my guess is that your web server is not configured correctly. If the server doesn't have a MIME type associated with that file extension it can prevent the file from being downloaded.

Save file in a folder above the site files

My host has the following structure:
/Web -> Where is the content of the site
/Data -> Folder permissions to read and write
How do I upload a file to the Data folder?
The code below does not work, since "~" returns the directory / web.
//Save Image
var serverPath = Server.MapPath(Href("~/Data/") + id);
Directory.CreateDirectory(serverPath);
imgOri.Save(Path.Combine(serverPath, fileName));
Server.MapPath() is designed to map a path up to the root directory of the application. As you are trying to upload a file above the root it won't work.
You can upload a file above the root by specifying the exact file path (if the host can provide it):
var serverPath = "C:\YourFolder\Data\") + id);
I'm surprised your host is allowing you to upload a file outside of the root directory as there are a number of dangers in doing this...you may also run into Trust issues.
You can obtain the path to a directory which sits at the same level of your site root by using Server.MapPath as below:
#{
var root = Server.MapPath(".");
var temp = root.Split('\\');
temp[temp.Length - 1] = "Data";
var newpath = string.Join("\\", temp);
}
Hosting companies used to provide "data" directories outside of the root folder as a safe place for things like Access mdb databases. You cannot directly browse to a directory which is outside of the root of your site. ASP.NET did away with the need for these things with the introduction of App_Data. The only reason you would want to use this kind of folder nowadays is if you want to apply some kind of authentication prior to serving the contents of the directory. Then you need to use a handler, or a simple cshtml file will do. You can combine the WebSecurity helper with the WebImage helper to first authenticate the user, and then retrieve and display the image if they pass the test. The src in your img tag will point to the cshtml file, with a querystring or UrlData value so you know which image to display.
If you don't need to validate users prior to displaying image, storing the image files outside of the root adds an unnecessary level of complication.

Flash XML config file problems with asp.net MVC

I'm creating an asp.net MVC app, first time I've done this. I have a flash component I need to use in a view. I have included the SWF files etc in the Contents folder and referenced it from my view, the flash file loads when you get to the view, great.
The problem occurs because the flash file references and XML file for its configuration data, and I'm getting an error accessing that XML file. I'm guessing this is because flash is looking for a relative path and is using the URL for the page, which is obviously an MVC url and so does not refer to an actual location on disk, so the XML file is not there.
I guess the obvious answer is the alter the flash file to look in the contents folder for the XML file, but that means re-compiling the flash, and I know very little about flash so I'd like to avoid doing that. So is there any way to get the XML file to show up in the same URL as the view, so at the moment, the page with the flash component on is located at htttp://localhost/upload/ so I guess the XML file needs to be accessible from http://localhost/upload/flash-settings.xml?
If there's any other better way to do this, without editing the flash file, im open to that too,
Add this Action to the FlashUpload Controller:
public class FlashUploadController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult FlashSettings()
{
var fileName = Server.MapPath("~/Contents/flash-settings.xml");
return new FilePathResult(fileName, "text/xml");
}
}
And this route to the RouteTable:
routes.MapRoute("FlashSettings", "upload/flash-settings.xml",
new { Controller = "FlashUpload", Action = "FlashSettings" });
You'll need to either set the routing mechanism to allow for direct files access to the /upload/ folder, or create a Controller Action which will return an XML stream (dynamic or the one read from the physical XML file), and point your SWF to that Route. I'd go with the second option, as it is much flexible.

Resources