3

I would appreciate if anyone could help me with this. I have input file control in a form in a view and when someone picks a picture and clicks the submit button on the form, that file has to be saved in /Pictures folder in the application and file path needs to be saved in SQL database as string (like: /Pictures/filename).

Models class part:

[Table("Automobil")]
public partial class Automobil
{   .....
    [Required]
    [StringLength(30)]
    public string Fotografija{ get; set; }
    ......

View (Create) file part:

@using (Html.BeginForm("Create", "Automobili", FormMethod.Post, new { enctype = "multipart/form-data" }))

....
<div class="form-group">
            <div class="editor-field">
                @Html.TextBoxFor(model => model.Fotografija, new { type = "file" })
                @Html.ValidationMessageFor(model => model.Fotografija, "", new { @class = "text-danger" })
            </div>
        </div>
....

Controller part:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "AutomobilID,Marka,Model,Godiste,Zapremina_motora,Snaga,Gorivo,Karoserija,Fotografija,Opis,Cena,Kontakt")] Automobil automobil)
    {
        if (ModelState.IsValid)
        {
                db.Automobils.Add(automobil);
                db.SaveChanges();
                return RedirectToAction("Index");
        }

        return View(automobil);
    }

What do I need to do so the photo(Fotografija) could be saved in the application folder Pictures, and file path in SQL base (like /Pictures/filename)?

Thank you in advance for helping the beginner.

6
  • 1
    Don't put the full path in the database - just put the filename. This way you won't need to make any data changes should you relocate or rename the containing folder, you would only need to change the code in a single place (assuming you structured your code correctly) Commented Aug 27, 2016 at 15:09
  • When I just use the code above I get the validation error that the picture has to have up to 30 characters. Also, it doesn't save the picture itself in the application. Commented Aug 27, 2016 at 15:15
  • remove [StringLength(30)] Commented Aug 27, 2016 at 15:41
  • It still doesn't work. If I remove the [StringLength(30)] the code goes through but the picture is saved in SQL database under the name "System.Web.HttpPostedFileWrapper", and picture file is not saved in the application. So there must be something that I'm missing for saving url in the database, and obviously, the code for saving the picture file in the application is missing. Commented Aug 27, 2016 at 15:50
  • Почему бы тебе не задать свой вопрос на русском форуме? Commented Aug 27, 2016 at 17:52

2 Answers 2

1

Looks like your Fotografija property is string type where you want to save the unique file name. You do not want to use that field to get the file from the browser. Let's use another input field for that.

@using (Html.BeginForm("Index", "Home", FormMethod.Post, 
                                                   new { enctype = "multipart/form-data" }))
{
  <div class="form-group">
        <div class="editor-field">
            @Html.TextBoxFor(model => model.Model)
            @Html.ValidationMessageFor(model => model.Model)
        </div>
    </div>
    <!-- TO DO : Add other form fields also -->

    <div class="form-group">
        <div class="editor-field">
           <input type="file" name="productImg" />
        </div>
    </div>
    <input type="submit" />
}

Now update your HttpPost action method to have one more parameter of type HttpPostedFileBase. The name of this parameter should be same as the input file field name we added (productImg)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "AutomobilID,Marka,Model,Godiste,
          Zapremina_motora,Snaga,Gorivo,Karoserija,Opis,Cena,Kontakt")] Automobil automobil, 
                                           HttpPostedFileBase productImg)
{
    if (ModelState.IsValid)
    {
        if(productImg!=null)
        {
          var fileName = Path.GetFileName(productImg.FileName);
          var directoryToSave = Server.MapPath(Url.Content("~/Pictures"));

           var pathToSave = Path.Combine(directoryToSave, fileName);
           productImg.SaveAs(pathToSave);
           automobil.Fotografija= fileName;
        } 

        db.Automobils.Add(automobil);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(automobil);
}

You have to remove any validation data annotation decoration(Ex : [Required], [MinLength] etc) on the Fotografija field.

I also strongly suggest you to update the fileName before saving to be a unique one to avoid collision/overwriting of existing files. You can add the DateTime current value to the file name (Before the extension) to make it unique

Sign up to request clarification or add additional context in comments.

10 Comments

Thank you a lot for taking your time to assist me. I appreciate that a lot. It work now. if you have a bit more time, could you tell me what to do now without annotations for Fotografija property? Should I make restrictions for productImg instead (and where to put them)? Thanks a lot.
You can keep MaxLength to control the table column length. The property is only used for storing the file name.
Thanks again. Enjoy the day.
Hello again Shyju, I am now on the edit part. Could you assist me with that please? I posted the basic code above, your first answer. Didn't know how to put it in the comment.
I'm trying to make this work and the only thing now that I do not know how to do is how to make the edit page to have file stored in the input control when I click edit. So somehow I need to make "productImg" to have my file stored there when I'm on the edit page.
|
0

The code that I have in controller is the basic one:

// GET: Automobili/Edit/5
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Automobil automobil = db.Automobils.Find(id);
        if (automobil == null)
        {
            return HttpNotFound();
        }
        return View(automobil);
    }

    // POST: Automobili/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "AutomobilID,Marka,Model,Godiste,Zapremina_motora,Snaga,Gorivo,Karoserija,Fotografija,Opis,Cena,Kontakt")] Automobil automobil)
    {
        if (ModelState.IsValid)
        {
            db.Entry(automobil).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(automobil);
    }

How to change it to be compatible with the create code above?

Thank you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.