How to pass textbox values to MVC Action? - c#

I have tried the below but I get the compliation error:
The name 'txtMakeModelTypeCode' does not exist in the current context.
<label>Type Code</label>
<input type="text" id="txtMakeModelTypeCode" name="txtMakeModelTypeCode" />
<label>Make</label>
<input type="text" id="txtMake" name="txtMake"/>
<label>Model</label>
<input type="text" id="txtModel" name="txtModel"/>
Create
I have also tried using a form but I don't want to use a submit button. Is it possible to use a plain button?
#using (Html.BeginForm("CreateMakeModel", "Vehicle"))
{
<label>Type Code</label>
#Html.TextBox("txtMakeModelTypeCode")
<label>Make</label>
#Html.TextBox("txtMake")
<label>Model</label>
#Html.TextBox("txtModel")
<input type="submit" value="Create" />
}

MVC does not work the same as ASP.Net Webforms. The textboxes you create are not available in code. You use the controls to render your html and handling of data is done via the model.
So use TextBoxFor:
#using (Html.BeginForm("CreateMakeModel", "Vehicle"))
{
<label>Type Code</label>
#Html.TextBoxFor(m => m.MakeModelTypeCode)
<label>Make</label>
#Html.TextBoxFor(m => m.Make)
<label>Model</label>
#Html.TextBoxFor(m => m.Model)
<input type="submit" value="Create" />
}
Then in your controller, after the post, you should have the posted data in the model:
public ActionResult Index(CreateMakeModel model) // or is it Vehicle?
{
// whatever you do here:
string code = model.MakeModelTypeCode;
}

Related

File upload ASP.NET MVC in multiple submits form

I have a small tool that downloads reports based on the specified options. The download works well. And now, I want to also upload a file to the folder and then further use it.
The problem is that I already have one submit button on the form that is used for the download and when I am adding another button for the upload, only download is triggered.
I tried to resolve it using an #Html.ActionLink(), but no success. Is there any proper way to resolve the issue? I know that there is a possibility to capture the submit value and then check in one main ActionResult in the Controller and redirect to the respective ActionResult, but I don't want to do it, since there are too many POST Actions in one controller.
Here is my View - download.cshtml:
#using (Html.BeginForm())
{
<fieldset>
<div class="title">Click to download report</div>
<div class="field">
<input id="downloadBtn" type="submit" class="button" value="Download" />
</div>
</fieldset>
<fieldset id="Option_ClientInfo">
<div class="title">
Image
</div>
<div class="field">
<input type="file" name="ImageUpload" accept="image/jpeg" />
<p>#Html.ActionLink("Upload", "UploadImage", new { controller = "Home", enctype = "multipart/form-data"}, new { #class = "button" })</p>
</div>
</fieldset>
}
And the controller - HomeController.cs:
public partial class HomeController : Controller
{
// some functions
// ....
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadImage(HttpPostedFileBase imageFile)
{
string path = Path.Combine(this.GetImageFolder, Path.GetFileName(imageFile.FileName));
imageFile.SaveAs(path);
return null;
}
// additional POST functions for other forms
// ....
[HttpPost]
public ActionResult Download(Info downloadInfo)
{
// perform checks and calculations
return new reportDownloadPDF(downloadInfo);
}
}
Any suggestion in appreciated.
The solution is just separate upload and download functionalities using two forms so it wont conflict while submitting.
#using (Html.BeginForm())
{
<fieldset>
<div class="title">Click to download report</div>
<div class="field">
<input id="downloadBtn" type="submit" class="button" value="Download" />
</div>
</fieldset>
<fieldset id="Option_ClientInfo">
<div class="title">
Image
</div>
</fieldset>
}
#using (Html.BeginForm("UploadImage", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<fieldset>
<div class="field">
<input type="file" name="ImageUpload" accept="image/jpeg" />
<p>
<input id="uploadBtn" type="submit" class="button" value="Upload" />
</p>
</div>
</fieldset>
}
There is another issue as well. Image control name and Post Action method parameter name should be same.
So your upload image Post Action method will be:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadImage(HttpPostedFileBase imageUpload)
{
string path = Path.Combine(this.GetBasePath + "/img/tmp/", Path.GetFileName(imageFile.FileName));
imageFile.SaveAs(path);
return null;
}

ASP.NET MVC: Why request is being caught by the wrong method?

I'm using to wrap my forms the following helper:
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post)) { ... }
In my Controller I have two methods, one for loading my partial view and another one for processing the Post request:
[SomeFilter]
[ChildActionOnly]
[AcceptVerbs(HttpVerbs.Get)]
public PartialViewResult Edit(int id)
{
//Some Code
}
[SomeFilter]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MyViewModel model, string submit) {
//Some Code
}
Everything seems to be working fine except when users submit an empty form. In that case request is being caught by GET Method instead of POST one. I know it's calling the GET method because I get an exception as:
"The action 'Edit' is accessible only by a child request."
And only the GET overload has [ChildActionOnly] filter. I don't understand why is this happening. Both are different and both are decorated.
Any suggestions?
Partial View code:
#model MVC.Models.MyViewModel
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post))
{
#Html.HiddenFor(m => m.Id)
#Html.AntiForgeryToken()
<div class="row margin-top-20 form-group text-center">
<div class="col-md-3 col-lg-offset-2">
#Html.LabelFor(m => m.ManyItemsAvailable)
#Html.ListBox("ManyItemsAvailable", Model.ItemsAvailable)
</div>
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" />
<div class="col-md-3">
#Html.LabelFor(m => m.ManyItemsSelected)
#Html.ListBox("ManyItemsSelected", Model.ItemsSelected)
</div>
</div>
}
So, I replaced both submit buttons with these:
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" formmethod="post" />
Explicitly specifying formmethod="post" and it's now working as expected.

Upload multiple files in one form MVC4

I'm trying to upload multiple images on one form
#using (Html.BeginForm("Create", "AdminRestaurants", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label for="logoFile" class="col-sm-2 control-label">Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="logoFile" id="logoFile" />
</div>
</div>
<div class="form-group">
<label for="fohFile" class="col-sm-2 control-label">FOH Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="fohFile" id="fohFile" />
</div>
</div>
<div class="form-group">
<label for="bohFile" class="col-sm-2 control-label">BOH Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="bohFile" id="bohFile" />
</div>
</div>
<div class="form-group">
<label for="mgmFile" class="col-sm-2 control-label">MGM Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="mgmFile" id="mgmFile" />
</div>
</div>
I'm trying to process the form on the controller with this
public ActionResult Create(IEnumerable<HttpPostedFileBase> files, RestaurantModel collection)
{
if (ViewData.ModelState.IsValid)
{
}
}
Currently nothing shows up in the files signature on the controller. This seems to work great when only working with one file
public ActionResult Create(HttpPostedFileBase file, EventsModel collection)
Can someone point me in the direction to allow multiple files to be uploaded with one submission form?
Your problem is that you form creates a post request with information that the model binder can bind because the naming convention is not right.
you see, you have 4 file fields each with a different name, for the model binder to bind them correctly your controller action signature should look like this:
public ActionResult Create(HttpPostedFileBase mgmFile,
HttpPostedFileBase logoFile,
HttpPostedFileBase fohFile ,
HttpPostedFileBase bohFile)
Following MCV design pattern The best option would be to use a ViewModel that holds an IEnumerable<HttpPostedFileBase>
and you would create a custom editor template for an IEnumerable<HttpPostedFileBase>
so that you could use it like that:
Html.EditorFor(m=>Model.filesUploaded)
and your controller action would look like this:
public ActionResult Create(MyViewModel i_InputModel)
{
i_InputModel.filesUploade; //Use the files here to upload them.
}
Other options are:
Use the HTML5 multiple attribute on the file input field like this:
<label for="mgmFile" class="col-sm-2 control-label">Files:</label>
<div class="col-sm-6">
<input type="file" multiple="multiple" name="files" id="files" />
</div>
and a controller action like this:
public ActionResult Create(HttpPostedFileBase files)
or use multiple file fields but index them in their name:
<input type="file" multiple="multiple" name="files[0]" id="files_1" />
<input type="file" multiple="multiple" name="files[1]" id="files_2" />
<input type="file" multiple="multiple" name="files[2]" id="files_3" />
<input type="file" multiple="multiple" name="files[3]" id="files_4" />
and then you could use a controller action like this:
public ActionResult Create(IEnumerable<HttpPostedFileBase> files)
This would only work if your file inputs had indexed names like files[0], files[1], files[2],...
In order to understand how model binding to a list works in asp.net mvc, I recommend that you read this post: Model Binding to a List
You don't even have to use model binding to get the files. Use Request.Files in your Action to get them.
public ActionResult Create(EventsModel collection)
{
var files = Request.Files;
// rest of the code...
}
<td>
<input type="file" name="files" id="files" multiple="multiple" />
</td>
As Here, I demonstrate with simple example : http://www.infinetsoft.com/Post/How-to-create-multiple-fileUpload-using-asp-net-MVC-4/1229#.V0J-yfl97IU

How to send text from the textbox to the actionResult?

I have a question about MVC4 (Razor). I have page where I want to filter data. There is a textbox (input) and a submit button. I want to move the text in the textbox to the actionresult. How can I resolve this?
On my page I've the following row:
#{ using (Html.BeginForm("Experiences"))
{
<span class="label">Filter on:</span><input id="FilterText" type="text" size="50"/>
<input type="submit" value="Submit" name="knowledge" /><br />
}
}
<br />
And I want to call the ActionResult Experiences
public ActionResult Experiences(string knowledge = "")
{
ReadExperienceData(knowledge);
return View(ListOfExperiences);
}
Specify the name property value of the input element same as the action method parameter name.
<input id="FilterText" name="knowledge " type="text" size="50"/>
<input type="submit" value="Submit" name="submitKnowledge" />
Also it looks like you are not using the Beginform method properly. You may try any of the below overloads, as needed
#using(Html.Beginform("Knowledge","YourControllerName"))
{
//form elements
}
or
#using(Html.Beginform())
{
//form elements
}

In ASP.NET MVC, how do I return a different view when submitting a form via ajax?

I am attempting to create a message board in ASP.NET MVC. I have two partial views, one to display a message (this is recursive and will display all child... messages as well), and one to display a form to submit new messages. When a message gets posted, I want the form to submit via ajax, and return the partial view to display a message (the message that was just posted).
This is the partial view for displaying the form (NewMessage)
#model Intranet.Entities.ForumRepository.Message
<div id="#Html.Raw("formbox" + Model.ParentID)">
#using (Ajax.BeginForm("NewMessage", new AjaxOptions { UpdateTargetId = "formbox" + Model.ParentID })) {
#Html.TextAreaFor(m => m.Text, new { #class = "responsebox" })
#Html.HiddenFor(m => m.ParentID)
<br /><input type="submit" value="Save Comment" class="savebutton" />
}
</div>
And its submit method
[HttpPost]
public ActionResult NewMessage(ForumRepository.Message message) {
if (ModelState.IsValid) {
RouteData.Values.Add("Responses", message);
//message.SaveMessage();
return PartialView("DisplayMessage", message);
} else {
return PartialView(message);
}
}
When I attempt to submit the form, the form view doesn't get replaced with the DisplayMessage view. It keeps showing the form. Running in debug mode shows that the backend code is getting called.
I'm fairly certain that it has something to do with the fact that the div that the ajax code is using to redisplay is inside the NewMessage view (it can't replace its own container) but I have no idea how to set this up so that it will work.
As requested, here is some rendered HTML
<div id="formbox0">
<form action="/EventList/NewMessage/Q6UJ9A00T49L" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#formbox0" id="form0" method="post"><textarea class="responsebox" cols="20" data-val="true" data-val-required="The Text field is required." id="Text" name="Text" rows="2">
</textarea><input data-val="true" data-val-number="The field ParentID must be a number." data-val-required="The ParentID field is required." id="ParentID" name="ParentID" type="hidden" value="0" /> <br /><input type="submit" value="Save Comment" class="savebutton" />
</form>
</div>
I prefer to avoid the AjaxBeginForm method and like to write handwritten and Clean jQuery code.
I am giving a css class (commentItem) to the container div so that i can use it in my jQuery selector later.
#model Intranet.Entities.ForumRepository.Message
<h3> Enter your comment</h3>
<div id="formbox#Model.ParentID" class="commentItem">
#using(Html.BeginForm())
{
#Html.TextAreaFor(m => m.Text, new { #class = "responsebox" })
#Html.HiddenFor(m => m.ParentID)
<input type="submit" value="Save Comment" class="savebutton" />
}
</div>
<script type="text/javascript">
$(function(){
$(".savebutton").click(function(e){
var item=$(this);
e.preventDefault();
$.post("#Url.Action("NewMessage","EventList")",
item.closest("form").serialize(),function(data){
item.closest("div.commentItem").html(data);
});
});
});
</script>
This code will replace the existing form (or whatever inside the container div) with the content received from your Action method.

Categories