Here is my code for upload a file. It upload the file and save into upload folder. Now want to save the file name in the database. what can i do to save the file name in database.
public ActionResult FileUpload(upload mRegister)
{
//Check server side validation using data annotation
if (ModelState.IsValid)
{
//TO:DO
var fileName = Path.GetFileName(mRegister.file.FileName);
var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName);
mRegister.file.SaveAs(path);
ViewBag.Message = "File has been uploaded successfully";
ModelState.Clear();
}
return View();
}
Related
this is my function to update an instance but here i can't delete the old image it is only delete the instance from the database but the real image doesn't deleted from the image folder i have got this error message
The instance of entity type 'Images' cannot be tracked because another instance with the same key value for {'ImageId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
public async Task<IActionResult> Edit( int id, [Bind("ImageId,Title,ImageFile")] Images images )
{
if (id != images.ImageId)
{
return NotFound();
}
if (ModelState.IsValid)
{
var im = await _context.Images.FindAsync(id);
//delete image from wwwroot/image
var imagePath = Path.Combine(_hostEnvironment.WebRootPath, "image", im.ImageName);
if (System.IO.File.Exists(imagePath))
System.IO.File.Delete(imagePath);
//save image to wwwroot/image
string wwwRootPath = _hostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(images.ImageFile.FileName);
string extension = Path.GetExtension(images.ImageFile.FileName);
images.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
string path = Path.Combine(wwwRootPath + "/Image", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await images.ImageFile.CopyToAsync(fileStream);
}
//Edit record
try
{
_context.Update(images);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ImagesExists(images.ImageId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(images);
}
If you want to get the ImageName only then you should use your find method withAsNoTracking(). Probably you need to change your find method on something like that :
var im = await _context.Images.AsNoTracking().SingleOrDefaultAsync(i => i.Id == id)
About AsNoTracking
It doesn't look like you programmed your action to delete the old image... Deleting the image name from the database doesn't magically delete it from your wwwroot (assuming that's where the image is saved).
You can delete an image programmatically if you have its path like this:
System.IO.File.Delete(path_of_image);
But telling from your code, it doesn't look like you have the path of the image you want to delete. To get the path, I recommend doing either one of these two (if applicable):
Adding another property in your view model for the old image path
Querying the database for the old image path before updating the record
When I try to upload an image and save it in a certain folder of the server I get error System.UnauthorizedAccessException in the file.SaveAs(path) line.
View:
Controller:
public ActionResult LoadImage()
{
return View();
}
public ActionResult Upload(HttpPostedFileBase file)
{
//String path = Server.MapPath("~/img/" + file.FileName);
if (file != null)
{
String pic = System.IO.Path.GetFileName(file.FileName);
String path = System.IO.Path.Combine(Server.MapPath("~"), pic);
file.SaveAs(path);
}
return RedirectToAction("index", "Home", null);
An UnauthorizedAccessException means:
The caller does not have the required permission to the folder.
The file is an executable file that is in use.
Path specified a read-only file.
More Info on
Workaround: Using Server Folder instead of full path
Create an Image Folder In solution(or any your choice) as a storage for your images..
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null)
{
//Get the file name
var pic = System.IO.Path.GetFileName(file.FileName);
//Get the folder in the server
var imagesDir = System.Web.HttpContext.Current.Server.MapPath("~/image/");
var imgPath = imagesDir + pic;
file.SaveAs((imgPath));
}
return RedirectToAction("index", "Home", null);
}
Cheers,
The possible causes of this exception are:
Permission not granted to the folder where you are uploading the images. (Provide read write permission to the folder if not given)
The folder in which you are uploading is read only.
The file is an executable which may be in use.
Hope this helps.
Whenever I try to upload a file to a server the current View is redirected to a different View from the controller. How can I upload a file and stay on the same View.
I have tried the following code:
public Action Result(HttpPostedFileBase file)
{
return new EmptyResult();
}
Return View();
Should work as you'd expect, returning the View named Result.
If the current Action Method isn't the view you'd like to return you can use:
return RedirectToAction("actionmethodname");
I would suggest using something like plupload for async upload. That way you can upload without redirect and even view image/document when upload is complete.
It allows multiple upload and fallback through different methods to successfully upload a file.
For implementation you just create another controller just for handling uploads.
Check my code for article submission in MVC architechture.
public ActionResult Submit(ArticleViewModel newSubmit, HttpPostedFileBase uploadFile)
{
if (ModelState.IsValid)
{
//Upload File
if (uploadFile != null)
{
string fileName = uploadFile.FileName;
newSubmit.Article.image = fileName;
uploadFile.SaveAs("~/Content/Uploads/Images");
string savedFileName = Path.Combine(Server.MapPath("~/Content/Uploads/Images"), uploadFile.FileName);
}
// The HTML comes encoded so we decode it before insert into database
newSubmit.Article.content = HttpUtility.HtmlDecode(newSubmit.Article.content);
//Set article flags
newSubmit.Article.flagged = true;
newSubmit.Article.finished = false;
newSubmit.Article.submitStoryFlag = true;
//Insert article in the database _repository.AddArticle(newSubmit);
return View("Submitted");
}
else
{
// Invalid – redisplay with errors
return View(newSubmit);
}
}
Suppose your view name is UploadView.cshtml and from there, you are uploading file.
UploadView.cshtml
#using (Html.BeginForm("UploadFile", "MyController", FormMethod.Post, new { enctype = "multipart/form-data", id = "frm", name = "frm" }))
{
<input id="FileAttachments" type="file" name="FileAttachments" />
<input type="submit" value="upload" />
}
Your Controller would be
MyController.cs
[HttpGet]
public ActionResult UploadView()
{
Return View();
}
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase FileAttachments)
{
if (FileAttachments != null)
{
string fileName = System.Guid.NewGuid().ToString() + Path.GetFileName(FileAttachments.FileName);
fileName = Path.Combine(Server.MapPath("~/Content/Files"), fileName);
FileAttachments.SaveAs(fileName);
}
return View("UploadView");
}
I haven't really coded this before but I've got a list of file names in my view. There's a download button next to them. So for example:
here's the view markup for that:
#foreach (CarFileContent fileContent in ModelCarFiles)
{
using (Html.BeginForm("GetFileDownloadUrl", "Car", FormMethod.Get, new { carId = Model.CarId, userId = Model.UserId, #fileCdnUrl = fileContent.CdnUrl }))
{
#Html.Hidden("userId", Model.UserId);
#Html.Hidden("carId", Model.CarId);
#Html.Hidden("fileCdnUrl", fileContent.CdnUrl);
<p><input type="submit" name="SubmitCommand" value="download" /> #fileContent.Name</p>
}
}
When clicked, I send over the CdN url to my action method which under the hood goes and downloads that file from Rackspace and then copies it to our server for the user to download. So my action method returns back the url to the .zip file that the user has now access to download. But when I test this, it's posting back and redirecting me to a blank page that shows the url rendered in text on the page and that's it!
"http://www.ourAssetServer.com/assets/20120331002728.zip"
I'm not sure how to invoke a save as prompt instead and keep the user on the same View they are already in or redirect them back to the same view that lists out the files to download...
What I want to happen is this:
User clicks on the download button
Action Method does its thing, downloads the file in the backend
User seemlessly gets a save as pop-up immediately after clicking the download button
this is probably routine but I've never done this before. I need help figuring out how to get the save as prompt to show up and how I should handle returning to my View after my action method gets the final download url for the .zip...what do I do with that url in my action method...return it to the view? Not sure here.
here's the action method:
[HttpGet]
public string GetFileDownloadUrl(string fileCdnUrl int carId, int userId)
{
string downloadUrl = string.Empty;
downloadUrl = GetFileZipDownloadUrl(carId, userId, fileCdnUrl);
return downloadUrl;
}
downloadUrl returned in my action method is that "http://www.ourAssetServer.com/assets/20120331002728.zip" string for example sent back to the user...I just need to figure out how to get this wired up to a save as prompt but also figure out how to handle the view...do I redirect back to the same view or what?
UPDATE:
After researching a bit more, here's what I came up with:
[HttpGet]
public FilePathResult GetFileDownloadUrl(string fileCdnUrl, int carId, int userId)
{
string downloadUrl = string.Empty;
downloadUrl = rackSpaceTask.GetFileZipDownloadUrl(carId, userId, fileCdnUrl);
int i = downloadUrl.LastIndexOf("/");
string fileName = downloadUrl.Substring(i);
return File(downloadUrl, "application/zip", fileName);
}
I get the error 'http://ourAssetServer.com/assets/20120331002728.zip'; is not a valid virtual path
UPDATE #2
Here's my latest attempt using the redirect method to try and get a save prompt to show. What's happening is it is hitting my GetFileDownloadUrl but then never seems to get to my Redirect action method and I end up being redirected to a completely blank page (all white) with the url as http://localhost/Car/GetFileDownloadUrl and just stops there
#foreach (CarContent fileContent in Model.CarFiles)
{
using (Html.BeginForm("GetFileDownloadUrl", "Car", FormMethod.Post, new { carId = Model.CarId, userId = Model.UserId, #fileCdnUrl = fileContent.FileCdnUrl }))
{
#Html.Hidden("userId", Model.UserId);
#Html.Hidden("carId", Model.CarId);
#Html.Hidden("fileCdnUrl", fileContent.FileCdnUrl);
<p><input type="submit" name="SubmitCommand" value="download" /> #fileContent.Name</p>
}
}
public void GetFileDownloadUrl(string fileCdnUrl, int carId, int userId)
{
string cownloadUrl = string.Empty;
cownloadUrl = GetFileDownloadUrl(carId, userId, fileCdnUrl);
RedirectToAction("RedirectToUrl", downloadUrl);
}
public ActionResult RedirectToUrl(string fileUrl)
{
Response.Redirect(fileUrl);
return null;
}
I'm not sure how the RedirectToUrl should be coded...the return type and what do you return if anything? Should it just redirect keeping me on the page I was on? I don't "think" this is even being hit, only my first method. I put a debug point on the Response.Redirect and it's never hit..only a debug point on RedirectToAction("RedirectToUrl", downloadUrl);
You need to return a FileResult instead of a string.
return File(path + fileName, "application/zip", "20120331002728.zip");
Consider defining a new action "RedirectToUrl" that takes url as parameter and then using RedirectToAction in your code:
public ActionResult GetFileDownloadUrl(string fileCdnPath int carId, int userId)
{
string downloadUrl = string.Empty;
downloadUrl = GetFileZipDownloadUrl(carId, userId, fileCdnPath);
return RedirectToAction("RedirectToUrl",
new { url = downloadUrl });
}
Update: using the FilePathResult with Server.MapPath is another option (assuming that the server you're downloading the file to is the same as server running your ASP.NET MVC code). Add the following to the bottom of function in your last edit:
var assetsPath = Server.MapPath("~/assets");
var localPath = Path.Combine(assetsPath, zipFileName );
return this.File(localPath, "application/zip");
public ActionResult GetAttachment1(string projectID)
{
return File("~/Uploads/Project", "application/pdf", projectID);
}
this code gives an error......
You need to specify an absolute path to the File method. Use Server.MapPath to convert a relative into an absolute path:
public ActionResult GetAttachment1(string projectID)
{
string projectPath = Server.MapPath("~/Uploads/Project");
string file = Path.Combine(projectPath, projectID);
// at this stage file will look something like this
// "c:\inetpub\wwwroot\Uploads\Project\foo.pdf". Make sure that
// this is a valid PDF file and pass it to the File method
return File(file, "application/pdf", projectID);
}