Ok, so I have this class:
public class BackstoreInventoryUtility
{
public BackstoreInventoryInfo Item { get; set; }
public List<ItemListingUtility> ListItemUtility { get; set; }
public BackstoreInventoryUtility()
{
Item = new BackstoreInventoryInfo();
ListItemUtility = new List<ItemListingUtility>();
}
}
And here's the ListItemUtility class:
public class ItemListingUtility
{
public int Quantity { get; set; }
public string Duration { get; set; }
public List<string> AvailableDurations { get; set; }
public ItemListingUtility()
{
AvailableDurations = new List<string>();
}
}
In a view I am building, I am displaying 1 BackstoreInventoryUtility based on a BackstoreInventoryInfo item my user is currently browsing.
The ListItemUtility is a class allowing the user to proceed to certain action, like display for a set time a set quantity.
The view renders like this:
#model MyApp.Utilities.BackstoreInventoryUtility
#using (Html.BeginForm())
{
<div>
#if (Model.Item.Quantity > 0)
{
<input type="submit" value="Display"/>
}
#Html.HiddenFor(_item => _item.Item.BackstoreInventoryID)
<div class="bigFontSize bold formStyle">
<label class="center">Options will eventually be displayed here.</label>
<div>
<div class="float-left">Quantity Allocated:</div>
<div class="float-right">#Html.DisplayFor(_item => _item.Item.Quantity)
#Html.HiddenFor(_item => _item.Item.Quantity)
</div>
<div class="clear"></div>
</div>
<div class="formStyle" id="itemUtilityZone">
<label>Options</label>
#for (int i = 0; i < Model.ListItemUtility.Count; i++)
{
<div>
<div class="float-left">
Quantity To Display:
</div>
<div class="float-right">
#Html.TextBoxFor(_item => _item.ListItemUtility[i].Quantity, new { #class = "positive-integer numberTextBox" })
</div>
<div class="clear"></div>
</div>
}
</div>
#if (Model.Item.Quantity > 0)
{
<input type="submit" value="Display"/>
}
</div>
}
I'd like my user to dynamically add a new row to the view, and then when the view is submitted, all the rows would be included.
So far I am at the beginning and I am trying this:
[HttpGet]
public ActionResult AddItemUtilityRow()
{
return PartialView(new ItemListingUtility());
}
Where the partial view rendered would be identical to the div used in the table. But I am not sure how could I make this happen, should I use a jQuery call? How might I do this?
EDIT Okay, so I have tried something in jquery which VISUALLY does what I want:
<script type="text/javascript">
$(document).ready(function() {
$("#addUtility").click(function() {
$.get("#Url.Action("AddItemUtilityRow")", {
}, function(data) {
$('#itemUtilityZone').append(data);
});
});
});
</script>
So, as I said, this works but only partially because when the user submits only the default number of items in the list is submitted. How can I make it so that each time the user add a row it adds up to the model and gets later submitted?
Woah! It was more complex than I thought, but thanks to this link : http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ I was able to make the whole thing work!
I first transfered every row created in a partial view like this:
<div class="formStyle" id="itemUtilityZone">
<label>Options</label>
#foreach (var utilityRow in Model.ListItemUtility)
{
Html.RenderPartial("ItemUtilityRow", utilityRow);
}
</div>
Which renders like this:
#using HtmlHelpers.BeginCollectionItem
#model MyApp.Utilities.ItemListingUtility
#using (Html.BeginCollectionItem("listItems"))
{
<div>
<div class="float-left">
Quantity To Display:
</div>
<div class="float-right">
#Html.TextBoxFor(_item => _item.Quantity, new { #class = "positive-integer numberTextBox" })
</div>
<div class="clear"></div>
</div>
}
Note: for the Html.BeginCollectionItem Html Helper, I had to search a bit for Steven Sanderson's Helper which he mentions in the upper link. You can find it here:
https://github.com/danludwig/BeginCollectionItem
Next, my javascript call looks like this:
$(document).ready(function() {
$("#addUtility").click(function () {
$.ajax({
url: '#Url.Action("AddItemUtilityRow")',
cache: false,
success: function(html) {
$('#ItemUtilityZone').append(html);
}
});
});
});
And the controller method that adds a new row:
[HttpGet]
public ActionResult AddEbayUtilityRow()
{
return PartialView("ItemUtilityRow", new ItemListingUtility());
}
And the rows shows just fine now. The catch is, how do I catch it back in my post method? Well, following Steve Sanderson's blog, I understood that the listItems variable was actually the name of the collection which would be sent back to the post method.
So by adding this parameter to the controller post method:
IEnumerable<EBayListingUtility> listItems
The list is indeed sent back to the post method with the count being what it is supposed to be. Hurray!
We approach this in one of two ways:
1.) Client-side approach - you can use jquery/knockout whatever to append items to your table. This is fine for simple additions, but negates the use of c# in the view.
2.) Server-side approach (and usually used) - Basically, post your viewmodel back to an action that manually adds a list item;
[HttpGet]
public ActionResult AddItemUtilityRow()
{
return PartialView(new ItemListingUtility());
}
[HttpPost]
public ActionResult AddItemUtilityRow(BackstoreInventoryUtility viewModel)
{
viewModel.ListItemUtility.Add(new ItemListingUtility());
return PartialView(viewModel);
}
We have a number of ways using jquery of 'posting' to a different action (the one that simply adds an item). I would consider using jquery's ajax call to accomplish this.
But the premise is the same:
send the data from your page to the server
manipulate the data
reuse the view you created
Related
In my app I want to make model that can have dynamic list of attributes:
Provider class
using System;
using System.Collections.Generic;
namespace DynamicForms.Models
{
public class Provider
{
public String Name { get; set; }
public List<Attribute> Attributes { get; set; }
public Provider()
{
Attributes = new List<Attribute>();
}
}
}
My controller has two methods. One to add more attributes to current model and one to save Provider model. Method to add more attributes looks like this:
[HttpPost]
// Add attribute to current provider model
public IActionResult Index(Provider provider)
{
provider.Attributes.Add(new Models.Attribute());
return View(provider);
}
And my view looks like this:
#model Provider
#using (Html.BeginForm())
{
<div>
#Html.TextBoxFor(m => m.Name)
<input type="submit" value="Add attribute" formmethod="post"/>
</div>
<div>
#foreach ( var attribute in Model.Attributes)
{
<div>
#Html.TextBoxFor(a => attribute.Name)
#Html.TextBoxFor(a => attribute.Value)
</div>
}
</div>
<div>
<input type="submit" value="Save form" formaction="Provider/Save" formmethod="post"/>
</div>
}
When I press "Add attribute" button attribute is added and a row of input fields is appearing. However when i press the button one more time nothing happens. No another row is added. Model attributes count is still 1. I've been looking for solutions all over the web but couldn't find anything that fixes my problem. How can I make form fields be added dynamically to model and displayed in vieW?
Try looping over your List with an index instead of foreach, e.g.
#for (var i = 0; i < Model.Attributes.Count; i++)
{
<div>
#Html.TextBoxFor(a => Model.Attributes[i].Name)
#Html.TextBoxFor(a => Model.Attributes[i].Value)
</div>
}
You want the names to be formatted something like this Attributes[0].Name, etc.
You wrote a method for Post, but you wrote a method for get.
Get method
public IActionResult Index()
{
Provider provider = new Provider();
provider.Attributes.Add(new Models.Attribute());
return View(provider);
}
Post metod
[HttpPost]
// Add attribute to current provider model
public IActionResult Index(Provider provider)
{
provider.Attributes.Add(new Models.Attribute());
return View(provider);
}
The problem I will be describing is very similar to ones I already found (e.g. this post with nearly identical name) but I hope that I can make it into something that is not a duplicate.
I have created a new ASP.NET MVC 5 application in Visual Studio. Then, I defined two model classes:
public class SearchCriterionModel
{
public string Keyword { get; set; }
}
public class SearchResultModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Then I created the SearchController as follows:
public class SearchController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DisplaySearchResults()
{
var model = new List<SearchResultModel>
{
new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
};
return PartialView("SearchResults", model);
}
}
as well as views Index.cshtml (strongly typed with SearchCriterionModel as model and template Edit) and SearchResults.cshtml as a partial view with model of type IEnumerable<SearchResultModel> (template List).
This is the Index view:
#model WebApplication1.Models.SearchCriterionModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SearchCriterionModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Keyword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Keyword, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='#Url.Action("DisplaySearchResults", "SearchController")'" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">
</div>
As you can see, I added a div with id="searchResults" below the standard template and edited the button. What I want is to display the partial view SearchResults.cshtml in the div on the bottom, but only after the button is clicked. I have succeeded in showing a partial view there by using #Html.Partial("SearchResults", ViewBag.MyData), but it is rendered when the parent view is loaded for the first time and I set ViewBag.MyData in the Index() method already, which is not what I want.
Summary: On clicking the button, I will obtain some List of SearchResultModel instances (via database access) and then the partial view should be rendered, using this newly obtained data as model. How can I accomplish this? I already seem fail at the first step, that is reacting to the button click with the above code. Right now, I navigate to the URL ~/Search/DisplaySearchResults, but of course there's nothing there and no code-behind method is called.
In traditional ASP.NET I'd just have added a server-side OnClick handler, set the DataSource for a grid and show the grid. But in MVC I already fail with this simple task...
Update: Changing the button to #Html.ActionLink I can finally enter the controller method. But naturally since it returns the partial view, it's displayed as the whole page content. So the question is: How do I tell the partial view to be rendered inside a specific div on the client side?
Change the button to
<button id="search">Search</button>
and add the following script
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
var keyWord = $('#Keyword').val();
$('#searchResults').load(url, { searchText: keyWord });
})
and modify the controller method to accept the search text
public ActionResult DisplaySearchResults(string searchText)
{
var model = // build list based on parameter searchText
return PartialView("SearchResults", model);
}
The jQuery .load method calls your controller method, passing the value of the search text and updates the contents of the <div> with the partial view.
Side note: The use of a <form> tag and #Html.ValidationSummary() and #Html.ValidationMessageFor() are probably not necessary here. Your never returning the Index view so ValidationSummary makes no sense and I assume you want a null search text to return all results, and in any case you do not have any validation attributes for property Keyword so there is nothing to validate.
Edit
Based on OP's comments that SearchCriterionModel will contain multiple properties with validation attributes, then the approach would be to include a submit button and handle the forms .submit() event
<input type="submit" value="Search" />
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
if (!$(this).valid()) {
return false; // prevent the ajax call if validation errors
}
var form = $(this).serialize();
$('#searchResults').load(url, form);
return false; // prevent the default submit action
})
and the controller method would be
public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
var model = // build list based on the properties of criteria
return PartialView("SearchResults", model);
}
So here is the controller code.
public IActionResult AddURLTest()
{
return ViewComponent("AddURL");
}
You can load it using JQuery load method.
$(document).ready (function(){
$("#LoadSignIn").click(function(){
$('#UserControl').load("/Home/AddURLTest");
});
});
source code link
I'm moving from WPF development to Asp MVC and have started doing an Asp MVC app. So far I've set up my:
model
controller
and
view(with the relevant fields.)
The next step involves sending the data entered in my form to the controller on the Submit button click.
I know in WPF I can bind the control properties to a property in the viewmodel, also there would be a click event on the button which I don't see in MVC.
This is my pseudo understanding of how to do that in MVC but correct me if I' wrong (Model is of type Case):
1.Set button click event to send form data to controller.
2.Pass data into controller constructor and assign to typed Case object.
Question:
How can you pass view values on button submit to a typed object in a controller?
Code:
View -
<form action="" method="post">
<div class="form-horizontal">
<div class="col-lg-6">
<!-- SELECT STATUS STATIC-->
<div class="form-group">
<label class="col-md-3 control-label" for="Current Status">Status</label>
<div class="col-md-8">
<select id="Status" name="Status" onchange="" class=" form-control">
<option value="Down">Down</option>
<option value="Up">Up</option>
</select>
</div>
</div>
<!-- SELECT APP STATIC-->
<div class="form-group">
<label class="col-md-3 control-label" for="App">App</label>
<div class="col-md-8" >
<select id="App" name="App" onchange="" class=" form-control">
<option value="SAP">SAP</option>
<option value="JAP">JAP</option>
</select>
</div>
</div>
<asp:Button id="b1" Text="Submit" runat="server" />
</div>
</div>
</form> <!--
Controller -
public class CaseController : Controller
{
public ActionResult Index()
{
return View();
}
}
Model -
Public class Case
{
public string Status { get; set; }
public string App { get; set; }
}
I hope that I understand your scenario well? You have a form with two drop down lists and a submit button? When you click the submit button you want to extract the selected values? This is how I understand it and this is how I will try to explain my answer with examples.
I would suggest that you bind your view/page to a view model. A view model is a kind of model that will represent your data in the view, whether it be textboxes, drop down lists, textareas, radio buttons, checkboxes, etc. It can also display static text on your view. I wrote a detailed answer as to what a view model is, if you have the time please go and read it:
What is ViewModel in MVC?
Go and create your view model. It will contain two lists that will represent your two drop down lists. Each list has an id associated with it that will contain the value of the selected drop down list item:
public class CaseViewModel
{
public int StatusId { get; set; }
public List<Status> Statuses { get; set; }
public int AppId { get; set; }
public List<App> Apps { get; set; }
}
Your domain models, namely Status and App, for the above mentioned lists:
public class Status
{
public int Id { get; set; }
public string Name { get; set; }
}
public class App
{
public int Id { get; set; }
public string Name { get; set; }
}
Now that you have this setup your next step is to populate these lists in your controller's action method. Ideally you would populate it with values from a database, but in your case I guess it is ok to hard code these values:
public ActionResult Index()
{
CaseViewModel model = new CaseViewModel();
model.Statuses = new List<Status>();
model.Statuses.Add(new Status { Id = 1, Name = "Down" });
model.Statuses.Add(new Status { Id = 2, Name = "Up" });
model.Apps = new List<App>();
model.Apps.Add(new App { Id = 1, Name = "SAP" });
model.Apps.Add(new App { Id = 2, Name = "JAP" });
return View(model);
}
As soon as you have populated your two lists, you pass the view model directly to the view. The view will receive a strongly type model and will do with it what it needs to do with it. In your case, a form will be created with two drop down lists and a submit button. I have left out all your CSS for clarity (just go and add it):
#model WebApplication_Test.Models.CaseViewModel
#using (Html.BeginForm())
{
<div>
#Html.DropDownListFor(
m => m.StatusId,
new SelectList(Model.Statuses, "Id", "Name", Model.StatusId),
"-- Select --"
)
#Html.ValidationMessageFor(m => m.StatusId)
</div>
<div>
#Html.DropDownListFor(
m => m.AppId,
new SelectList(Model.Apps, "Id", "Name", Model.AppId),
"-- Select --"
)
#Html.ValidationMessageFor(m => m.AppId)
</div>
<div>
<button type="submit">Submit</button>
</div>
}
So now you have two drop down lists populated with data. Select a value in each and press the submit button. Your view is bound to a view model and will retain values on form submission. Values in lists are not kept on form submission and will need to be populated again:
[HttpPost]
public ActionResult Index(CaseViewModel model)
{
// Check form validation
if (!ModelState.IsValid)
{
// If validation fails, rebind the lists and send the current view model back
model.Statuses = new List<Status>();
model.Statuses.Add(new Status { Id = 1, Name = "Down" });
model.Statuses.Add(new Status { Id = 2, Name = "Up" });
model.Apps = new List<App>();
model.Apps.Add(new App { Id = 1, Name = "SAP" });
model.Apps.Add(new App { Id = 2, Name = "JAP" });
return View(model);
}
// Form validation succeeds, do whatever you need to do here
return RedirectToAction("Index");
}
I hope this helps.
In the view just add a button in the form like
<button id="b1" Text="Submit"/>
In the controller add an action method to handle the post.
public class CaseController : Controller
{
[HttpPost]
public ActionResult Index(Case case)
{
//Do Something
return View();
}
public ActionResult Index()
{
return View();
}
}
You may also want to look into using Razor and strongly typed views. Makes things much simpler.
another approach is to use mvc ajax call, by doing these you also can pass parameter to controller from simple parameter to a selected row in gridview.
On the view in the button control add onclick property that point to a javascript function and passing parameter. In these sample will get selected row on the gridview
<input id="GenerateData" type="button" value="GenerateData" onclick="generateData(App.grdNameOfGridview.getRowsValues({selectedOnly:true}) [0]);" />
On the view create a javascript function that use ajax to call the controller, note the paramater that can be passing from click button event to the javascript function that will use ajax to call the controller. In this sample i use extjs framework, if you want you can also use jquery as well
generateData= function (recordData) {
var jsonStringContractUnit = JSON.stringify(recordData);
Ext.Ajax.request({
url: '../ControllerName/GenerateData',
method: 'POST',
params: {
SelectedContractUnit: jsonStringContractUnit
},
On the controller the parameter will be pass from view and will be store on SelectedData
public ActionResult GenerateData(string SelectedData)
{
}
I am new to asp.net MVC. I have a dynamic table in my project. Adding dynamic rows in table is achieved with the help of following link
Adding and deleting rows in dynamic table in Asp.net mvc razor view
I need to edit and update the dynamic table.
I have tried following code
My sample model
public class Gift
{
public string Name { get; set; }
public double Price { get; set; }
}
public class GiftViewModel
{
public string Age { get; set; }
public DateTime TheDate { get; set; }
public IEnumerable<Gift> Gifts { get; set; }
}
My sample Controller
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(GiftViewModel model)
{
// do work here
return RedirectToAction("Index");
}
public ViewResult AddNew()
{
return View("_TimeSheetView");
}
}
My sample Partial View
#model HelloWorldMvcApp.Gift
#using (Html.BeginCollectionItem("giftList"))
{
<div>
<span class="drop_medium">
#Html.TextBoxFor(m => m.Name)
</span>
<span class = "drop_medium">
#Html.TextBoxFor(m => m.Price)
</span>
</div>
}
My sample main view
#model HelloWorldMvcApp.GiftViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Age)
#foreach (var data in Model.Gifts)
{
{ Html.RenderPartial("_TimeSheetView", data); }
}
#Html.ActionLink("Add another", "AddNew", null, new { id="addItem" })
<input type="submit" value="Save"/>
}
<script type="text/javascript">
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#dynamic").append(html); }
});
return false;
});
</script>
When I click 'Add Another' button a row is added to the table. After editing the values in the table When I click submit button I receive nothing in the controller. The IEnumerable Gifts variable is null. How to take the table values to the controller. Please help me to fix this is issue. Thanks in advance
Your model's collection property is named Gifts so the partial needs to be
#model HelloWorldMvcApp.Gift
#using (Html.BeginCollectionItem("Gifts")) // not "giftlist"
{
...
}
This will generate inputs with the correct name attributes for binding to a collection (where ## is a Guid)
<input name="Gifts[##].Name" ... />
<input name="Gifts[##].Price" ... />
<input type="hidden" name="Gifts.Index" value="##" />
The problem you're facing is the name of the rendered input isnt matching your model structure. There are a couple of ways out of this:
Make an editor template for the model type
your partial view:
#model IEnumerable<HelloWorldMvcApp.Gift>
#Html.EditorForModel("","Gifts")
and an EditorTemplate for the Gift model:
#model HelloWorldMvcApp.Gift
<div>
<span class="drop_medium">
#Html.TextBoxFor(m => m.Name)
</span>
<span class = "drop_medium">
#Html.TextBoxFor(m => m.Price)
</span>
</div>
Manually create the inputs with the properly parsed name - "Gifts[x].Property"
Obviously the first option is far cleaner and imho preferred.
Hope this works, and helps :)
I have MVC application with a model like this :
public class ListOfMyModel
{
public List<MyModel> MyModels { get; set; }
public Guid MyID { get; set; }
}
public class MyModel
{
// Some code like :
public string MyString { get; set; }
}
And my post method in my controller is like this :
[HttpPost]
public ActionResult EditMe(ListOfModel myList)
{
try
{
if (ModelState.IsValid)
{
List<MyModel> myModels = myList.MyModels;
foreach (MyModel model in myModels)
// Some code
return RedirectToAction("Index");
}
catch
{
// Some code
return View(myList)
}
return View(myList);
}
And my view : ( I use Kendo UI ) ( P.S : Some code has been stripped away and replaced by comment code )
#model MyApplication.Web.Models.ListOfMyModel
#{
ViewBag.Title = MyTitle;
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<div class="span1"></div>
<div class="span8">
<div id="list-wrapper">
<div class="k-content">
<form id="form" class="form-horizontal well span8 offset2" method="post" action="#Url.Action("EditMe")">
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-1.9.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.514/kendo.web.min.js")"></script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.514/kendo.aspnetmvc.min.js")"></script>
<div class="offset2 span2">
<fieldset>
<legend> My title </legend>
<p>Some code :</p>
#Html.HiddenFor(m => m.MyID)
#for (int i = 0; i < Model.MyModels.Count; i++)
{
// Some code
<div class="control-group">
<label class="control-label">MyText : </label>
<div class="controls">
#(Html.Kendo().DropDownListFor(c => Model.MyModels[i].MyString)
.DataTextField("Text")
.DataValueField("Value")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetSomeThings", "MyController"))
)
.Value(Model.MyModels[i].MyString)
)
</div>
</div>
}
<div class="form-actions">
<button type="submit" class="btn btn-primary">Validate</button>
</div>
</fieldset>
</div>
</form>
</div>
</div>
</div>
But the problem is that when I push the submit button in my view, the method of my controller is called with all the data expected ( saw in Chrome ) but in this method, all of the model is null : The ID and the list... I don't known where the problem is ?
Thank you all for reading and trying to understand this, if you want more informations please tell me.
The MyId should be correctly received with your existing code.
The model binder can only match the value of inputs whose name have a matching property in the form. I.e. if you have an input like this <input name='bikes' ...> then your model should have a property Bikes so that the model binder can transfer the value from the input to the property. In your case you're creating input with dynamic names that doesn't have a matching property name. (NOTE: thei referes to the model you're using as the action parameter).
The farthest you can go is giving a series of input elements the same name, i.e. several elements like <input name='categories' ...> and receive it in an array parameter like string[] categories or a model which has a property like string[] Categories {get;set;}
In short, you have to redesign your model and view. If you used a List<string> instead of a List<MyModel>, and the view had a fixed name for the dropdow lists, like DropDownListFor(c => Model.MyModels, then the model binder would fill the MyModels property with the list of selected strings in each drop down list.
Hint: you can use a model for the View and receive a different model (or series of parameters) in the Action. In this way you can send more information to render the View, and receive a post with the essential data to process the user input.
See my answer to this question for alternatives. It explains something similar to this question.