Passing parms to Controller from View with Html.BeginForm - asp.net-mvc

I have two simple questions that I am hoping someone could answer... It's been asked several times on the web, but I cannot find a post that clearly state what I need below...
question 1:
How do you get the values from the View to pass to the Controller where the values already exist on the View? In other words, I need the #loanID value. This value is a textbox on the form and is not part of the model.
<label for="txtLoanID">Loan ID :</label>
#(Html.Kendo().IntegerTextBox()
.Name("txtLoanID")
.Placeholder("Enter LoanID")
)
#using (Html.BeginForm("GeneratePDF", "Home", new { #loanID = loanID }, FormMethod.Post))
question 2:
How can I pass multiple values using the above line to the Controller, specifically, a dropdownlist text value which is also not part of the model.

The textbox should be in the form so it gets posted back by it.
#using (Html.BeginForm("GeneratePDF", "Home", FormMethod.Post)) {
<label for="txtLoanID">Loan ID :</label>
#Html.Kendo().IntegerTextBox().Name("txtLoanID").Placeholder("Enter LoanID")
}
then your controller should be able to get it through model binding
public ActionResult GeneratePDF(int txtLoadID)
{
}

Related

Second model in same view not posting to controller

With the help of several SO questions, I've figured out how to use two models on the same view, using the tuple form. At the top of my file is this:
#using Project.Models;
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
#model Tuple<Foo, Bar>
}
For the Foo stuff, it uses jQuery like this:
#Html.DisplayFor(tuple => tuple.Item1.ID)
and works fine. However, for my second model, it isn't displaying info, but is a submission form. Currently, this is what I have:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "createFoo", #action = "/api/Foo" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-field">
#Html.TextAreaFor(tuple => tuple.Item2.Text)
#Html.ValidationMessageFor(tuple => tuple.Item2.Text)<br />
</div>
<input type="submit" value="Post Response" />
}
Mind you, this is mostly copy paste from other views since I'm new to MVC and it worked fine with other forms. For my FooController, I have this:
public void Post([FromBody] Foo foo)
{
Foo existingFoo = this.fooRepository.GetFoo(foo.ID);
if (existingFoo != null)
{
// throw error
}
else
{
System.Diagnostics.Debug.WriteLine("MESSAGE POSTING: " + foo.Text);
}
}
When submitting from the view, the received foo isn't null (checked in other tests), but the foo.text is empty. I've tried lots of different inputs and such, but I'm just so unfamiliar with the #Html.* functions and ASP.net-MVC in general that I'm not sure where I could be going wrong.
If you need to see my repository code let me know, but I doubt it'd have an effect on this. Thanks in advance for any help.
There are 2 issues I can see with your code above:
The way the Html helper will output your fields and how that feeds into your api post
Not having your ID in the controller.
1: Outputting a field like this (#Html.TextAreaFor(tuple => tuple.Item2.Text)) will give the field the name "Item2.Text". This is an issue as that is what gets passed on the post. You will get form data with Item2.Text:dfsdsgdfg. This won't match when your API controller tries to bind. So, try outputting the text field with a set name:
#Html.TextArea("Text", #Model.Item2.Text)
2: Your Id field is not in the form... thus it won't be sent. Try using a hidden field:
#Html.Hidden("ID", #Model.Item1.ID)
Also, just a clarification, this (#Html.DisplayFor(tuple => tuple.Item1.ID)) is not jQuery.

MVC 4 Passing model from one controller to view and from view to other controller without users able to edit all fields

Im kinda new in MVC4 and im not able to figure it out.
"CustomViewMOdel" "CustomViewMOdel"
"ControllerX" ----------------> "VIEW" -----------------> "ControllerY"
My problem is that i want to pass my customviewmodel to view (which is working just fine!). In the View im showing some of model's fields to users (which is working fine also). BUT Now i want user, to change ONE field of the models fields and then PASS the WHOLE model to Controller X (with all fields filled, including the field what user was able to change AND other fields what were just shown)
Can anyone give a very simple code example of how to do this?
You can just create a form that posts to another controller:
ControllerX:
public ActionResult DoSomething()
{
return View(new CustomVM());
}
ViewA
#Model CustomViewModel
#using Html.BeginForm("DoSomethingElse", "ControllerY")
{
#Html.EditorFor(vm => vm.SomeProperty)
<input type="submit" value="OK" />
}
ControllerY
public ActionResult DoSomethingElse(CustomViewModel vm)
{
// do something else
}
You can use #Html.HiddenFor(o => o.Property) on the form.
This will not show a property on it.
But the advanced user may change the property through a development console. So you should check all the changes in the ControllerY
Example:
#Html.HiddenFor(o => o.Id)
#Html.HiddenFor(o => o.Name)
#Html.EditorFor(o => o.Description)
<input type="submit" value="OK" />
This will only let the user change a description but still have "id" and "name" on the FormCollection.

Attaching a hidden text field to a form MVC

This very well may end up being a very silly question in a way but basically I have this "form" in a model that gets attached to my View as the form but I haven't been able to actually pass any data do it from the View. It only has two properties: an Id property and a String property. I've been trying to fill the String property with text from a hidden text box on the page with no luck.
Form code:
public class AllocateListForm
{
public int Id { get; set; }
public virtual string HiddenText { get; set; }
}
Relevant View code:
<% using (Html.BeginForm("SaveExit", "User", new { }, FormMethod.Post, new { id = "selectExitPoints" })) { %>
<fieldset>
<input type="hidden" id="HiddenText" />
</fieldset>
<% } %>
There is JQuery behind the scenes that fills HiddenText with text and I can assure you that it is filling. There is also JQuery behind the scenes that performs an Ajax submission and I can promise you that code works as it is used elsewhere in the application without a problem. When I perform the action that submits the form to the server and I go to my controller code that this points to, I have a breakpoint set so I can go into the console and check if the HiddenText field on the form has any data it is null. Can anybody point me in the right direction?
If you assign the input's name to be "HiddenText" the model binder should pick it up. I'm assuming that your controller action accepts an AllocateListForm as a parameter.
<input type="hidden" name="HiddenText" id="HiddenText" />
You can also use Html Helpers like so:
#Html.HiddenFor(model => model.HiddenText, new { id = "HiddenText" })
EDIT: Add an AllocateListForm as a property of your main model and then change the helper to be #Html.HiddenFor(model => model.MyAllocateListForm.HiddenText)
This should do the trick, if you want to do it the Razor-way.
#Html.HiddenFor(model => model.HiddenText);

Post a model property with DisplayFor on submit

My one view page I passed in a model through the controller, so I can write:
#Html.DisplayFor(m => m.FirstName) which displays the First Name of the model. When I try to submit the form on the page using
#using (Html.BeginForm("CreateUser", "Controller", FormMethod.Post, new { UserViewModel = Model }))
and I take a look at my model in
[HttpPost]
public virtual ActionResult CreateUser(UserViewModel model)
{
//model.FirstName is blank
Is there anyway I can make the model.FirstName not blank? by some how passing the model that I originally passed? I could set a bunch of hidden remarks, though if there is a better way that would be very helpful
EDIT: the DisplayFor is just an example to show the model is accessible. I actually have about 15 fields, and I am going through multiple forms trying to populate the model. Is Hidden the only way? and could I just hide the entire model?
#Html.DisplayFor() creates a simple literal with the value by default (if you're not using a display template), on submit only form elements being submitted to the server.
You can use hidden input.
#Html.HiddenFor(m => m.FirstName)
Which will be something like:
<input type="hidden" value="{the first name}" name="FirstName" id="FirstName" />

Losing ViewModel Data after POST

I don't see this problem too often but I've got a .cshtml that uses a layout. In the layout I've got:
#using (Html.BeginForm(null, null, FormMethod.Post, new { #class = "someCssClass", #id = "UserForm" }))
{
...rest of the code
}
My main .cshtml using this layout has the model defined at the top as we always do:
#model CarViewModel
#{
Layout = "~/Views/Shared/_CarLayout.cshtml";
}
When It gets back to my action method, I get nulls for all values of the model:
public ActionResult Cars(CarViewModel model)
{
carBL.RemoveCars(model.CarIds, model.DealerId);
...
}
Not sure what I need to do here and why this is happening. Usually I just get it back successfully via autobind. It seems to me when the model is used via RAzor in the markup- that gets posted back fine with the returned ViewModel but if I'm not using those fields, it doesn't...so I assume that's how that works and if I don't use them in mark-up I need to send them back as hidden values then to force the persistence since I am not using x fields from the ViewModel (Which would have automatically persisted those fields if I had used them in the form)?
If the values are not bound to a form field, they will come back null.
in the form use the below for things like ID fields.
#Html.HiddenFor(x => x...)
A quick test, to see if the form is being posted correctly would be to modify the signature of your action:
public ActionResult Cars(FormCollection form)
{
...
}
If form is not populated then you have an issue with the form post. As a side, note you could accomplish this when reviewing the post data of the form with a tool like FireBug, Chrome Dev tools or Fiddler if you prefer.
If the form is posting correctly, then I you should check to make sure the name's of the input fields on the form align with the names of the CarViewModel you are expecting.
Not sure if this has been resolved yet, but this is how I do it (partial code):
#model MyProject.ViewModels.MyViewModel
#using (Html.BeginForm())
{
<table>
<tr>
<td>First Name:</td>
<td>#Html.TextBoxFor(x => x.FirstName, new { maxlength = "50" })
#Html.ValidationMessageFor(x => x.FirstName)
</td>
</tr>
</table>
<button id="btnSave" type="submit">Save</button>
<button id="btnCancel" type="button">Cancel</button>
}
Then my action method to handle the HTTP post request:
[HttpPost]
public ActionResult Create(MyViewModel viewModel)
{
// Check for null on viewModel
// Do what needs to be done
}
Doing it this way should not let you loose your values filled in on the form/view.

Resources