MVC 3 fileupload dialog - asp.net-mvc

I think those tags pretty much says what i'm asking..
I have been struggling with file upload. What I need to achieve is open a dialog for file upload and save it to database, so nothing too fancy.
Basic file upload is more than easy to make. Just form with correct encrypt and input type file. But when I insert my form to dialog something goes wrong and there is nothing in Post. I tried to add test parameters like filename and it worked fine. But the actual file is missing in post.
here's some code:
Form:
#using (Html.BeginForm("Edit", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" })){
<label for="Name">Filename: </label>
<input type="text" name="name" id="name"/>
<input type="file" name="file" id="file" />
<input type="submit"/>
}
Controller:
public ActionResult Edit(Attachment model)
{
var strLen = Convert.ToInt32(model.file.InputStream.Length);
var strArr = new byte[strLen];
model.file.InputStream.Read(strArr, 0, strLen);
return View();
}
Edit:
Model:
public class Attachment
{
public string Name { get; set; }
public HttpPostedFileBase file{ get; set; }
}
This form is inside the dialog.

Try this,
public ActionResult Edit(HttpPostedFileBase file)
{
////
return View();
}

Related

Upload File From View to Controller in .net Core

I'm trying to create a .net core project with file upload.
In the model I have a class name "Movie" with 2 properties: Image - of type byte[] and Picture - of type IFormFile.
In the view I added a form with the input:
<input asp-for="Picture" type="file" id="image_upload" />
And in my controller I have a function like that:
public IActionResult NewMovie(Movie movie){...
In the movie object that is passed the property Image and Picture are always NULL.
I tried changing the asp-for from Image to Picture, to change the function to be of type Task, to add IFormFile to the function calling and nothing helped.
I never been able to get the file's data. I need it to be of type byte[] but I'll take anything to help me.
Thank you all in advance.
You dont need to store the image in a byte array your model only needs an IFormFile like this:
Model:
[Required(ErrorMessage = "The {0} field is required")]
[Display(Name = "Image")]
[DataType(DataType.Upload)]
public IFormFile Image { get; set; }
Controller:
if (model.Image == null)
return View(model);
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath,"Your upload path");
string ImagePath = Guid.NewGuid().ToString() + "_" + model.Image.FileName;
string filePath = Path.Combine(uploadsFolder, ImagePath);
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
await model.Image.CopyToAsync(fs);
}
Add this to your form tag: enctype="multipart/form-data".
Its essential for the type="file" input to be submitted.
View:
<form enctype="multipart/form-data" Other attributes...>
<div class="custom-file">
<input asp-for="Model.Image" type="file" class="custom-file-input fileUpload" />
<label class="custom-file-label fileLabel">Choose file</label>
</div>
<input type="submit" value="Submit" />
</form>
And finally you save the ImagePath only in your db entity.

get information from form to controller and save it in database

I have this code in my html.And i want to post this information from form to controler and save in data base.
<form method="POST" class="contactme form-group">
<input type="text" placeholder="Name" class="form-control inputcontact">
<input type="text" placeholder="Surename" class="form-control inputcontact">
<input type="email" placeholder="E-mail" class="form-control inputcontact">
<input type="tel" pattern="[0-9]{5,10}" class="form-control inputcontact" placeholder="tel. number"><br>
<input type="submit" class="btn btn-default buttonsend" value="Оставить заявку">
</form>
And i have this model:
public int Id { get; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string Phonenumber { get; set; }
The MVC concept is quite straight forward for achieving what you need. It's usual to have a model that contains properties for the data that you need to display a "View" and also for the content entered by the user so the data can be bound to the model when posted. If you've not got any controller code yet then I would recommend the below approach.
First, write a controller to handle the displaying of your view and the posting of the views form content.
public class YourController : Controller
{
[HttpGet]
public ActionResult YourViewName()
{
var myViewModel = new YourViewModel();
//Populate model data from services etc...
return View("YourViewName", myViewModel);
}
}
I find it easier to wrap my views data objects that it needs in a class.
public class YourViewModel
{
public string Property1 { get; set; }
public int Property2 { get; set; }
\\etc...
}
Then in your view, wrap your controls in a Form and use Html helper controls to display and bind to the data in the model.
#using (Html.BeginForm("ActionName", "YourController ", FormMethod.Post, new { id = "FormName"}))
{
#Html.TextBoxFor(x => x.YourModel.Property1, null, new { #class = "SomeCssClass"})
\\Repeat for all properties that need displaying or for user input.
}
You will also need a submit button on the form to post the form to your specified controller.
<button id="btnSubmitForm" type="Submit" class="SomeCssClass">Submit</button>
Then in your controller you create a method to receive the posted form (Model)
[HttpPost]
public ActionResult ActionName(YourViewModel postedContent)
{
//Handle saving etc.. here.
var x = postContent.Property1;
//Do something with data
//Re populate model and show updated view.
var myViewModel = new YourViewModel();
return View("YourViewName", myViewModel);
}
Thant should help you on your way. A lot of this is down to preference and opinions though.
You have to tell it which Controller and which Action in the controller to look for like below:
using (Html.BeginForm("YourActionMethodHere", "YourControllerHere", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
<input type="text" placeholder="Name" class="form-control inputcontact">
<input type="text" placeholder="Surename" class="form-control inputcontact">
<input type="email" placeholder="E-mail" class="form-control inputcontact">
<input type="tel" pattern="[0-9]{5,10}" class="form-control inputcontact" placeholder="tel. number"><br>
<input type="submit" class="btn btn-default buttonsend" value="Оставить заявку">
}
This link should also help

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.

File upload bound to the Viewmodel

I have a form where I am uploading multiple files and there are a couple of textboxes and some checkboxes associated with each file being uploaded.
I have seen examples for uploading multiple files where the actionresult signature is something like this:
[HttpPost]
public ActionResult Upload(IEnumerable<HttpPostedFileBase> fileUpload)
However, I cant find any example where I can have multiple files uploaded where my actionresult signature is something like this:
[HttpPost]
public ActionResult Upload(MyViewModel vm)
The reason I want this viewmodel being posted is because I think its cleaner than using the FormCollection variable and because I want to each file being uploaded and the data added along with its associated textboxes to be grouped together by way of a List<FileUploadPacket> which will part of the ViewModel
UPDATE
My View model below:
public class EmployeeVM
{
public int EmployeeID {get ;set;}
public string EmpName {get ;set;}
//Other properties
public List<FileUploadPacket> FileUploadPackets { get; set; }
}
The FileUploadPacket class which has the property of type HttpPostedFileBase
public class FileUploadPacket
{
public int FileID {get ;set;}
public string UserEnteredDesc {get ;set;}
//some more other properties
public HttpPostedFileBase UpFile { get; set; }
}
Code snippet of my view.aspx as below
<%: Html.TextBoxFor(model => model.EmpName, new { maxLength = 50 })%>
Upload your files here:
<input type="file" id="UpFile" name="UpFile" value="ActionHandlerForForm" />
<%: Html.TextBoxFor(model => model.FileUploadPackets[0].UserEnteredDesc )%>
<input type="file" id="UpFile" name="UpFile" value="ActionHandlerForForm" />
<%: Html.TextBoxFor(model => model.FileUploadPackets[1].UserEnteredDesc )%>
As you can see, I have all the other properties specific to this one file being uploaded kept in its own class. So that in my form an employee can enter his name and upload his files and provide some description and other details for each file. If I move the public HttpPostedFileBase UpFile { get; set; } property to the EmployeeVM class then I will have to collect all the files separately in an array and manually map a file to its description. Is there no way to do this keeping the UpFile property in the FileUploadPacket class itself?
I am using the aspx view engine.
Please help. Thanks for your time...
GetHtml helper is not part of mvc framework, you should look up for third party library containing that helper.
Uploading file that is part of ViewModel is simple though. Basically it goes like this
Define view model
public class MyViewModel
{
public HttpPostedFileBase MyFile { get; set; }
}
Inside Views/Shared/EditorTemplates, create MyViewModel.cshtml
<input type="file" id="MyFile" name="MyFile" />
And view, corresponding to upload action
#model MyViewModel
#using(Html.BeginForm("Upload", "MyController", FormMethod.Post, new { enctype="multipart/form-data"})
{
#Html.EditorForModel()
<input type="submit" value="Upload" />
}
required attribute is important to upload files.
And that's it, once form is submitted, you should see uploaded file inside [HttpPost] action, vm.MyFile.
The fix to this is changing the way you Name and ID the upload control.
<%: Html.TextBoxFor(model => model.EmpName, new { maxLength = 50 })%>
Upload your files here:
<input type="file" id="FileUploadPackets[0].UpFile" name="FileUploadPackets[0].UpFile" value="ActionHandlerForForm" />
<%: Html.TextBoxFor(model => model.FileUploadPackets[0].UserEnteredDesc )%>
<input type="file" id="FileUploadPackets[1].UpFile" name="FileUploadPackets[1].UpFile" value="ActionHandlerForForm" />
<%: Html.TextBoxFor(model => model.FileUploadPackets[1].UserEnteredDesc )%>
This worked for me!! Hope it helps anyone else out there..

ASP.NET MVC File Uploading

HI there,
My model (partial)
public class Document : HttpPostedFileBase
{
public string DocumentTitle { get; set; }
public string DocumentType { get; set; }
My action
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddDocumentToVault(Document model)
{
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
_documentAggregator.Add(model);
_documentAggregator.Commit();
}
return PSDocumentVaultPartial();
}
File uploader
<% using (Html.BeginForm("AddDocumentToVault", "PersonalSpace", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<input type="file" id="Document" runat="server" name="Document"/>
<input id="AddDocument" type="submit" value="Upload" style="display:none"/>
<% } %>
The problem I am having is that when the AddDocument button is pressed it's passing an empty model to the action in my controller. And the base properties in HttpPostedFileBase give a System.NotImplementException.
Can anyone tell me what I need to do to correctly pass my model to my action?
It's an issue with HttpPostedFileBase and model binding. See ASP.NET MVC posted file model binding when parameter is Model

Resources