I have to ask a suggestion about a project I'm following. I need to create an action inside an MVC controller that let me download a series of images directly and not by compressing them inside a zip archive. I tried to achieve that by calling a download function inside the action, like this:
foreach(var image in images){
var imageFilename = image.filename;
var imageName = image.text;
var mimeType = image.type;
DownloadFile(imageFilename, imageName, mimeType);
}
Setting download file as
public FileResult DownloadFile(string imageFilename, string imageName, string mimeType){
return File(imageFilename, imageName, mimeType);
}
But this not works. Do you have any suggestion on how to proceed on this to avoid zip archive? Or is the only suitable method for this problem?
Related
I am working on an asp.net project using c# and I need to copy a file from an arbitrary location which is determined by the file upload dialog box.
I need to make an exact copy of the file in a folder that is located in the Solutions Explorer. Below is the code I am using.
string filename = txt_lesson_title.text;
string sourcepath = _Uploadedfile.PostedFile.FileName.ToString();
string targetPath = HttpContext.Current.Server.MapPath("/destFolder/");
File.Copy(sourcePath, targetPath + fileName);
The above code runs without reporting any errors but I cannot see the copied files in the destination folder. Any help will be deeply appreciated.
Thanks
You don't need to copy the file, you need to save a copy of it.
You can do this
if the file is coming to your controller, you controller should have arguments like HttpPostedFileBase or HttpPostedFileBase[] depending on if you are saving one or more
if you are saving one,
public ActionResult Step(FormCollection collection, HttpPostedFileBase file) {
//HttpPostedFileBase file; //this comes from you controller argument
var directory = "~/Uploads/";
//this if statement can be optional
if(!Directory.Exists(System.Web.HttpContext.Current.Server.MapPath(directory)))
{
Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(directory));
var virtualPath = directory + "/" + <your file name here>;
var filePath = System.Web.HttpContext.Current.Server.MapPath(virtualPath);
//if the file exists already, delete and replace it with the new one
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
file.SaveAs(filePath);
}
else {
//do as above without the create directory
}
}
I have data coming from a source to my Api and I need to post it to another POST ActionResult.
I have no problem in receiving data in first function which is basically this;
var provider = new MultipartFormDataStreamProvider(root);
try
{
//irrelevant confirmations and other code pieces are left out
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData fileData in provider.FileData)
{
var appPath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
var basePath = Path.GetFullPath(Path.Combine(appPath, #"..\"));
var headerActivityPath = basePath + "\\Documents\\" + tenantString + "\\Activity\\" + activityId;
File.Copy(fileData.LocalFileName, Path.Combine(activityPath, fileName));
}
}
I need to make an POST after this one finishes receiving the file. I want to make it without saving it to disk first, so I don't know where I should do the POST request with HttpClient.
The ActionResult with will be receiving the data has a parameter with HttpPostedFileBase but I don't know what to send it.
Every method I used before uses a file on the disk, is it possible to do this without saving the file to disk first?
HttpPostedFileBase has a property on it called InputStream this will give you access to the content of the attachment which was uploaded to your endpoint. You can use this as the argument to a new StreamContent in the HttpClient.
foreach (MultipartFileData fileData in provider.FileData)
{
await client.PostAsync("http://someurl.com", new StreamContent(fileData.InputStream));
}
I have created a function where a user can download a pdf file from my webpage. The file is stored in a databse and is requested from a webapi. The return value of the webapi is a byte[].
My issue here is that when i run the web application on my local iis this function runs without any errors. I get the pdf file and it is downloaded correctly on my machine. But when i deploy the web application to my Test server this code generates either RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION in chrome with some of the files where as other files are downloaded to the machine but when i try to open the pdf file i get: could not load the pdf file.
This happens with both chrome and IE.
This is my code:
[HttpGet]
[DoNotChangeCacheSettings]
public virtual FileResult DownloadTranslationFile(Guid id)
{
Guid assessmentTemplateId = id;
File translationFile = Services.GetFileContent(assessmentTemplateId);
var fileName = HttpUtility.UrlPathEncode(translationFile.FileName);
this.HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
var result = File(translationFile.FileContent.Content, System.Net.Mime.MediaTypeNames.Application.Pdf, fileName);
return result;
}
I have been trying to fix this issue for 2 days now but i simply cant figure out what the issue is. Hope you guys can help. Thanks.
You don't need to use Content-Disposition. .Net will add it for you. From the docs.
The fileDownloadName parameter is used to generate the
content-disposition header. The result object that is prepared by this
method is written to the response by the ASP.NET MVC framework when
the object is executed. The MediaTypeNames class can be used to get
the MIME type for a specific file name extension.
I tend to use the Stream-overload:
[HttpGet]
[DoNotChangeCacheSettings]
public virtual FileResult DownloadTranslationFile(Guid id)
{
Guid assessmentTemplateId = id;
File translationFile = Services.GetFileContent(assessmentTemplateId);
var fileName = HttpUtility.UrlPathEncode(translationFile.FileName);
var stream = = new MemoryStream(translationFile.FileContent.Content);
return File(stream, "application/pdf", fileName);
}
But you can use the byte[] as well:
[HttpGet]
[DoNotChangeCacheSettings]
public virtual FileResult DownloadTranslationFile(Guid id)
{
Guid assessmentTemplateId = id;
File translationFile = Services.GetFileContent(assessmentTemplateId);
var fileName = HttpUtility.UrlPathEncode(translationFile.FileName);
return File(translationFile.FileContent.Content, "application/pdf", fileName);
}
EDIT:
If you got an error when opening the PDF you can ensure that the web browser is doing the right thing by manually saving the PDF from code as well. If that file has errors as well you're probably generating an incorrect byte[].
[HttpGet]
[DoNotChangeCacheSettings]
public virtual FileResult DownloadTranslationFile(Guid id)
{
Guid assessmentTemplateId = id;
File translationFile = Services.GetFileContent(assessmentTemplateId);
var fileName = HttpUtility.UrlPathEncode(translationFile.FileName);
var stream = = new MemoryStream(translationFile.FileContent.Content);
// Code for debugging
var tempDir = "C:\\temp"; // Make sure app pool can write here.
var path = Path.Combine(tempDir, fileName); // Possibly add extension here.
using (var fileStream = File.Create(path))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}
stream.Seek(0, SeekOrigin.Begin);
// Return to client.
return File(stream, "application/pdf", fileName);
}
Hi there i have created a zipfile and i want to upload it after it has been created.
I have a method to upload the file but it only accepts the file in as a HttpPostedFileBase.
After my zip file is saved how would i go about changing it into a HttpPostedFileBase so that i can pass it to my upload method.
using (ZipFile zip = new ZipFile())
{
// add this map to zip
zip.AddFile(tempFolderPath + PropInfo[7].TagValue, "");
zip.AddFile(tempFolderPath + "data.xml", "");
zip.AddFile(tempFolderPath + "dvform.dvform", "");
zip.AddFile(tempFolderPath + "CS1.pdf", "");
zip.AddFile(tempFolderPath + "CS2.pdf", "");
zip.AddFile(tempFolderPath + "CS3.pdf", "");
zip.AddFile(tempFolderPath + "CS4.pdf", "");
zip.AddFile(tempFolderPath + "CS5.pdf", "");
zip.Save(tempFolderPath + "Tester.xap"); //Xap Save Name
}
If you really want to make a zip file into HttpPostedFileBase then your best option is probably to create a class that inherits from HttpPostedFileBase and override the methods as needed.
There aren't many things to override and they should all be pretty simple to get from a file object (they are filename, contentlength and contenttype as well as the filestream itself).
By far the best thing to do would be to refactor your upload method to not need a HttpPostedFileBase object. Make it take a more usual file object or stream or similar (depending on what the upload needs) and then create an override that takes a HttpPostedFileBase and extracts the bits it needs to pass to your main upload method.
Refactoring the upload method is probably beyond the scope of this question though.
Just an Idea, hope you can build on this
HttpPostedFile f = new HttpPostedFile();
f.InputStream = new System.IO.FileStream(); //replace this with Stream from your zip
HttpPostedFileBase zipFile = new HttpPostedFileWrapper(f);
I try to use plupload in my asp.net MVC2 project, can I do it?
Please help me if it can.
Best regards!
it is same as normal file upload but i like plupload i will use on my project so following codes will work with plupload
[HttpPost]
public ActionResult Create(FormCollection collection)
{
// my project need single file upload so i get the first file
// also you can write foreach statement to get all files
HttpPostedFileBase postedFile = Request.Files[0];
Image image = new Image();
if (TryUpdateModel(image))
{
fRepository.AddImage(image);
fRepository.Save();
// Try to save file
if (postedFile.ContentLength > 0)
{
string savePath = Path.Combine(Server.MapPath("~/Content/OtelImages/"), image.ImageID.ToString() +
Path.GetExtension(postedFile.FileName));
postedFile.SaveAs(savePath);
// Path for dbase
image.Path = Path.Combine("Content/OtelImages/", image.ImageID.ToString() +
Path.GetExtension(postedFile.FileName));
}
i didn't change the codes, but if you need any further help please ask, i'll explain