Save images in repository and recover it through a Path with C#

Asked

Viewed 4,499 times

-1

How to save images in repository and recover it through a Path with Asp.Net MVC?

Searching in some places, I found that saving images directly in the database may have a significant loss of performance in the application.

2 answers

2

Follow code example of an application my ASP.NET MVC5 and the package Imageresizer. I made a model called ProductPicture where each record keeps the image of a product and its respective thumbnail (thumbnail). Images and thumbnails are stored inside the directory Content of the site.

Model

public class ProductPicture
{
    [Key]
    public int ProductPictureId { get; set; }
    public int ProductId { get; set; }

    [Required]
    [Display(Name = "FileName", ResourceType = typeof(Resources.Language))]
    public String FileName { get; set; }

    public String Thumbnail { get; set; }

    [Display(Name = "Product", ResourceType = typeof(Resources.Language))]
    public virtual Product Product { get; set; }

    [NotMapped]
    [Display(Name = "File", ResourceType = typeof(Resources.Language))]
    public HttpPostedFileBase File { get; set; }

    public ProductPicture() { }

    public ProductPicture(int _ProductID) {
        this.ProductID = _ProductID;
    }
}

Controller

[HttpPost]
[Authorize(Roles = "Uploaders")]
public ActionResult Create(ProductPicture productpicture)
{
    // Se foi enviado um arquivo com mais do que 0 bytes:
    if (productpicture.File != null && productpicture.File.ContentLength > 0)
    {
        // Extraindo nome do arquivo
        var fileName = Path.GetFileName(productpicture.File.FileName);

        var path = Path.Combine(Server.MapPath(imagesDirectory), fileName);
        productpicture.File.SaveAs(path);

        productpicture.FileName = fileName;
        ModelState.Remove("FileName");

        // Thumbnails
        if (productpicture.File.ContentLength > 0)
        {
            ImageResizer.ImageJob i = new ImageResizer.ImageJob(productpicture.File, 
                imagesDirectory + "/Thumbnails/<guid>.<ext>", new ImageResizer.ResizeSettings(
                                        "width=250;height=250;format=jpg;mode=pad"));
            i.CreateParentDirectory = true; //Auto-create the uploads directory.
            i.Build();
            productpicture.Thumbnail = i.FinalPath.Split('\\').Last();
        }
    }

    if (ModelState.IsValid)
    {
        context.ProductPictures.Add(productpicture);
        context.SaveChanges();
        return RedirectToAction("Index");  
    }

    // Se a validação falhar e a tela precisar ser recarregada
    ViewBag.PossibleProducts = context.Products;
    return View(productpicture);
}

View _Createoredit.cshtml

@model MyProject.Models.ProductPicture
@using MyProject.Models
@using MyProject.Resources

<div class="editor-label">
    @Html.LabelFor(model => model.File)
</div>
<div class="editor-field">
    @Html.TextBoxFor(model => model.File, new { type = "file" })
    @Html.ValidationMessageFor(model => model.File)
</div>
<div class="editor-label">
    @Html.LabelFor(model => model.Product)
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.ProductId, ((IEnumerable<Product>)ViewBag.PossibleProducts).Select(option => new SelectListItem {
        Text = (option == null ? "None" : option.Name), 
        Value = option.ProductId.ToString(),
        Selected = (Model != null) && (option.ProductId == Model.ProductId)
    }), Language.Choose)
    @Html.ValidationMessageFor(model => model.ProductId)
</div>

View Create.cshtml

@model MyProject.Models.ProductPicture
@using MyProject.Resources

@{
    ViewBag.Title = Language.Create;
}

<h2>@Language.Create</h2>

@using (Html.BeginForm("Create", "ProductPictures", FormMethod.Post, new { enctype = "multipart/form-data" })) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>@Language.ProductPicture</legend>
            @Html.Partial("_CreateOrEdit", Model)
        <p>
            <input type="submit" value="@Language.Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink(Language.BackToList, "Index")
</div>

1

An alternative is to only write the file path to the database (Path). Having in hand the image Path, loaded from the database, it is possible to do as follows:

private static BitmapImage LoadImage(String arquivo)
{
    try
    {
            if (System.IO.File.Exists(arquivo))
            {

                Uri urlImg = new Uri(arquivo, UriKind.RelativeOrAbsolute);

                return new BitmapImage(urlImg);
            }
            else
                return null;

    }
    catch (Exception)
    {
        throw;
    }
}

Then just call:

LoadImage("..\imagens\xxx.png");

Browser other questions tagged

You are not signed in. Login or sign up in order to post.