-1

I've found some code to do this and tried to implement it into my project, but so far it has been unsuccessful. I don't get any errors, but I don't see any images being stored in my images directory inside visual studio.

View:

  @using (Html.BeginForm())
{
    <span>Please enter your story here:</span>
    <textarea id="testimonial" name="testimonial"></textarea>
    <button type="submit">Submit</button>
    <input type="file" name="file" />
}

Controller:

[HttpPost]
    public ActionResult Create(Testimonials testimonials)
    {
        if (Request.Files.Count > 0)
        {
            var file = Request.Files[0];

            if (file != null && file.ContentLength > 0)
            {
                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
                file.SaveAs(path);
            }
        }


        TestimonialsContext testContext = new TestimonialsContext();
        testContext.testimonialContext.Add(testimonials);
        testContext.SaveChanges();
        return RedirectToAction("Index");
    }

The part below the if block works fine. That just saves the content of a textarea to the database. Any thoughts? Do I need to make any changes to my model?

model:

[Table("Testimonials")]
public class Testimonials
{
    public int Id { get; set; }
    public string Testimonial { get; set; }
}

context class:

public class TestimonialsContext:DbContext
{
    public DbSet<Testimonials> testimonialContext { get; set; }
}
9
  • Hi everyone, I opened the file in file explorer and saw the images there. Strange how it doesn't update in visual studio... Commented Mar 9, 2016 at 23:50
  • In visual studio click on the folder (Images) and then click on "Show All Files" at the solution explorer options. It will show all files even if they are not added to the project. You need to click on "Refresh" to show newly added files. Commented Mar 9, 2016 at 23:56
  • Your file will not be sent to the server because you have not added the enctype="multipart/form-data" attribute to the form Commented Mar 10, 2016 at 0:21
  • @StephenMuecke Thank you, I did that. Now, I am wondering how I could add this file path to my database in the same table as the testimonial. Right now all I am getting is System.Web.HttpPostedFileWrapper. How can I pass in the path string to add it to the database at the same time as the testimonial? By the way, I updated my code to reflect changes I have made to make this work so far. Commented Mar 10, 2016 at 0:45
  • You cant just change the original question and I have rolled back the changes (my previous comment would not make sense and no one can add an answer). If you have a new question, then ask a new question. Commented Mar 10, 2016 at 0:50

1 Answer 1

4

Your file is not being posted because you do not have the necessary enctype attribute on the form. Change the view to use

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

You will now get the file and save it, but there is no relationship to your Testimonials object so you cannot retrieve it. You will need to add additional fields in your Testimonials table to store the file properties (or a separate table if a Testimonials can have multiple images). I also recommend you save the file to your server with a unique identifier (e.g. a Guid to prevent accidental overwriting if 2 users upload files with the same name). You revised model might be

public class Testimonials
{
    public int Id { get; set; }
    public string Testimonial { get; set; }
    public string ImagePath { get; set; }
    public string ImageDisplayName { get; set; }
}

I would also recommend using a view model for the view that includes the above properties plus public HttpPostedFileBase Image { get; set; } so that you can strongly bind to the model and add validation attributes (for example a [FileSize] attribute assuming you do not want to allow users to upload 2GB files). Your controller method would then be

[HttpPost]
public ActionResult Create(TestimonialVM model)
{
    // ModelState.IsValid check omitted
    Testimonials testimonials = new Testimonials();
    // map view model properties to the data model
    ....
    if (model.Image != null && model.Image.ContentLength > 0)
    {
        string displayName = model.Image.FileName;
        string fileExtension = Path.GetExtension(displayName);
        string fileName = string.Format("{0}.{1}", Guid.NewGuid(), fileExtension)
        string path = Path.Combine(Server.MapPath("~/Images/"), fileName)
        model.Image.SaveAs(path);
        // Update data model
        testimonials.ImagePath = path;
        testimonials.ImageDisplayName = displayName;
    }
    TestimonialsContext testContext = new TestimonialsContext();
    testContext.testimonialContext.Add(testimonials);
    testContext.SaveChanges();
    return RedirectToAction("Index");
}
Sign up to request clarification or add additional context in comments.

7 Comments

Hey man, sorry for taking so long to get back to you. So far my problem is with "file.SaveAs(path). The name 'file' does not exist in the current context. I tried adding semicolons after the two lines above it, but still to no avail...Thanks for all your help though.
Sorry, its model.Image.SaveAs(path); :) - see update
Now I get "String or binary data would be truncated.The statement has been terminated." I was having issues with your way, so I modified my original way to include your edits. Rather than using the testimonialVM, I just kept the original method and rather than using "model.Image" I referred to it as the object created in the parameter (public ActionResult Create(Testimonials testimonials, HttpPostedFileBase Testimonial_ImgName)). I'm curious, do we need to declare the ImagePath = path and ImageDisplayNAme = displayName when the changes are being saved anyway a few lines down?
Ok, so I realized the error was my table was not allowing enough characters. Odd, I thought varchar(100) would be enough. Thanks for all your help you rock!
There is no difference between file.SaveAs(path); in your code and model.Image.SaveAs(path); in my answer so that error has nothing to do with with the code I have shown.
|

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.