I have a list in my view with an ActionLink button 'Download' and I want them to download a file when they click the link. The file is located in a map in my project.
View:
<div id="right-column-links">
<h2>Your active links</h2>
#if (lstLinks.Count == 0)
{
<p>You have no active links yet.</p>
}
else
{
<table>
#foreach (var item in lstLinks)
{
<tr>
<td>#Html.DisplayFor(model => item.Url)</td>
<td>#Html.ActionLink("Put inactive", "LinkInActive", new { linkid=item.LinkId }, new { onclick = "return confirm('Are you sure you want this link inactive?');" })</td>
<td>#Html.ActionLink("Download Qrcode", "DownloadQrcode", new { linkid=item.LinkId })</td>
</tr>
}
</table>
}
</div>
Controller:
[HttpPost]
public FileResult DownloadQrcode(int linkid)
{
Qrcode Qrcode = DbO.getQrcodebyLinkId(linkid);
string image = Server.MapPath("~") + "\\Qrcodes\\" + Qrcode.Image;
string contentType = "image/jpg";
return File(image, contentType, "Qrcode-" + Qrcode.QrcodeId);
}
The linkid comes from the selected link in the list. Then I lookup what qrcode matches the linkid in my database. From this qrcode object I get the image name. Example (qrcode-1337). Then I'am not sure what to do. I lookup the path where my project is stored and attach the map Qrcodes to it (where all the images are stored) and the image name. This returns me a link that he doesn't find.
Map location:
C:\Users\stage\Desktop\Immo-QR\Immo-QR\Immo-QR\Qrcodes
This doesn't seem to work. I am not sure how I should use FileResult. Can anyone explain this? Or show me another way?
EDIT:
A user suggested me to put the images in the App_Data file which I did under a map Qrcodes.
To save the file I use this code:
string path = Server.MapPath("~");
System.IO.File.WriteAllBytes(path + "\\App_Data\\Qrcodes\\qrcode-" + qrcodeid + ".jpg", bytes);
If I use "~\App_Data\Qrcodes\qrcode-" instead of the above, It doesn't work either.
I still get this error: Server Error in '/' Application. The resource cannot be found.
SOLUTION:
With this code it works!
public FileStreamResult DownloadQrcode(int linkid)
{
Qrcode Qrcode = DbO.getQrcodebyLinkId(linkid);
string path = Server.MapPath("~");
Stream image = new FileStream(path + "\\App_Data\\Qrcodes\\" + Qrcode.Image + ".jpg", FileMode.Open);
return File(image, "image/jpeg");
}
Try changing your string image line to Stream image.
This will help understand if you can't read the file. Your return File line will take a Stream with no issues.
Your approach is correct.
I think the path to the file is incorrect.
If you use ~\\Qrcodes\\filename it will translate to <appRootDirectory>\\QrCodes\\filename.
Also remember that IIS runs as a separate user in most cases, which does not have a home directory like a regular user.
I would suggest you move the Qrcodes to AppData folder or AppGlobalResources folder.
If you dont want to do that, you need to provide absolute path to Qrcodes folder.
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
}
}
My database table
First I tried storing images with datatype image/varbinary but I get an error:
Invalid Value The changed value in this cell was not recognized as being valid. .Net Framework Data Type: Byte[] Error Message: You cannot use the result pane to set this Field data to values other than NULL Type a value appropriate for the data type or press ESC to cancel the change
How can I store image in my database table manually and retrieve them through jQuery Ajax method?
use in C# Button Submit with data source
if (FileUpload1.PostedFile != null && FileUpload1.PostedFile.FileName != null)
{
byte[] img = new byte[Request.Files[0].ContentLength];
Request.Files[0].InputStream.Read(img, 0, Request.Files[0].ContentLength);
datasource.Photo = img; --here you can save file to Database
}
for retrieving image from dbserver use belowed
img.ImageUrl = "data:image/jpg;base64," + Convert.ToBase64String(Upprofile.Photo);
Have you ever tried other ways to store images ?
I have never used such a way to store image in database if you want my two cents it would be better to save your image on host and save its url in the database.
You only need url to show picture in browser...!
I'm not sure if this works in VS2012, but you can try this approach that I'm using in my MVC projects:
public action UploadFile(HttpPostedFileBase file) //this is how you get the file that was submited from your form
{
//so now that I have the file, i need to save it somewhere
//let's see if we have a folder for that, if not let's create it
if(!Directory.Exists(Server.MapPath("~/The path from the root of the app to the uploaded files folder/")))
{
Directory.CreateDirectory(Server.MapPath("~/The path from the root of the app to the uploaded files folder/"));
} //the ~ symbol is part of the code, it returns the physical path to the root of the application
var storage = Server.MapPath("~/The path from the root of the app to the uploaded files folder/");
//now we need a name, we can generate one as a GUID for example, or we can get it's own.
var fileName = file.FileName.Substring(file.FileName.LastIndexOf("\"), file.Name.Length + 1);
//Now you might have to play a bit with the substring arguments, I'm not sure i wrote that right,
//it might not need the +1 part, or it might need it on the LastIndexOf as well,
//anyway, now we have the name and the folder where to save our file, let's do that:
path = String.Format("{0}\{1}", storage, filename);
try
{
file.SaveAs(path); //Now the file is on the server,
//just save this path and whatever else you need in the database so you can
//grab it later.
}
catch
{
//do your exception handling here
}
Saving to database here...
}
In order to grab it you just get that object from the database like any other objects like so:
Let's presume you're doing everything in your controller, which you shouldn't,
public Action GetFile(int id)
{
using(context = new YourDbContext())
{
var file = context.Files.FirstOrDefault(p => p.Id == id);
}
return View(file);
}
And put it's path for the src in html to show the image like so:
<img src="#Model.path" /> //Considering that in your controller you will `return View(file);`
//So your file object is the model.
One more thing, I'm not sure if in paths you'll need \ or /, I always get it wrong the first time so debug it on the first run and if your path looks likeFolder1Folder2Folder3File it means you need to change it :).
I hope this helped, good luck.
P.S., there might be better ways to do it, but this is how I'm doing it and it seams to work fine for me.
On server, you convert image to a base64 string and save to database.
using (Image image = Image.FromFile(Path))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
Beside Client, you put base64 string in Image object
var image = new Image();
image.src = 'data:image/png;base64,your base64 string';
document.body.appendChild(image);
I think store image on the disk better.
How to open pdf in my asp.net mvc website? But reusing code and which I have not. I do not want to do this for each pdf, so I want to reuse code.
My Index View:
<p>#Html.ActionLink("Historia.pdf", "ObtenerPdf", "Home")</p>
My Controller Method:
public FileStreamResult ObtenerPdf()
{
FileStream fs = new FileStream("c:\\Historia.pdf", FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
}
Untested, I don't have VS in front of me to check.
In summary, you need to add a parameter to your DownloadPdf action and pass it in with the action link.
Here's some code to list all the PDFs (Q used C:\ so this does as well, see notes), show them to the user and download.
Controller:
public ActionResult Index()
{
var files = System.IO.Directory.GetFiles(#"C:\", "*.pdf")
.Select(x => System.IO.Path.GetFileNameWithoutExtension(x))
.ToList();
return View(files);
}
public FileStreamResult ObtenerPdf(string file)
{
FileStream fs = new FileStream("c:\\" + file + ".pdf", FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
}
View:
#model IList<string>
#foreach (var file in Model)
{
<p>#Html.ActionLink(file, "ObtenerPdf", "Home", new { file }, null)</p>
}
Couple of notes:
Directory.GetFiles includes the path - there are other methods to get a list of files without the path included.
ActionLink overload is: text, action, controller, routeValues, attributes - without the null it will pick the wrong overload.
In new { file } if you don't specify a name, it will use the variable name, you could be specific to match the parameter name on the action which would be more robust, ie: new { file = file } but some optimisers will highlight this.
You probably don't want to list all your PDFs on C:\ on the server... you can use Server.MapPath to locate a folder within your application (then it doesn't matter if your site moves)
There's very likely an overload for return File to specify the path, so you don't need to open it first and will dispose it for you correctly etc, I've used the same code as supplied in the question.
I'm working on a site where I need to crop and resize images that people upload.
I got the code for the upload function but in my httpPost action result I want to resize the image to start off with. I also got the code for that but I can't find a way to show the image.
Here is my code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FileUpload(HttpPostedFileBase uploadFile)
{
if (uploadFile.ContentLength > 0)
{
foreach (string fileKey in System.Web.HttpContext.Current.Request.Files.Keys)
{
HttpPostedFile file = System.Web.HttpContext.Current.Request.Files[fileKey];
if (file.ContentLength <= 0) continue; //Skip unused file controls.
ImageResizer.ImageJob i = new ImageResizer.ImageJob(file, "~/img/", new ImageResizer.ResizeSettings("width=50;height=50;format=jpg;mode=max"));
i.CreateParentDirectory = true; //Auto-create the uploads directory.
i.Build();
string relativePath = "~/img/" + Path.GetFileName(uploadFile.FileName);
string physicalPath = Server.MapPath(relativePath);
uploadFile.SaveAs(physicalPath);
return View((object)relativePath);
}
}
I want go write out the Image information from ImageResizer.ImageJob i..
Any ideas?
Thank you!
First, the code you're using allows anybody to upload an executable page and run it.
Never, under any circumstances, should you use uploadFile.FileName as part of the final path name, unless you deeply understand path and length sanitization.
Second, ImageJob needs a destination path, not a folder path. You can use variables, like "~/img/<guid>.<ext>" and access the resulting physical path from i.FinalPath. You can use ImageResizer.Util.PathUtils.GuessVirtualPath(i.FinalPath) to get the app-relative path.
As this is almost a precise duplicate of mvc3 ImageResizer, please consider using the search feature before posting.
I am working on a project of Asp.Net MVC-4. In my project user post requirements. Post contains title, tags, files etc.File may be multiple and it may be of any type like Video, doc ( ppt, excel, pdf, etc), images etc.
My problem is the handling of multiple file upload. Now first of all i tell you
currently how i am handling this :
I am using Jquery FIle Uplaod plugin. Through this plugin i am uploading file to server sequentially and on server i am saving those file with SessionId.Now when user post there requirement form than i just rename those file with userId.
drawback of my approach
First i have to save those files with session id and than i have to rename it with userId. So if i save my file in Window Azure Blobs than in that case for uploading single file i have to do 2 transaction. First save the blob with SessionId and than Renaming the blob with userid. Which i think result extra processing and extra cost.
Now i want to know if there is any approach by which i can upload all file (with progress bar for individual file [required]) with form post. So that user's requirement form (tags, titile etc) with all files go to server together than in that case i will save the user first in the database and than i will save the files with the userId ??
Note: I cannot save File with guid or other. UserId is required in the file name to uniquely identify user's files.
You can upload using following code in controller
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files) {
foreach (var file in files) {
if (file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
}
return RedirectToAction("Index");
}
more details here
Not sure if i completely understand the question, but you could post the model for your user details in the same POST as the file upload (same form?), then on the server:
[HttpPost]
public JsonResult AddNewImage(UserModel user)
{
ReturnArgs r = new ReturnArgs();
repo.AddUser(user) // add your user to DB here
SaveImages(user.Id);
r.Status = 200;
r.Message = "OK!";
return Json(r);
}
private void SaveImages(string userid)
{
for (var i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i] as HttpPostedFileBase;
string fileName = userid + "_" + i;
// saving file to DB here, but you can do what you want with
// the inputstream
repo.SaveImage(fileName, file.InputStream, file.ContentType);
}
}