Asp.Net MVC Razor FileUpload Html Helper into existing View - asp.net-mvc

I have have a View where I add products to a simple WebStore. I want to have multiple images with one product. That's why I use FileUpload from Microsoft.Web.Helpers. The use of FileUpload in my View is like this:
#FileUpload.GetHtml("Upload", 5, true, true, addText: "Add more", uploadText: "Upload files")
Then I have some labels and fields for other product attributs like this:
<div class="editor-field"><br>
#Html.EditorFor(model => model.Title)<br>
#Html.ValidationMessageFor(model => model.Title)<br>
</div>
The problem is that when I use post method, my controller does not get anything. I use controller like this:
[HttpPost]
public ActionResult Create(Product product, IEnumerable<HttpPostedFileBase> fileUpload)
{
foreach (var file in fileUpload)
{
var fileName = Path.GetFileName(file.FileName);
}
return RedirectToAction("Index");
}
So does anyone have any idea what I am doing wrong. Because my FileUpload object is always empty.

Most likely your BeginForm is missing the required field. It should look like this:
using(Html.BeginForm("Index", "Home", FormMethod.Post,
new { enctype="multipart/form-data" })) {
}

Now using HttpPostedFileBase in mvc 4 easy to upload multiple files, EditorFor FileUpload in asp.net mvc 4 razor

I had this problem last night FileUpload control and the parameter name should be the same
Change:
public ActionResult Create(Product product, IEnumerable<HttpPostedFileBase> **fileUpload**)
to
public ActionResult Create(Product product, IEnumerable<HttpPostedFileBase> **upload**)

Related

ASP.NET MVC - URL Action Path

I am writing an app using ASP.NET MVC. I'm in a view that is located at:/orders/{orderId}. That view renders just fine. Inside of it though, I have a button inside of a form that looks like this:
<form action="/orders/{orderId}/flag" method="post">
<button type="submit" class="btn">Flag</button>
</form>
In my controller, I have the following:
public class OrdersController : Controller
{
public ActionResult Details(string id)
{
var model = Orders.FindById(id);
return View(model);
}
public ActionResult Flag(string id)
{
var model = Orders.FindById(id);
model.Flag();
return RedirectToAction(
}
}
My question is, how do I use the ASP.NET MVC helpers to generate the path to my flag action? The action in my form is just a template at the moment which won't work. How do I address this scenario in my razor view?
Thanks!
#Url.Action("Flag", "Orders", new { id = [orderid here] })
I recommend using T4MVC, the you can do:
#Url.Action(MVC.Orders.Flag([orderid here])

MVC5 ViewModel binding in HTTP GET?

I have an action like this
public ActionResult Overview(TimeAxisVM TimeAxis = null)
{
return View(new OverviewVM());
}
View model like this
public class TimeAxisVM
{
// omitted ctor
[DataType(DataType.DateTime)]
public DateTime? From { get; set; }
[DataType(DataType.DateTime)]
public DateTime? To { get; set; }
}
An editor template for the view model
#model TimeAxisVM
#using (Html.BeginForm("Overview", "Controller", FormMethod.Get))
{
#Html.EditorFor(model => model.From)
#Html.EditorFor(model => model.To)
<button type="submit">Submit</button>
}
And a view for the Overview action like this
#model OverviewVM
#Html.EditorFor(model => model.TimeAxis)
When I execute the GET request this is the query string is TimeAxis.From=22.+02.+2014&TimeAxis.To=25.+02.+2014 but once in the action TimeAxis.From and TimeAxis.To are both null.
If I change the form method to POST it immediately works as expected. From design point of view this should/has to be a GET request.
Any ideas how to make the model binding work for GET?
UPDATE:
Changing the action to
public ActionResult Overview(DateTime? From = null, DateTime? To = null)
and sending the request in this form: .../Overview/?From=22.+02.+2014&To=25.+02.+2014 works as well.
But I'd like to keep it encapsulated in the class and dont need to change the input field name - EditorFor generates them as TimeAxis.From and TimeAxis.To. I might add other properties to the ViewModel/form.
I found the answer. HTTP GET requests are culture invariant, whereas HTTP POST requests respect current culture in ASP.NET MVC.
http://weblogs.asp.net/melvynharbour/archive/2008/11/21/mvc-modelbinder-and-localization.aspx
If you want to bring the Model again into the view, you need to pass the ModelView back to the View like
return View(TimeAxis);
then, I think you do not have a controller called Controller do you? You might have a HomeController or something else, no?
in that case, please amend you form to
#using (Html.BeginForm("Overview", "Home", FormMethod.Get))
if for example you're Overview action is in the Home controller
all in all, your controller and view should be:
public ActionResult Overview(TimeAxisVM TimeAxis)
{
return View(TimeAxis);
}
and
#using (Html.BeginForm("Overview", "Home", FormMethod.Get))
{
#Html.EditorFor(Model => Model.From)
#Html.EditorFor(Model => Model.To)
<button type="submit">Submit</button>
}
here's the screencast of the code above: http://screencast.com/t/7G6ofEq0vZEo
Full source: http://ge.tt/1Uh80pK1/v/0?c

Create a folder with a name typed by user in textbox ASP.NET MVC 4 Razor

I'm new to ASP.NET MVC 4.
I'm able to create a folder with a hardcoded name using Directory.CreateDirectory(#"C:/") in my controller, but what I need to do is have the user type the desired folder name into a textbox, and pass that information to the CreateFolder method in the Controller.
Here's the method:
public ActionResult CreateFolder(String newFolderName)
{
Directory.CreateDirectory(#"C:\..." + newFolderName);
return View();
}
In my view I need a textbox for the user to define the desired folder name, and a button that creates the folder with the selected name.
How should I handle this?
I've tried some suggestions from the web, but can't seem to get it going.
View:
#using Folder
#using ( #Html.BeginForm( "CreateFolder", "ControllerName", FormMethod.Post) )
{
#Html.TextBoxFor(x=>x.FolderName)
<input type="submit" id="btnCreateFolder" value="Create Folder" />
}
Model:
public class Folder
{
// other properties
string FolderName {get;set;}
}
Controller:
[HttpPost]
public ActionResult CreateFolder(Folder model)
{
Directory.CreateDirectory(#"C:\..." + model.FolderName);
return View();
}

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