简体   繁体   中英

Uploading and displaying image in ASP.NET MVC

I have hard time uploading picture and then displaying it in my view. I went through a lot of posts here and for some reason nothing really works for me.

Picture gets uploaded (in my case saved in ~/Content/Images , but is not displayed in the view. Whole project is published on Azure.

Please abstract from things like verifying if the uploaded file is really a picture or handling the size of the picture.

My domain model is:

public class Product
{
    ...
    public string ProductImageUrl { get; set; }
    ...
}

Controller - post method:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(/*[Bind(Include = "ProductId,ProductName,ProductDescription,ProductPrice, CategoryId, Quantity, picture")]*/ Product product, HttpPostedFileBase picture)
{
   if (ModelState.IsValid)
   {
        db.Products.Add(product);

        if (picture != null)
        {
             var originalFileName = Path.GetFileName(picture.FileName);
             string fileId = Guid.NewGuid().ToString().Replace("-", "");
             var path = Path.Combine(Server.MapPath("~/Content/Images/"), fileId + ".jpg");

             picture.SaveAs(path);

             product.ProductImageUrl = path;
             product.ProductImageName = fileId;

             db.SaveChanges();
        }

        db.SaveChanges();

        return RedirectToAction("Index");
     }

     return View(product);
} 

My view is:

       @foreach (var item in Model)
        {
            <tr>
                <td>
                    <img src="@item.ProductImageUrl" />
                </td>
...

Problem is that your are storing absolute path in the ProductImageUrl field and that's why its not working in your hosting environment. More importantly you don't need both ProductImageUrl and ProductImageName to handle images. Use only ProductImageName .

Do as follows:

Your Product model should as follows:

public class Product
{
    ...
    public string ProductImageName { get; set; }
    ...
}

Then in the Controller method:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Product product, HttpPostedFileBase productImage)
{
   if (ModelState.IsValid)
   {
      if (productImage != null && productImage.ContentLength > 0)
      {
          var fileName = Guid.NewGuid().ToString().Replace("-", "") + "_" + Path.GetFileName(productImage.FileName);
          var path = Path.Combine(Server.MapPath("~/Content/Images/Product/"), fileName);

          productImage.SaveAs(path);
          product.ProductImageName = fileName;
      }

      db.Products.Add(product);
      await db.SaveChangesAsync();
      return RedirectToAction("Index");
   }

   return View(product);
} 

Then in the View as follows:

@foreach (var item in Model)
{
   <tr>
       <td>
           <img src="@Url.Content("~/Content/Images/Product/"+@item.ProductImageName)" />
       </td>
   <tr>
}

Hope it will work for you! Thank you.

I would add a <base> tag to your view so that all links are relative to your site. Then you don't need to build a path to the image at all.

For intance, if you site is at https://bestsiteever.com your tag would look like this:

<base href="https://bestsiteever.com" >

and your path would be:

$"/Content/Images/{fieldId}.jpg"

If you post your image as a byte array, you should be able to turn it in Base64 format and display in view :

<img src="data:image;base64,@Convert.ToBase64String(item.ProductImageUrl)" />

Worth a shot.

Correct me if i'm wrong but the string stored in item.ProductImageUrl is a path like c:\\\\.. right?

Server.MapPath gives relative hard drive location on the server. If you put that location in src then you are asking the browser to find that file in your LOCAL hard drive.

Try item.ProductImageUrl = "<url to your site>/Content/Images/" + fileId + ".jpg"; .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM