MVC : Model does not submit for multiple forms - asp.net-mvc-2

This is related to ASP.Net MVC 2
I have a model (MoviesForAll) bound to my view and this model has a collection of class ICollection. I want my user to buy single ticket at a time by clicking submit button 'Buy this ticket' so I have placed a button besides each row representing the ticket details. This lead to following sequence
<%#Page Title="title" Language="C#" MasterPageFile="~/Views/Shared/MyMaster.Master"
Inherits="System.Web.Mvc.ViewPage<OnlineBooking.Movies.MoviesForAll>">
<Table>
<% for(i=0; i<Model.Tickets.count; i++)
{ %>
<tr>
<% using (Html.BeginForm(myaction(), FormMethod.Post, new {id="myform"}))
{ %>
<td>
<%= Model.tickets[i].ticketID %>
<%= Html.HiddenFor(m=>m.tickets[i].ticketID) %>
</td>
<td>
<%= Model.tickets[i].seatNo %>
<%= Html.HiddenFor(m=>m.tickets[i].seatNo) %>
</td>
...
...
<td>
<input type="submit" value="buy this ticket" runat="server">
</td>
<% } %>
</tr>
<% } %>
</table>
This creates a form for each row of tickets having single submit button in that form.
The problem is, when I submit first row (having index 0) by clicking the button, it gets submitted properly and I can see the values in controller method. But no other row gets through to controller even if I have used hidden fields to bind it.
Am I missing anything here specific to index or something?
Thanks in advance..

I would suggest having one form for all the rows, then on each row use the button element instead of an input as follows:
<button type="submit" value="<%= Model.tickets[i].ticketID %>" name="buyticket">Buy this ticket</button>
You should have a parameter on your controller action called buyticket and that should have the ticket id of the button which was clicked

How about the following:
<table>
<% for(i = 0; i < Model.Tickets.Count; i++) { %>
<tr>
<% using (Html.BeginForm("myaction", FormMethod.Post, new { id = "myform" })) { %>
<td>
<%= Model.tickets[i].ticketID %>
</td>
<td>
<%= Model.tickets[i].seatNo %>
</td>
...
...
<td>
<%= Html.Hidden("TicketId", Model.tickets[i].ticketID) %>
<%= Html.Hidden("SeatNumber", Model.tickets[i].seatNo) %>
<input type="submit" value="buy this ticket" />
</td>
<% } %>
</tr>
<% } %>
</table>
and then:
public class TicketToPurchaseViewModel
{
public int TicketId { get; set; }
public int SeatNumber { get; set; }
}
and the action:
[HttpPost]
public ActionResult myaction(TicketToPurchaseViewModel ticket)
{
...
}
Remark: notice that I have removed the runat="server" attribute from the submit button as well because this is something that you definitely don't want to see in an ASP.NET MVC application.

Related

List all data from database using asp.net mvc 2.0

I'm new to asp.net mvc 2.0.I have a question about listing data from database using asp.net mvc.
Controller
public ActionResult ListEmployee() {
UserModels emp = new UserModels();
emp.EmployeeList = (List<tblEmployee_Employee>)Session["list"];
return View(emp);
}
Model
public class GetEmployee
{
public string name { get; set; }
public string sex { get; set; }
public string email { get; set; }
}
And I have the view page employee.aspx page but I do not know how to write code in this view page.
please help me to solve this problem.
Thanks,
In ASP.NET MVC views need to be strongly typed to the model you are passing to them. So in your case you are passing a UserModels instance to your view. Assuming you already have a master page and you want to display in a table the list of employees you might have something along the lines of:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<AppName.Models.UserModels>"
%>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<table>
<thead>
<tr>
<th>Name</th>
<th>Sex</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<% foreach (var employee in Model.EmployeeList) { %>
<tr>
<td><%= Html.Encode(employee.name) %></td>
<td><%= Html.Encode(employee.sex) %></td>
<td><%= Html.Encode(employee.email) %></td>
</tr>
<% } %>
</tbody>
</table>
</asp:Content>
or even better, define a reusable display template that will automaticall be rendered for each item of the EmployeeList collection property (~/Views/Shared/DisplayTemplates/GetEmployee.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<dynamic>"
%>
<tr>
<td><%= Html.DisplayFor(x => x.name) %></td>
<td><%= Html.DisplayFor(x => x.sex) %></td>
<td><%= Html.DisplayFor(x => x.email) %></td>
</tr>
and then in your main view simply reference this template:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<AppName.Models.UserModels>"
%>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<table>
<thead>
<tr>
<th>Name</th>
<th>Sex</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<%= Html.EditorFor(x => x.EmployeeList)
</tbody>
</table>
</asp:Content>
Now you no longer need any foreach loops (as ASP.NET MVC will automatically render the display template if the property is a collection property following standard naming conventions) and also you have a reusable display template for your model.

MVC Html.CheckBox list and Jquery Post

my code is
<% using (Html.BeginForm())
{%>
<table>
<tr>
<th>
LabelID_FK
</th>
<th>
LabelName
</th>
<th>
LabelIsDocument
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%: item.LabelID_FK %>
</td>
<td>
<%: item.LabelName %>
</td>
<td>
<%-- <input type="checkbox" value="df" id="chk" onclick="check()" />--%>
<%=Html.CheckBox("chk_"+ item.LabelID_FK)%>
</td>
</tr>
<% } %>
</table>
<p>
<input type="button" value="submit" id="btn" />
</p>
which show checkbox list for document label which user can select it .
i want pass data list which user select checkbox it use jquery post
what i do?
i use this code when user click on button and work very good
[HttpPost]
public ActionResult DocumentLabel(FormCollection model)
{
for (int i = 0; i < model.Count; i++)
{
AriaCRMEntities aria = new AriaCRMEntities();
DocumentLabel label = new DocumentLabel();
string lbl = model[i].ToString();
string[] check = lbl.Split(',');
bool chk = Convert.ToBoolean(check[0]);
string name = model.Keys[i].ToString();
string[] n = name.Split('_');
string lblid = n[1];
if (chk)
{
label.LabelID_FK = Int32.Parse(lblid);
Guid id = Guid.NewGuid();
label.DocumentID_FK = id;
aria.DocumentLabels.AddObject(label);
aria.SaveChanges();
}
}
return Content("0ok");
}
but i want jquery post i need array check box whit select it to pass it to controller?

Populating and passing complex object from MVC2 view to controller action

I have following code in my MVC2 view:
<tr class="edit" style="display:none">
<td>
<%= Html.DropDownList("drpFields", new SelectList(Model.Fields, "FieldID", "NiceName", whiteout.FieldID)) %>
</td>
<td>
<%= Html.DropDownList("drpStartTimeh", new SelectList(Model.Hours, whiteout.StartHour.Hour.ToString("0,0")))%>
<%= Html.DropDownList("drpStartTimem", new SelectList(Model.Minutes, whiteout.StartHour.Minute.ToString("0,0")))%>
<%= Html.DropDownList("drpStartTimet", new SelectList(Model.AMPM, whiteout.StartHour.Hour > 12 ? "PM" : "AM"))%>
-
<%= Html.DropDownList("drpEndTime", new SelectList(Model.Hours, whiteout.EndHour.Hour > 12 ? (whiteout.EndHour.Hour - 12).ToString("0,0") : whiteout.EndHour.Hour.ToString("0,0")))%>
<%= Html.DropDownList("drpEndTimem", new SelectList(Model.Minutes, whiteout.EndHour.Minute.ToString("0,0")))%>
<%= Html.DropDownList("drpEndTimet", new SelectList(Model.AMPM, whiteout.EndHour.Hour > 12 ? "PM" : "AM"))%>
</td>
<td>
<%= Html.DropDownList("drprepeat", new SelectList(Model.RepeatList,whiteout.Repeats))%>
</td>
<td>
Active
</td>
<td>
<a class="icon-button-cancel" href='<%: Url.Action("EditWhiteOut", "Settings", new {Id = whiteout.WhiteoutID}) %>'>
<img src='<%: Url.Content("~/static/Images/expanded.png") %>' alt="Delete this device" />
</a>
<a class="icon-button-success" href="#">
<img src="/static/images/gear.png" alt="Edit this device" /></a>
</td>
<td>
</td>
</tr>
I want to create an object of type Whiteout class and populate it with values selected by user from dropdowns and send to settingcontroller's EditWhiteout action method instead of passing only new {Id = whiteout.WhiteoutID}. How can I do this ?
Please suggest solution.
Thanks.
MVC provides some automatic mapping on form values from the view back into the controller action. Usually you would use a strongly type view i.e. at the top of the page you will have something
like
Control Language="C#" Inherits="System.Web.Mvc.ViewPage<namespace.Whiteout>
The names of the dropdown lists need to match those of the properties in the Whiteout class and the controller action will expect a return value of the model type i.e.
[HttpPost]
public ActionResult EditWhiteout(WhiteOut tseItem)
{ //method body here
The rest should just happen as if by magic. If you are getting confused by the dropdowns it is sometimes easier to replace them with simple inputs until you get the send/receive part working - then change to dropdown.

Collections.Generic.Dictionary<TKey,Tvalue> model binding from Viewmodel to controller

i have this problem :
when i try to post submit from a View to a httppost actionResult i get always a null value.
this is my code :
public class WhiteListViewModel
{
public string Badge { get; set; }
public IEnumerable<string> Selezioni { get; set; }
public IEnumerable<bool> Abilitazioni { get; set; }
}
public ActionResult WhiteList()
{
return View( "Whitelist", MasterPage, new WhitelistViewModel());
}
[HttpPost]
public ActionResult WhiteListp(IEnumerable<WhiteListViewModel> Whitelist )
{
bool[] abilitato = new bool[Whitelist.Single().Abilitazioni.Count()];
string[] selezione = new string[Whitelist.Single().Selezioni.Count()];
...
}
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/SiteR.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<_21112010.ViewModel.WhiteListViewModel>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
WhiteList
</asp:Content
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>WhiteList</h2>
<table style="width:100%;">
<thead>
</thead>
<tbody >
<%using ( Html.BeginForm( ) )
{%>
<% foreach ( var item in Model ){%>
<tr style="width:100%;">
<td >
<%: item.Badge%>
</td>
<%foreach ( var abit in item.Abilitazioni ){%>
<td >
<%: Html.CheckBoxFor(c=>abit/*, new { onchange = "this.form.submit();" } */ )%>
<%: Html.ValidationMessageFor(c => abit) %>
</td>
<% } %>
<%} %>
<td style=" width:1px;" >
<%: Html.HiddenFor(model=>item.Badge) %>
<% foreach (var sel in item.Selezioni) {%>
<%: Html.HiddenFor(c=>sel) %>
<%} %>
</td>
</tr> <%}%>
</tbody>
<tfoot>
</tfoot >
</table>
<input type="submit" value="Salva ed Esci" style = "background-color:Gray; color:#F6855E; font-weight:bold; border:1px solid black; height:20px;" />
<%:Html.ActionLink( "Aggiungi Badge", "AggiungiBadge")%>
<% } %>
</div>
</asp:Content>
where am I doing wrong?
The binding process will attempt to map the IEnumerable to the parameter Whitelist of the HttpPost action. However, I'm fairly sure that this is failing because the binding process has no information to tie the submitted fields to the expected parameter "Whitelist".
You have a few options:
Try using TryUpdateModel() in your action;
Creating a custom ModelBinder. This will allow you to interogate the submitted Model and build your IEnumerable prior to it being passed to the action parameter;
You could interogate the submitted fields using the FormCollection object from within the action. This is a little messy and not ideal;
Simplify your view.
Personally, I would look at the ModelBinder. If anything, this would give you a better insight into why the Model may not be binding to the action parameter.

Foreach(Var item in model) problem

<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "EditUser", "Profile", new { id = item.UserID },null)%>
</td>
<td>
<%: Html.ActionLink("NewUser", "Create", "Profile", new { id = item.Customer },null)%>
</td>
<td>
<%: item.UserName %>
</td>
I am getting the NewUser Tab with every Edit Tab n also Username tab..I just need it once newhere in the Page, How Can i do that..n this is been done in a
I'm not sure what you're asking but if you only want one edit link for the passed in model then you should use the Model object.
Update based on new information in question
You need to pull the new user action link out of the foreach and instead of using item you use Model instead. If your Model does not contain a Customer object you should modify your ViewModel to include it or pass it in using the ViewData.Customer = SomeCustomerValue and then instead of using the model you would use View.Customer in your aspx page like so
Use this method if you're passing in the Customer via the ViewData
<%: Html.ActionLink("NewUser", "Create", "Profile", new { id = View.Customer },null)%>
(in your controller you would do this)
public ActionResult SomeAction() {
ViewData.Customer = CurrentCustomer;
return View(ListOfUsers);
}
Use this method if your Model includes the Customer property
<%: Html.ActionLink("NewUser", "Create", "Profile", new { id = Model.Customer },null)%>
<% foreach (var item in Model.Users) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "EditUser", "Profile", new { id = item.UserID },null)%>
</td>
<td>
<%: item.UserName %>
</td>
</tr>
<% } %>