MVC 3 - Image upload fails - asp.net-mvc

I am trying write a program that allows users add a image to a database, but it fails. I would be grateful if someone could help me...
My Index.cshtml file has the following code...
<td>
#item.Picture1
<img alt="#Html.Encode(item.Picture1)" src='#(Url.Action(("Picture1")) +
ToString())' width="64" height="64" />
</td>
Create.cshtml file looks like this...
<div class="editor-field">
#Html.EditorFor(model => model.Picture1)
<input type="file" id="fileUpload" name="fileUpload" size="23"/>
#Html.ValidationMessage("Picture1", "*")
</div>
<p>
<input type="submit" value="Create" />
</p>
In the controller, for Create, I have the following code...
[HttpPost]
public ActionResult Create([Bind(Exclude = "SubProductCategoryID")] SubProductCategory2 Createsubcat2, FormCollection values)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0)
{
Createsubcat2.Picture1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[0]);
}
db.AddToSubProductCategory2(Createsubcat2);
db.SaveChanges();
return RedirectToAction("/");
}
PopulateProductCategoryDropDownList(Createsubcat2.ProductCategoryID);
return View(Createsubcat2);
}
public FileResult Image(int id)
{
const string alternativePicturePath = #"/Content/question_mark.jpg";
SubProductCategory2 product = db.SubProductCategory2.Where(k => k.SubProductCategoryID == id).FirstOrDefault();
MemoryStream stream;
if (product != null && product.Picture1 != null)
{
stream = new MemoryStream(product.Picture1);
}
else // If product cannot be found or product doesn't have a picture
{
stream = new MemoryStream();
var path = Server.MapPath(alternativePicturePath);
var image = new System.Drawing.Bitmap(path);
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin);
}
return new FileStreamResult(stream, "image/jpeg");
}
FileHandler.cs
public class FileHandler
{
/// <summary>
/// Converts a HttpPostedFileBase into a byte array
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public byte[] uploadedFileToByteArray(HttpPostedFileBase file)
{
int nFileLen = file.ContentLength;
byte[] result = new byte[nFileLen];
file.InputStream.Read(result, 0, nFileLen);
return result;
}
Thanks in advance. I am using http://blog-dotnet.com/category/ASPNET-MVC.aspx website for reference. I am using VS 2010, ASP.NET 4.0, MVC 3 in C#. SQL Server 2008R2. SubProductCategory2 table has file Picture1, image data type.
Edit:
Actually working on more I have public byte[] Picture1 { get; set; } in one of the classes. The output I am now getting is System.Byte[] System.Byte[]. How do I fix this?

As well as having an input with a type of file, you need to make sure your form accepts multipart data...
<form method="POST" enctype="multipart/form-data" action="">
I couldn't see your form element to confirm whether you had done this.

Related

Photo Upload Problem in ASP.NET MVC My Blog Project

When I upload a photo, the page just refresh, not upload the photo in ASP.NET MVC My Blog Project. I looked the solution in Stack OverFlow but I didn't handle this problem. I don't know to write which code here because I am firstly trying to make a blog site in ASP.NET. If you are ask to me whatever code, I publish here quickly. Thanks for cooperation.
Say for example your model is
public class blog
{
public int Id { get; set; }
public string Code { get; set; }
public string Photo1 { get; set; }
}
Here I'm storing the photo in the server (Not in the database)
There goes the controller
public ActionResult BeginUploadPhoto(int Id)
{
var Blog= db.blog.Where(a => a.Id == Id).FirstOrDefault();
return View(Blog);
}
public ActionResult UploadPhoto(int? Id, HttpPostedFileBase Logo)
{
BlogCP = db.Blog.Find(Id);
WebImage img = new WebImage(Logo.InputStream);
if (img.Width > 500)
img.Resize(500, 500);
// to reduce the size upon upload
string extension = Path.GetExtension(Logo.FileName);
// get your photo extenstion
string filename = Guid.NewGuid().ToString();
// rename the upload photo
var path = Path.Combine(Server.MapPath("~/BlogPhoto/"), filename + extension);
// make sure that you create a folder BlogPhoto in your project or you can
//name it anything you like
string savepath = "~/BlogPhoto/" + filename + extension;
BlogCP.Photo1= savepath;
img.Save(path);
// save photo in your server
if (ModelState.IsValid)
{
db.Entry(BlogCP ).Property(r => r.Photo1).IsModified = true;
db.SaveChanges();
return RedirectToAction("Index","Staff");
}
return RedirectToAction("Index");
}
There goes the View
#model ProjectName.Entities.Blog
#{
ViewBag.Title = "BeginUploadPhoto";
}
<div class="container">
#if (Model.Photo1 != null)
{
<img id="Preview" class="img-thumbnail" src=#Model.Photo1/>
}
#using (Html.BeginForm("UploadPhoto", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
{
#Html.HiddenFor(m => m.Id)
<div>
<a>Select and upload Photo</a>
<input type="file" id="Logo" name="Logo"
<input type="file" id="Logo" name="Logo" accept="image/*" onchange="loadFile(event)">
</div>
<div class="form-group">
<button id="btnUpload"
class="btn btn-sm btn-primary"
formnovalidate="formnovalidate"
data-pdsa-action="upload">
<i class="glyphicon glyphicon-upload"></i>
Upload
</button>
</div>
}
}

File Upload in asp.net mvc3

I'm currently using Entity Framework Code First approach for my asp.net MVC3(aspx syntax) project.
I have a model in my project called EmployeeModel
public class EmployeeModel
{
public string imageinfo;
public string fileinfo;
}
My DbContext is
public class ContextDB:DbContext
{
public DbSet<EmployeeModel> Employee { get; set; }
}
I would like to have a file browser for both fileinfo and imageinfo in my view to upload the files and images and the path of the files and images need to be stored in the database.
Can anyone please help?
Try using
.chtml
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
Controller
public class HomeController : Controller
{
// This action renders the form
public ActionResult Index()
{
return View();
}
// This action handles the form POST and the upload
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
// Verify that the user selected a file
if (file != null && file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Index");
}
}
In Asp.Net MVC we have to use HttpPostedFileBase for Uploaded files as shown below :-
Controller :
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null) // file here will have your posted file which you post from view
{
int byteCount = file.ContentLength; <---Your file Size or Length
byte[] yourfile = new byte[file.ContentLength];
file.InputStream.Read(yourfile , 0, file.ContentLength);
var doc1 = System.Text.UnicodeEncoding.Default.GetString(empfile);
// now doc1 will have your image in string format and you can save it to database.
}
}
View :
#using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}

ASP.NET MVC Two file upload, different destinations

I'm trying to upload two different files into two different database fields on same form.
------------------------------------
reportid | name | image | template |
------------------------------------
this is the table look. So I want to upload files to image and template. My model:
public class Report
{
[Key]
public int ReportID { get; set; }
[Required]
public string Name { get; set; }
public byte[] Image { get; set; }
public byte[] Template { get; set; }
}
My Create method in controller:
public ActionResult Create(Report report, HttpPostedFileBase file, HttpPostedFileBase temp)
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
report.Image = ms.GetBuffer();
}
}
if (temp != null && temp.ContentLength > 0)
{
using (MemoryStream ms1 = new MemoryStream())
{
temp.InputStream.CopyTo(ms1);
report.Template = ms1.GetBuffer();
}
}
db.Reports.Add(report);
db.SaveChanges();
db.Configuration.ValidateOnSaveEnabled = true;
return RedirectToAction("Index");
}
And part of view concerning uploads:
<div class="editor-label">
<%:Html.LabelFor(model => model.Image) %>
</div>
<div class="editor-field">
<input type="file" id="fuImage" name="file" />
</div>
<div class="editor-label">
<%:Html.Label("Template") %>
</div>
<div class="editor-field">
<input type="file" id="temp" name="temp"/>
</div>
<p>
<input type="submit" value="Create" />
</p>
I'm quite stuck in this since I can not use IEnumerable<HttpPostedFileBase> files as a parameter in Create method because I need to save it in a different field, or can I? How should I approach this? Please help :S
Note: Image upload works fine.
Why not use IEnumerable<HttpPostedFileBase> ? You may use it like this.
[HttpPost]
public ActionResult Create(Report report, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
//Let's take first file
if(files.ElementAt(0)!=null)
{
var file1=files.ElementAt(0);
if (file1!= null && file1.ContentLength > 0)
{
//do processing of first file
}
}
//Let's take the second one now.
if(files.ElementAt(1)!=null)
{
var temp =files.ElementAt(1);
if (temp!= null && temp.ContentLength > 0)
{
//do processing of second file here
}
}
}
//Do your code for saving the data.
return RedirectToAction("Index");
}
EDIT : After seeing your View Markup in your EDIT.
The name of the file input element should be same as the parameter name in your action method. (files in this example)
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<b>File 1</b>
<input type="file" name="files" id="file1" />
<b>File 2</b>
<input type="file" name="files" id="file2" />
<input type="submit" />
}
This code assumes that read ONLY the first 2 entries from the collection.Since you wanted only 2 files, i hardcoded the indexes.
Phil has a nice blog post explaining about it very nicely.

Can't convert HttpFileCollectionBase to HttpFileCollection

I have a partial view:
<% using (Html.BeginForm("add", "home", FormMethod.Post,
new { enctype = "multipart/form-data" })){%>
<input name="IncomingFiles" type="file" />
<div class="editor-field"><%: Html.TextBox("TagsInput") %></div>
<p><input type="submit" value="Create" /></p><% } %>
And this in the controller:
[HttpPost]
public ActionResult add(HttpFileCollection IncomingFiles, string TagsInput)
{
return View();
}
It will simply not match up my uploaded file to the HttpFileCollection, they come out as HttpFileCollectionBase.
How can i get the view to pass me a HttpFileCollection?
Do i need any specific BeginForm args?
Thank you!
Do something like this instead on your action side. You don't pass the files as parameters:
[HttpPost]
public ActionResult add(string TagsInput) {
if (Request.Files.Count > 0) {
// for this example; processing just the first file
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength == 0) {
// throw an error here if content length is not > 0
// you'll probably want to do something with file.ContentType and file.FileName
byte[] fileContent = new byte[file.ContentLength];
file.InputStream.Read(fileContent, 0, file.ContentLength);
// fileContent now contains the byte[] of your attachment...
}
}
return View();
}

File upload MVC

With the following markup in my view:
<form action="Categories/Upload" enctype="multipart/form-data" method="post">
<input type="file" name="Image">
<input type="submit" value"Save">
</form>
And in my controller:
public ActionResult Upload(FormCollection form)
{
var file = form["Image"];
}
The value of file is null.
If I try it in a different view using a different controller Controller and it works with the same code.
I have VS2008 on Vista, MVC 1.0.
Why?
Malcolm
Use HttpPostedFileBase as a parameter on your action. Also, add the AcceptVerb attribute is set to POST.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(HttpPostedFileBase image)
{
if ( image != null ) {
// do something
}
return View();
}
This code is quite in the spirit/design of ASP.NET MVC.
Not to be picky here or anything, but here's how the code ought to look, as Daniel is missing a few minor details in the code he's supplied...
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadPlotImage(HttpPostedFileBase image)
{
if ( image != null )
{
// do something
}
return View();
}
Try this code:
public ActionResult Upload()
{
foreach (string file in Request.Files)
{
var hpf = this.Request.Files[file];
if (hpf.ContentLength == 0)
{
continue;
}
string savedFileName = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "PutYourUploadDirectoryHere");
savedFileName = Path.Combine(savedFileName, Path.GetFileName(hpf.FileName));
hpf.SaveAs(savedFileName);
}
...
}
Even I was facing a problem , The value was null in image at
public ActionResult UploadPlotImadge(HttpPostedFileBase image)
Earlier I didn't add [AcceptVerbs(HttpVerbs.Post)] which I added. Even after adding it, it didn't work because the second part I was missing, enctype="multipart/form-data", needed to be in the form tag ..
Now it works for me ....
try this class and below action and fix folder path in AppSetting.
config:
<appSettings>
<add key="UploadFolerPath" value="..Your folder path" />
</appSettings>
view:-
<form action="Account/AddImage" id="form_AddImage" method="post" enctype="multipart/form-data">
<input type="file" id="Img" name="Img" class="required" />
<input type="submit" value="Upload" id="btnSubmit" />
</form>
Class:-
public class FileUpload
{
public string SaveFileName
{
get;
set;
}
public bool SaveFile(HttpPostedFileBase file, string FullPath)
{
string FileName = Guid.NewGuid().ToString();
FileName = FileName + System.IO.Path.GetExtension(file.FileName);
SaveFileName = FileName;
file.SaveAs(FullPath + "/" + FileName);
return true;
}
}
//Post Action
[HttpPost]
public ActionResult AddImage(FormCollection Form)
{
FileUpload fileupload = new FileUpload();
var image="";
HttpPostedFileBase file = Request.Files["Img"];
if (file.FileName != null && file.FileName != "")
{
if (upload.ContentLength > 0)
{
fileupload.SaveFile(Request.Files["Img"], Server.MapPath(AppSetting.ReadAppSetting("UploadFolerPath")));
image = fileupload.SaveFileName;
// write here your Add/Save function
return Content(image);
}
}
else
{
//return....;
}
}

Resources