I am trying to make a file uploading page in my MVC project. First of all i want to manage this locally.
My Questions are:
1- Here is my controller and view. Is there any thing that I have to do to make this code work? I mean defining a model or using jquery, etc. What is the process when a file is being uploaded?
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase uploadFile)
{
if (uploadFile.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("C:/Users/marti/../PhotoGallery/myimages"),
Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(filePath);
}
return View();
}
Here is the View:
<input name="uploadFile" type="file" />
<input type="submit" value="Upload File" />
2- When i debug this, It never goes to controller.
You may need the enctype='multipart/form-data' on your view form:
#model ImageModel
#{
ViewBag.Title = "New Image";
}
<div class="content-form-container width-half">
<form id='PropertiesForm' action='#Url.Action(ImageController.Actions.Add, ImageController.Name)' method='post' enctype='multipart/form-data' class='content-form'>
#Html.Partial("ImageName")
<fieldset class='content-form-1field'>
<div class='legend'>
file to upload
</div>
#Html.LabelledFileInput(ImageView.FileName, string.Empty)
</fieldset>
<div class='buttons'>
#Html.Button("button-submit", "submit")
</div>
</form>
</div>
#section script{
#Html.JavascriptInclude("~/js/image/new.min.js")
}
And here is my controller code:
[HttpPost]
[MemberAccess]
public ActionResult Add()
{
var name = ImageView.ImageName.MapFrom(Request.Form);
if (Request.Files.Count == 0)
{
RegisterFailureMessage("No file has been selected for upload.");
return ValidationFailureAdd(name);
}
var file = Request.Files[0];
if (file == null || file.ContentLength == 0)
{
RegisterFailureMessage("No file has been selected for upload or the file is empty.");
return ValidationFailureAdd(name);
}
var format = ImageService.ImageFormat(file.InputStream);
if (format != ImageFormat.Gif && format != ImageFormat.Jpeg && format != ImageFormat.Png)
{
RegisterFailureMessage("Only gif, jpg and png files are supported.");
return ValidationFailureAdd(name);
}
if (query.HasName(name))
{
RegisterFailureMessage(string.Format("Image with name '{0}' already exists.", name));
return ValidationFailureAdd(name);
}
using (var scope = new TransactionScope())
{
var id = Guid.NewGuid();
var fileExtension = ImageService.FileExtension(format);
Bus.Send(new AddWikiImageCommand
{
Id = id,
Name = name,
FileExtension = fileExtension
});
var path = Path.Combine(ApplicationConfiguration.MediaFolder,
string.Format("{0}.{1}", id.ToString("n"), fileExtension));
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
file.SaveAs(path);
scope.Complete();
}
return RedirectToAction(Actions.Manage);
}
There are some custom bits in there so you can ignore those. The gyst of what you need should be there.
HTH
Related
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>
}
}
hi every one first time to ask here. So here is my Create post method on multiple images plus other data entries and it works with out any problem and it uploads all images and the content. My question is how to handle edit Post controller on multiple images.
here is the Create controller
public ActionResult SaveDataAdded([Bind(Include = "SId,Category,SName,LocalName,CommonName,Description,PicTakenBy,ContentBy,EditedBy")]SpeciesDataTable ARow, HttpPostedFileBase file,HttpPostedFileBase file2, HttpPostedFileBase file3, HttpPostedFileBase file4)
{if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
using (var Bnryreader = new System.IO.BinaryReader(file.InputStream))
{
ARow.MainPic = Bnryreader.ReadBytes(file.ContentLength);
}
}
if (file2 != null && file2.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file2.InputStream))
{
ARow.SecPic = reader.ReadBytes(file2.ContentLength);
}
}
if (file3 != null && file3.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file3.InputStream))
{
ARow.ThirdPic = reader.ReadBytes(file3.ContentLength);
}
}
if (file4 != null && file4.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file4.InputStream))
{
ARow.FourthPic = reader.ReadBytes(file4.ContentLength);
}
}
db.SpeciesDataTables.Add(ARow);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ARow);
}
and here is the code block for edit. Probably my approach was not correct. But i need help on this.
public ActionResult EditSpeciesPost([Bind(Include = "SId,Category,SName,LocalName,CommonName,Description,PicTakenBy,ContentBy,EditedBy")]SpeciesDataTable Editor, HttpPostedFileBase file, HttpPostedFileBase file2, HttpPostedFileBase file3, HttpPostedFileBase file4)
{
if (file != null && file.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file.InputStream))
{
Editor.MainPic = reader.ReadBytes(file.ContentLength);
}
}
if (file2 != null && file2.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file2.InputStream))
{
Editor.SecPic = reader.ReadBytes(file2.ContentLength);
}
}
if (file3 != null && file3.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file3.InputStream))
{
Editor.ThirdPic = reader.ReadBytes(file3.ContentLength);
}
}
if (file4 != null && file4.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file4.InputStream))
{
Editor.FourthPic = reader.ReadBytes(file4.ContentLength);
}
}
db.Entry(Editor).State = EntityState.Modified;
db.SaveChanges();
//return RedirectToAction("Index");
return View(Editor);
}
here is the view for edit
#using(Html.BeginForm("EditSpecies", "Species", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="col-md-10">
#if (Model.MainPic != null) // to view first image
{
var base64 = Convert.ToBase64String(Model.MainPic);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
<img src='#imgsrc' style="max-width:100px;max-height:100px" />
}
</div>
<div class="col-md-10">
<input type="file" name="file" /> // input for first image
</div>
<div class="col-md-10">
#if (Model.SecPic != null)// to view second image
{
var base64 = Convert.ToBase64String(Model.SecPic);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
<img src='#imgsrc' style="max-width:50px;max-height:50px" />
}
</div>
<div class="col-md-10">
<input type="file" name="file2" /> input for third image
</div>
// and it continues to third and fourth picture
}
What you should be doing is, sending only null for the images user has not updated in the UI and post the data to the httppost action method where you read the existing entity and update only those properties needed to update.
I would create a view model for my view with properties needed for the view.
public class SpeciesVm
{
public int Id { set; get; }
public string Name { set; get; }
public string LocalName { set; get; }
public HttpPostedFileBase MainImg { set; get; }
public HttpPostedFileBase SecondImg { set; get; }
public string MainPicImgSrc { set; get; }
public string SecondPicImgSrc { set; get; }
}
Now in your GET action, you create an object of this, load the property values.
public ActionResult Edit(int id)
{
var e=db.SpeciesDataTables.Find(id);
var vm = new SpeciesVm() { Id=id , Name =e.SName };
vm.LocalName= e.LocalName;
if(e.MainPic!=null)
{
vm.MainPicImgSrc = $"data:image/jpg;base64,{Convert.ToBase64String(e.MainPic)}";
}
if(e.SecPic!=null)
{
vm.SecondPicImgSrc = $"data:image/jpg;base64,{Convert.ToBase64String(e.SecPic)}";
}
return View(vm);
}
Now in your view, you will use the properties of type HttpPostedFileBase for the file input
#model SpeciesVm
#using (Html.BeginForm("Edit","Species", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.HiddenFor(a=>a.Id)
#Html.HiddenFor(a=>a.Name)
#Html.HiddenFor(a=>a.LocalName)
<div class="col-md-10">
#if (!string.IsNullOrEmpty(Model.MainPicImgSrc))
{
<img src='#Model.MainPicImgSrc' />
}
<input type="file" name="MainImg" />
</div>
<div class="col-md-10">
#if (!string.IsNullOrEmpty(Model.SecondPicImgSrc))
{
<img src='#Model.SecondPicImgSrc' />
}
<input type="file" name="SecondImg" />
</div>
<button type="submit">Save</button>
}
Now in your HttpPost action method, you will use the same view model as the parameter, read the Id property value, using which read existing entity and update the properties as needed.
[HttpPost]
public ActionResult Edit(SpeciesVm model)
{
var e=db.SpeciesDataTables.Find(id);
e.SName = model.Name;
//Update the image properties only if it was send from the form
if(model.MainImg!=null)
{
e.MainPic = GetByteArrayFromImage(model.MainImg);
}
if(model.MainImg!=null)
{
e.SecPic = GetByteArrayFromImage(model.SecondImg);
}
db.SaveChanges();
return RedirectToAction("Index");
}
private byte[] GetByteArrayFromImage(HttpPostedFileBase file)
{
if (file == null)
return null;
var target = new MemoryStream();
file.InputStream.CopyTo(target);
return target.ToArray();
}
I have a function for uploading selected files into folder in asp mvc4. The code in view page is
<form id="form1" method="post" enctype="multipart/form-data" action="EmployeeDetails/Upload">
<input type='file' id="imgInp" accept="image/jpeg"/>
<p>
<input type="submit" value="Upload" class="btn"/>
</p>
</form>
And the controller code is
[HttpPost]
public ActionResult Upload(HttpPostedFileBase imgInp)
{
if (imgInp != null && imgInp.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(imgInp.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/images/Profile"), fileName);
imgInp.SaveAs(path);
}
return view("Index");
}
Instead of this i want to send the image from view to controller as Json. Or is there any other methods to upload image without refreshing the view page..?
You can send form using ajax...
<form id="login-form">
<input type="file" name="photo" id="files" accept="image/*;capture=camera">
<button type="submit" onclick="submitform()">Submit</button>
</form>
jquery
function submitform(){
var postdata = $('#login-form').serialize();
var file = document.getElementById('files').files[0];
var fd = new FormData();
fd.append("files", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", "/Home/Index", false);
xhr.send(fd);
}
controller
[HttpPost]
public JsonResult Index(FormCollection data)
{
if (Request.Files["files"] != null)
{
using (var binaryReader = new BinaryReader(Request.Files["files"].InputStream))
{
var Imagefile = binaryReader.ReadBytes(Request.Files["files"].ContentLength);//your image
}
}
}
uploading file to the server is quite simple. we need is a html form having encoding type set to multipart/form-data and a file input control.
View: NewProduct.cshtml
<form method="post" enctype="multipart/form-data">
<fieldset>
<legend>New Product</legend>
<div>
<label>Product Name:</label>
#Html.TextBoxFor(x => x.ProductName)
</div>
<div>
<label>Product Image:</label>
<input name="photo" id="photo" type="file">
</div>
<div>
#Html.ValidationSummary()
</div>
<input type="submit" value="Save" />
</fieldset>
</form>
The uploaded files are available in HttpFileCollectionBase of Request.Files.
controller:
[HttpPost]
public ActionResult NewProduct()
{
HttpPostedFileBase image = Request.Files["photo"];
if (ModelState.IsValid)
{
if (image != null && image.ContentLength > 0)
{
var fileName = Path.GetFileName(image.FileName);
string subPath = Server.MapPath("ProductLogo");
bool isExists = System.IO.Directory.Exists(subPath);
if (!isExists)
System.IO.Directory.CreateDirectory(subPath);
var path = Path.Combine(subPath+"\\", fileName);
if (System.IO.File.Exists(path))
{
var nfile = DateTime.Now.ToString() + "_" + fileName;
path = Path.Combine(subPath+"\\", nfile);
}
file.SaveAs(path);
return RedirectToAction("List", "Product");
}
else
{
ModelState.AddModelError("", "Please Select an image");
return View();
}
}
else
{
return View();
}
}
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();
}
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....;
}
}