Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload and View Files ASP.NET MVC 5

I have this code:

    [HttpPost]
    public ActionResult Create(Knowledgebase KB, HttpPostedFileBase file)
    {
        var KBFilePath = "";
        if (ModelState.IsValid)
        {
            if (file.ContentLength > 0)
            {
                var fileName = Path.GetFileName(KB.KnowledgebaseTitle);
                var path = Path.Combine(Server.MapPath("~/Resources/KBArticles"), fileName + ".pdf");
                KBFilePath = path;
                file.SaveAs(path);
            }
            KB.KnowledgebaseLink = KBFilePath;
            db.Knowledgebases.Add(KB);
            db.SaveChanges();
            return RedirectToAction("Index", "Home");
        }

        else
        {
            return View();
        }

The link is the filepath which is stored in the DB which starts with C:/

On another page I can view the contents of the record. When I click on the link to which its saved on the C:/, Chrome says 'Failed to load local resource'. I am saving into the Resources folder which is part of my ASP.NET app directory. Anyway around this?

EDIT The page is served from this View:

public ActionResult Suggestions(String Tag)
{
      return View();
}

EDIT 2 - I put the changes in my view:

@{
string tag = "<td><a href=" + "~/Content/Files/" + ">" + item.Title.Replace(" ", "") + ".pdf" + "</a>" + "</td>";
 }
 @Html.Raw(tag)

The requested file in the browser address bar is

http://localhost:62165/Incident/~/Content/Files/

Now I get a HTTP Error 404.0 Not Found error

like image 842
ASPCoder1450 Avatar asked Mar 23 '14 14:03

ASPCoder1450


2 Answers

Try to save the files in Content folder. You can create a sub folder Content/Files. Put you files there. Then generate the links like:

<a href="~/Content/Files/file1.pdf">File1</a>

or use the download attribute if you want to download directly:

<a href="~/Content/Files/file1.pdf" download>File1</a>.

Most web servers are configured to deny requests for content outside the content folder. This can be modified in the config file but is easier (and safer) if you use the content folder. This is based on my experience, if someone think that I'm wrong please let me know to fix my answer. I'm always glad to learn something new.

EDIT 1: How to build the a tag dynamically

In the view you need a string variable link that holds the text of the link you want to show and another variable path to hold the path (maybe both are loaded from db in the controller). Then you can build the tag manually like this:

@{
    string tag = "<a href=" + path + ">" + link + "</a>";
}

@Html.Raw(tag)

EDIT 2: Dealing with spaces in Url.

You need to use Html.Content to get the right relative Url.

@{
    string link = item.Title;
    string path = Url.Content("~/Content/Files/") + link.Replace(" ", "%20") + ".pdf";
    string tag = "<a href=" + path + ">" + link + "</a>";
}

@Html.Raw(tag)
like image 133
rareyesdev Avatar answered Oct 23 '22 14:10

rareyesdev


First the Create View <

<div class="form-group"> @Html.LabelFor(model => model.ImageData, new { @class = "control-label col-md-2" }) 
  <div class="col-md-10"> <input name="Image" type="file" /> 
    @Html.ValidationMessageFor(model => model.ImageData) 
  </div> 
</div>

Then the Controller Create Action

public ActionResult Create(ArtWork artwork, HttpPostedFileBase image) { 
  if (ModelState.IsValid) { 
    if (image != null) { //attach the uploaded image to the object before saving to Database 
      artwork.ImageMimeType = image.ContentLength; 
      artwork.ImageData = new byte[image.ContentLength]; 
      image.InputStream.Read(artwork.ImageData, 0, image.ContentLength); //Save image to file 
      var filename = image.FileName; 
      var filePathOriginal = Server.MapPath("/Content/Uploads/Originals"); 
      var filePathThumbnail = Server.MapPath("/Content/Uploads/Thumbnails"); 
      string savedFileName = Path.Combine(filePathOriginal, filename); 
      image.SaveAs(savedFileName); //Read image back from file and create thumbnail from it 
      var imageFile = Path.Combine(Server.MapPath("~/Content/Uploads/Originals"), filename); 

      using (var srcImage = Image.FromFile(imageFile)) 
      using (var newImage = new Bitmap(100, 100)) 
      using (var graphics = Graphics.FromImage(newImage)) 
      using (var stream = new MemoryStream()) { 
        graphics.SmoothingMode = SmoothingMode.AntiAlias; 
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 
        graphics.DrawImage(srcImage, new Rectangle(0, 0, 100, 100)); 
        newImage.Save(stream, ImageFormat.Png); 
        var thumbNew = File(stream.ToArray(), "image/png"); 
        artwork.ArtworkThumbnail = thumbNew.FileContents; 
      } 
    } 

    //Save model object to database 
    db.ArtWorks.Add(artwork); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
  } 
  return View(artwork); 
}

Then a get Image or GetThumbnail method

public FileContentResult GetThumbnailImage(int artworkId) { 
  ArtWork art = db.ArtWorks.FirstOrDefault(p => p.ArtWorkId == artworkId); 
  if (art != null) { 
    return File(art.ArtworkThumbnail, art.ImageMimeType.ToString()); 
  } else { 
    return null; 
  } 
}

And here for the display in the view

<td> <img src="@Url.Action("GetThumbnailImage", "Artwork", new { Model.ArtWorkId })" alt="Artwork Image" /> </td>
like image 1
user3892688 Avatar answered Oct 23 '22 13:10

user3892688