passing model from view to controller in mvc3 c# - c#

#foreach (var item in Model.AllManagementActions)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
I want to pass all these values to my controller. The ID , the name, etc.
Can't i just pass the item itself?
This is my current code, but it doesn't work.
<a class="complete" title="My Action" data-url="#Url.Action("Submit", "Period", new { tpId = Model.Id ,it = item})" style="cursor: pointer;">
It works if I pass item.name, item.id,item.number,etc
Can i pass the model ?

Don't iterate in your views - use editor templates for the type.
Have a '~/shared/EditorTemplates/ManagementAction.ascx' (or .cshtml if using razor) that renders a single ManagementAction.
In the view, instead of iterating use:
#Html.EditorFor(model => model.AllManagementActions)

yes you can pass the entire model, but you should use a submit button instead of of an anchor tag and also put your code inside a
using(Html.BeginForm)
{
#foreach (var item in Model.AllManagementActions)
{
//your desire.
}
<input type="submit" value="Save" />
}
in your controller you will recieve the model on post
[HttpPost]
public ActionResult SaveViewData(YourModel model)
{
//your logic.
}

Related

How do I Pass Selected items from one page to another page in asp.net mvc

In my index page, i have multiple checkboxes that can be selected:
#foreach (var item in Model) {
<tr>
<td class ="text-nowrap">
<input class="chkSelect" type="checkbox" name="Selected" value="#item.Id">
</td>
<td>
#Html.ValueFor(modelItem => item.trandate, "{0:dd/MM/yyyy}")
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id })
</td>
</tr>
}
I need to get the selected items and pass them to another form/page /action where i want to use the ids of the selected item to perform other actions.
How do i pass the selected items to the controller action of the other page ?
so , now i created public ActionResult SendSMS(string[] msisdn)
{
return View();
}
and
#using (Html.BeginForm("SendSMS", "Subscribers", FormMethod.Post))
{
<div class="form-group">
<span class="btn btn-primary"> <i class="fa fa-envelope"></i> Send SMS</span>
</div>
}
So, will Request["Selected"] hold all the selected items? it appears null when debugging.
You could POST it to the controller and do a redirect with those values. The values would then do in a query strings to the other action. Like:
return RedirectToAction("Index", "Home", new { value1 = value1, value2 = value 2});
I was able to get this done by simply using a submit button. and
and in the controller action SendSMS i have :
if (Request["Selected"] != null)
{
model.msisdn = string.Empty;
model.MessageId = string.Empty;
foreach (var selection in Request["Selected"].Split(','))
{
}
}

how to iterate a list variable in html using razor

I am new to asp .net and MVC. I have a service method called Jumbo(). This method returns a list containing first name, last name and contact number. And I call this method from my main project as below. Also I return it to the view page.
var info = add.jumbo();
ViewData["sample"] = info;
return View("FormResults");
When I debugged the code the variable 'info' contains all the data I needed. The problem is how do I iterate the variable in html table using razor. I searched a lot to find a solution but I failed. Please help me with a solution. Thanks in advance.
First you need to pass the model to the view:
return View("FormResults", info);
And in the view, you'll need to state the Type of model, and use # to indicate code rather than html:
#model List<Foo> // Whatever your list is
#foreach (var item in Model)
{
<span>#item.Text</span>
}
Here's a blog about it in detail: http://weblogs.asp.net/scottgu/asp-net-mvc-3-new-model-directive-support-in-razor
Case 1:
Basically you can observe this within your application itself. MVC itself provide you your answer. When ? When you creating View against the action which returning list. Say your action returning list of customer then you can observe following code.
#model IEnumerable<Customer>
<h2>Customers</h2>
<p>
#Html.ActionLink("Create New", "CreateCustomer", "ControllerName")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.ActionLink("Edit |", "UpdateCustomer", new { id = item.Id})
#Html.ActionLink("Details", "Details", new { id = item.Id})
#Html.ActionLink("Delete", "Delete", new { id = item.Id})
</td>
</tr>
}
</table>
Case 2:
your scenario is when you sending the list within ViewData. Then you have to cast ViewData into respective model list and then you can perform same foreach loop.
Action:
var info = add.jumbo();
ViewData["sample"] = info;
return View("FormResults");
View:
#if (ViewData["sample"] != null)
{
List<Info> infoList = (List<Info>)ViewData["sample"];
foreach (var i in infoList)
{
//Perform your html here enclosed with html tags.
}
}
#model Models.Nodes
#foreach (var item in Model)
{
<li>
<span> item.name </span>
</li>
}
In your view write a foreach loop as below
#model List<Object>
#foreach(var item in Model)
{
item.YourProperty;//without html
<label>#item.YourProperty</label> //in html
}

Post a Model with Collection reference to Controller

I have a Model that has a properties as name, email... etc. Also has a Collection.
In the View I edit the properties and I kept the Collection UNchanged.
When I try to submit the form, it sends the changed and unchaged values, BUT the Collection is lost. How to handle this?
HTML.HiddenFor() - doesn't work.
It loses all proprties that are not changed in the form !(In the form I use HTML.EditorFor(Model => Model.Name))
Edit:
View:
<% using (Html.BeginForm("Action", "Controller", FormMethod.Post))
{%>
<%: Html.AntiForgeryToken()%>
<table>
<tr>
<td>Name: </td>
<td>
<%: Html.EditorFor(Model => Model.Name) %></td>
</tr>
<tr>
<td>Phone: </td>
<td>
<%: Html.EditorFor(Model => Model.Phone) %></td>
</tr>
#h#</table>
<%} %>
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveModelDealer(User ModelReceived)
{
try
{
if (ModelState.IsValid)
{
using (Context db = new Context ())
{
System.Diagnostics.Debug.WriteLine(" " + ModelReceived.ListOfPhones.Count);
}
return View();
}
else
{
}
}
catch (Exception)
{
}
}
Only properties inside a form are send back to the server with a post. You should re-populate the collection after the post the same way you did in the HttpGet action.
If you want to persist items in the form, but not show them, you can use a hidden field. Like this:
#Html.HiddenFor(m => m.ID);
Also, check out this question, I gave an example to solve your problem.

MVC4 - how to use EditorFor() with dynamic form data from a database

I have tables in my database called Sections and Fields. Sections contain Fields. Fields can be a textbox or checkbox. I am using this to dynamically create HTML forms for data entry.
I have a view which is bound to a Section:
#model Data.Section
#using (Html.BeginForm("SaveSection", "MyController"))
{
#Html.ValidationSummary(true)
<div class="fields">
#Html.EditorFor(m => m.Fields)
</div>
<input type="submit" value="Save">
}
I then have an editor template for Field in my EditorTemplates folder:
#model Photon.Data.Field
#if (Model != null)
{
<span class="label">#Html.DisplayFor(m => m.Name)</span>
<span class="field">
#Html.EditorFor(m => m.FieldValues)
</span>
}
(I have an editor template for FieldValues but that's not relevant here I don't think.)
The above solution works GREAT for listing textboxes and checkboxes. When a user edits them and then clicks Save, it posts back to my controller method:
[HttpPost]
public ActionResult SaveSection(Section model)
{
// do some magic
}
My Section model that is passed into my method is valid, and bound to the fields from the page.
Here's where I am stumped:
In some of these sections, the fields will need to be laid out in a specific html format (like horizontally or to look like a form from a document) -- basically they can't just be listed. So my thought was to assign a section a template name, then load that template with all the fields, like:
<div class="fields">
#if (Model.IsTemplated)
{
#Html.EditorFor(m => m.Fields, Model.TemplateName)
}
else
{
#Html.EditorFor(m => m.Fields)
}
</div>
What would my view for Model.TemplateName look like if I wanted to lay all of these fields out in a specific html format that is not just a list?
Here's where I'm at:
#model IEnumerable<Data.Field>
<table border="1">
<tr>
<td>
How do I display one field here with EditorFor?
</td>
<td>
How do I display another field here with EditorFor?
</td>
<td>
How do I display and another field here with EditorFor?
</td>
</tr>
</table>
Ideas? Am I going along the right path here?
I'm not sure if I understand your question correctly, but if you manage to arrive at the final View, then laying the fields out in the table row should be similar to this?
...
<tr>
#foreach(var fld in Model)
{
<td>
#Html.EditorFor(m => fld)
</td>
}
</tr>
...
(I don't sit in front of Visual Studio with a razor designer right now, so I apologize for any typos..)

ASP.Net MVC3 Model Binding IEnumerable<T> with Editor Template [duplicate]

This question already has an answer here:
How to pass IEnumerable list to controller in MVC including checkbox state?
(1 answer)
Closed 6 years ago.
All, please clear up my confusion on how the model binding works with IEnumerables and Editor Templates.
I have a view, Approve.cshtml
#model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
#Html.EditorForModel()
</table>
A model, Approve.cs
public class Approve
{
public string Name { get;set;}
public string Role { get; set; }
}
And an editor template
#model MvcWebsite.Models.Approve
#using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
#Html.HiddenFor(m => m.Name)
#Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
This is all fine and good. It renders the following output.
<input name="[0].Name" type="hidden" value="" />
....
However, in my Controller, I can't seem to receive values back for the Model (binding).
[HttpPost]
public ActionResult Approve(Approve approveModel)
{
.... approveModel has all default values
}
Can someone shed light on what I am doing wrong here? I abbreviated the code, I am using the Editor Template with other EditorFor and HiddenFor fields from my model...
Edited: I basically have a table layout, each with the User's Name, a textbox where I can enter their role (User or Admin) and then an Approve button which submits to my controller. Hence the reason I want to only return a single Approve object. I can return the entire IEnumerable to my Controller, but if I do that, how can I tell which of the items was the one I clicked the Approve button (submit) for?
EDIT:
So I have modified the code so that I have a single form surrounding my entire View Approve.cshtml
#model IEnumerable<MvcWebsite.Models.Approve>
#using (Html.BeginForm("Approve", "Program", FormMethod.Post))
{
<table>
<tr>
<th>
Name
</th>
</tr>
#Html.EditorForModel()
</table>
}
And then changed the controller to
[HttpPost]
public ActionResult Approve(IEnumerable<Approve> approvals)
{
// ???????????????????????
}
Now I'm still not clear on how to know which row I clicked Approve for. I know there are other ways to accomplish this task (create a checkbox for approve, and approve anything checked, etc.) However, I need the ability to click a button and only save 1 row back to the database, regardless if the user entered information into the other rows. Is it better practice to wrap my IEnumerable inside of it's own model (i.e. AllApprovals) and then add helper properties to that parent model (SelectedIndex, etc.)? If that is the approach to take, then how do I set the SelectedIndex after clicking an Approve button? Is that still jquery magic or is there a correct MVC way to accomplish this? Jquery magic seems very hackish to me?
EDIT: Based on Brian's response, here is my final. Still doesn't feel quite right, but it works!
View
#model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
#Html.EditorForModel()
</table>
Editor Template
#using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
#Html.HiddenFor(m => m.Name)
#Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
Controller
[HttpPost]
public ActionResult Approve([Bind(Prefix="approval")]Approve approval) {
// WORKS!
}
Since you are only changing one at a time, I think the following is easier than trying to figure out at the controller which values changed, or adding a changed property and setting it via javascript.
Change Approve.cshtml to
#model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th colspan=2>
Name
</th>
</tr>
#foreach(var user in Model){
#using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) {
<tr>
<td>
#Html.EditorFor(m => user)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
}
</table>
Change the Approve Editor Template to
#Html.HiddenFor(m => m.Name)
#Html.EditorFor(m => m.Role)
You're binding to the single Approve class, you should bind to IEnumerable<Approve>
Martin is correct I just want to add some more information. Your rendered HTML with the [0] is special syntax the model binder looks at and assumes you are working with a list if objects. Since your action method has a single Approve class and not a kist, you are experiencing this problem.

Categories

Resources