I very newbie in asp.net mvc . here I had a problem in the controller image upload anyone can give help ?? This example controller I get from the internet , what should I ch
Uploading a file, storing in the local file-system, and saving to a database is a common pattern. These are my recommendations.
1. Do not use the uploaded filename as your filename.
This is common:
var filename = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads/Photo/"), filename);
file.SaveAs(path);
Don't do it. There are a few reasons:
a) Filenames may conflict. b) Remote filenames may be incompatible with your local file-system. c) Someone may try a malicious filename and doing this may break your server.
Instead, generate your own filename (perhaps using a GUID, GUID.NewGuid().ToString()
) and store the original filename in your database.
2. Don't store all files in a single folder
At some point, your folder will contain too many files for the OS to process quickly.
Partition the files by something useful, like the user ID. This also helps to segregate the files between users.
3. Don't store the full path to the file in the database
At some point, you may move the files (perhaps to a different drive) and all your stored file locations will be broken.
4. Don't store the image URL in the database
Same as #3. If your web app changes and you want to change the image URLs, then you have incorrect URLs stored in the database. You'll have to scan and update all your database records.
5. Don't store redundant path information in the database
While it may be tempting to include "Uploads/Photo/" in the stored URL in the database, it has many problems too:
a) It's redundant data. For every file, you're using extra, unnecessary, data space. b) If your app changes and the URL should change, your stored URLs are now broken.
Instead, prepend "Uploads/Photo/" to the URL after you read the value from the database.
Update:
Here is some sample code:
[HttpPost]
public ActionResult Create(EventModel eventmodel, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
var originalFilename = Path.GetFileName(file.FileName);
string fileId = Guid.NewGuid().ToString().Replace("-", "");
string userId = GetUserId(); // Function to get user id based on your schema
var path = Path.Combine(Server.MapPath("~/Uploads/Photo/"), userId, fileId);
file.SaveAs(path);
eventModel.ImageId = fileId;
eventmodel.OriginalFilename = originalFilename;
_db.EventModels.AddObject(eventmodel);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(eventmodel);
}
However, I would be wary about using your data model as the MVC action model.
You should change your AvatarUrl to:
public HttpPostedFileBase AvatarUrl { get; set; }
In your view, you can create a form similar to the following. Add the fields you will accept input for and use a file input for your avatar. When the form is posted back to the controller, MVC will attempt to bind the inputs to the parameters.
@using(Html.BeginForm("Create", FormMethod.Post, new { enctype = "multipart/form-data" }) {
<fieldset>
@Html.LabelFor(m => m.FirstName)
@Html.EditorFor(m => m.FirstName)
</fieldset>
<!--
REST OF YOUR INPUT FIELDS HERE
-->
<fieldset>
@Html.LabelFor(m => m.Avatar)
@Html.EditorFor(m => m.Avatar)
</fieldset>
<input type="submit" value="Submit" />
})
Your controller method should be updated to:
[HttpPost]
public ActionResult Create(EmployeeModel model)
{
if (ModelState.IsValid)
{
// Create avatar on server
var filename = Path.GetFileName(model.AvatarUrl.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads/Photo/"), filename);
file.SaveAs(path);
// Add avatar reference to model and save
model.AvatarUrl = string.Concat("Uploads/Photo/", filename);
_db.EventModels.AddObject(model);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
If you're still stuck let me know and I can go into more detail.
There's also an excellent/detailed write up related to what you're trying to do here http://cpratt.co/file-uploads-in-asp-net-mvc-with-view-models/