Passing complex objects in asp.net mvc - asp.net

I am trying to pass complex object from my view to my controller.
I give the ability to the client to create infinity listBox.
How can I transfer this to the controller?
Here is description:
For every CompanyFeedbackTopic, the client can insert infinite CompanyFeedBackQuestion(Text with int).
I have this objects:
public class CompanyFeedbackTopic
{
/***fields***/
private readonly int m_topicId;
private int m_companyFeedbackId;
private int m_formatFeedbackId;
private int m_percent;
private List<CompanyFeedbackQuestion> m_companyFeedbackQuestionList;
/***constractors***/
public CompanyFeedbackTopic(int topicId, int companyFeedbackId, int formatFeedbackId, int percent,
List<CompanyFeedbackQuestion> companyFeedbackQuestionList)
{
m_topicId = topicId;
m_companyFeedbackId = companyFeedbackId;
m_formatFeedbackId = formatFeedbackId;
m_percent = percent;
m_companyFeedbackQuestionList = companyFeedbackQuestionList;
}
/***get/set***/
public int TopicId
{ get { return m_topicId; } }
public int CompanyFeedbackId
{ get { return m_companyFeedbackId; } set { m_companyFeedbackId = value; }}
public int FormatFeedbackId
{ get { return m_formatFeedbackId; } set { m_formatFeedbackId = value; }}
public int Percent
{ get { return m_percent; } set { m_percent = value; }}
public List<CompanyFeedbackQuestion> CompanyFeedbackQuestionList
{ get { return m_companyFeedbackQuestionList; } set { m_companyFeedbackQuestionList = value; }
}
/***functions***/
}
public class CompanyFeedbackQuestion
{
/***fields***/
private readonly int m_questionId;
private int m_topicId;
private string m_question;
private int m_fieldGradeOptions;
/***constractors***/
public CompanyFeedbackQuestion(int questionId, int topicId, string question, int fieldGradeOptions)
{
m_questionId = questionId;
m_topicId = topicId;
m_question = question;
m_fieldGradeOptions = fieldGradeOptions;
}
/***get/set***/
public int QuestionId
{ get { return m_questionId; } }
public int TopicId
{ get { return m_topicId; } set { m_topicId = value; }}
public string Question
{ get { return m_question; } set { m_question = value; } }
public int FieldGradeOptions
{ get { return m_fieldGradeOptions; } set { m_fieldGradeOptions = value; }}
}
And this is the view:
#using (Html.BeginForm("SubmitNewForm", "ManageFeedback", FormMethod.Post))
{
#Html.Label("Choose feedback type: ")
#Html.DropDownListFor(model => model.SelectedFeedbaclType, Model.FeedbackTypesDic.Select(i => new SelectListItem() { Text = i.Value, Value = i.Key.ToString() }), "---")
<div id="formTable">
#foreach (var item in Model.FormatFeedbackDic)
{
<h4>#item.Value</h4>
<table id="#item.Key">
<tr>
<td class="tableHeader">#</td>
<td class="tableHeader">question</td>
<td class="tableHeader">Grade Options</td>
</tr>
<tr>
<td>1</td>
<td>#Html.TextBox("SS", "", new { style = "width:500px" })</td>
<td>#Html.DropDownList("fieldGradeOptions", Model.GetDropDownList()) </td>
</tr>
</table>
<br />
<button onclick="AddNewRow(#item.Key);">+</button>
<hr />
}
</div>
<br />
<button onclick="SubmitForm();">Create new feedback</button>
}
How can I transfer it to the view?

You have to do two things
Replace all the foreach loops with simple for loops. Example -
for(int i = o; i< Model.FormatFeedbackDic.Count; i++){}
2.Replace this line //button onclick="SubmitForm();">Create new feedback// with
/input type = "sumbit" />
Now it will pass the complex model back to controller

Related

List of Items always null MVC 5

I am stuck in this problem and i cannot solve it.
This is my ViewModel
public class AddOrderReceive
{
public string item_name { get; set; }
public DateTime? date_received { get; set; }
public decimal? quantity_received { get; set; }
public bool IsSelected { get; set; }
public decimal? item_rate { get; set; }
}
This is my View
#model List<newtest.Models.AddOrderReceive>
#if(Model != null && Model.Count > 0)
{
for(var i = 0; i < Model.Count; i++)
{
<tr>
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
else
{
#Html.HiddenFor(r => Model[i].item_id)
<td>#Html.CheckBoxFor(r => Model[i].IsSelected)</td>
<td>#Html.EditorFor(r => Model[i].item_rate)</td>
}
</tr>
}
}
And finally, This is my Controller:
[HttpGet]
public ActionResult AddRAR(int? my_id)
{
try
{
var get_items = (from or in db.orders
where or.id == my_id
select new AddOrderReceive()
{
item_name = or.item_name,
quantity_received = or.quantity_receive,
date_received = or.date_receive,
order_receive_id = or.order_receive_id
}).ToList();
foreach(var t in get_items)
{
var get_remain = (from ra in db.order_detail
where ra.contract_id == t.ca_id && ra.order_receive_id == t.order_receive_id
select new
{
consump_quantity = ra.consump_quantity
});
t.quantity_remaining = t.quantity_received - get_remain.Sum(r => r.consump_quantity) ?? t.quantity_received;
}
return View(get_items);
}
catch(Exception ex)
{
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddReceivng(List<AddOrderReceive> rc_form)
{
//Some Logic
}
The problem is that whenever I post the form, it is always null. But when I remove this block:
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
It starts working. I don't know what's the problem. I've searched everywhere but still can't figure out the problem here.
Your #if(Model[i].quantity_remaining == 0) block of code, if its executed in the first iteration, means that your collection indexers would not be zero based. The DefaultModelBinder requires that collection indexers start at zero and be consecutive.
You can override this behavior by including a hidden input for the indexer. Note also that an <input> is not a valid child of a <tr>, and should be inside a <td> element.
for(var i = 0; i < Model.Count; i++)
{
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
else
{
<td>
<input type="hidden" name="Index" value="#i" /> // Add this
#Html.HiddenFor(r => r[i].item_id)
#Html.CheckBoxFor(r => r[i].IsSelected)
</td>
<td>#Html.EditorFor(r => r[i].item_rate)</td>
}
}

How do i correctly loop through the my list to display the information using Razor?

I have been struggling to loop through my private static List in my HomeController to display in such a way it shows a list of both students and personnel. Below is an example of what my loop should look like.
[Student] Name:John Surname:Greenberg Email: 123#123 Cellphone:123456789 Age: 20
[Personnel] Name:Rose Surname:Marry Email: email#email Cellphone:123456789 WorkerType: Permanent Degree: BED Education
[Student] Name:Chaz Surname:Brown Email: chazz#gmail.com Cellphone:123456789 Age: 30
Please help me loop properly and Below is my ContestantView i tried coding
#model List<Assignment9_u14333393.Models.ContestantViewModel>
<div style="width:100%;height:auto; background-color:brown; padding-top:10px; padding-bottom:10px;">
<h2 style="text-align:center; color:white;">List of Contestants</h2>
</div>
.
<div class="members" >
<table>
#foreach (var temp in Model)
{
<div class="member">
[#temp.MemberType] Name:#temp.Name Surname:#temp.Surname Email: #temp.Email Cellphone:#temp.CellPhone
</div>
}
</table>
</div>
For additional information I also have three models (StudentViewModel, PersonnelViewModel and ContestantViewModel).
ContestantViewModel is my parent class and StudentViewModel and PersonnelViewModel are my classes which have inherited data members and properties for the parent class.
1st Model
public class ContestantViewModel
{
//Data members
private string mName;
private string mSurname;
private string mCellPhone;
private string mEmail;
private string mMemberType;
//Defeaut Constructor
public ContestantViewModel()
{
mName = "NoName";
mSurname = "NoSurname";
mCellPhone = "NoCellNumber";
mEmail = "NoEmail";
mMemberType = "NoMemberType";
}
//Constructor
public ContestantViewModel(string Name, string Surname, string CellPhone, string Email, string MemberType)
{
mName = Name;
mSurname = Surname;
mCellPhone = CellPhone;
mEmail = Email;
mMemberType = MemberType;
}
//Properties
public string Name
{
get { return mName; }
set { mName = value; }
}
public string Surname
{
get { return mSurname; }
set { mSurname = value; }
}
public string CellPhone
{
get { return mCellPhone; }
set { mCellPhone = value; }
}
public string Email
{
get { return mEmail; }
set {mEmail = value; }
}
public string MemberType
{
get; set;
}
}
2rd Model
public class PersonnelViewModel : ContestantViewModel
{
private string mWorkerType;
private string mDegree;
public PersonnelViewModel(string Name, string Surname, string CellPhone, string Email, string MemberType, string WorkerType, string Degree) : base (Name,Surname,CellPhone,Email, MemberType)
{
mWorkerType = WorkerType;
mDegree = Degree;
}
public PersonnelViewModel()
{
mWorkerType = "NoWorkerType";
mDegree = "NoDegree";
}
public string WorkerType
{
get { return mWorkerType;}
set { mWorkerType = value; }
}
public string Degree
{
get { return mDegree; }
set { mDegree = value; }
}
}
3rd Model
public class StudentViewModel : ContestantViewModel
{
//Data members
private int mAge;
//D Constructor
public StudentViewModel()
{
mAge = 0;
}
//Constructor
public StudentViewModel(string Name, string Surname, string CellPhone, string Email, string MemberType, int Age) : base(Name, Surname, CellPhone, Email, MemberType)
{
mAge = Age;
}
//properties
public int Age
{
get { return mAge; } set { mAge = value; }
}
}
and this is my controller
public class HomeController : Controller
{
// list to hold all my new members
private static List<ContestantViewModel> List = new List<ContestantViewModel>();
// GET: Home
public ActionResult Index()
{
return View();
}
// GET: Signup
public ActionResult Signup(string Name, string Surname, string Email, string Cellphone, string MemberType, int Age,string WorkerType,string Degree)
{
StudentViewModel Stundent = new StudentViewModel();
PersonnelViewModel Personnel = new PersonnelViewModel();
if (MemberType == "Student")
{
//creates instance
Stundent.Name = Name;
Stundent.Surname = Surname;
Stundent.Email = Email;
Stundent.CellPhone = Cellphone;
Stundent.MemberType = MemberType;
Stundent.Age = Age;
// Add data to list
List.Add(Stundent);
}
else
{
//creates instance
Personnel.Name = Name;
Personnel.Surname = Surname;
Personnel.Email = Email;
Personnel.CellPhone = Cellphone;
Personnel.MemberType = MemberType;
Personnel.WorkerType = WorkerType;
Personnel.Degree = Degree;
// Add data to list
List.Add(Personnel);
}
return View(List);
}
}
Put your collection into it's own view model instead of trying to reference it with this line:
#model List<Assignment9_u14333393.Models.ContestantViewModel>
Make a new view model, ViewModelCollections with a collection of your ContestantViewModel. Something like
List<ContestantViewModel> ContestantList
(you can also add others, like your students and workers and reuse the model, even if for some purposes some collections are empty)
Then reference that with:
#model ViewModelCollections
Once you have put all your contestants into the collection you are very close in your current view code.
<div class="members">
<table id="contestantListTable">
<tbody>
#* Column Headers *#
<tr class="contestantListHeaders">
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
#* Content Rows *#
#foreach (var temp in Model.ContestantList)
{
<tr>
<td>#temp.mName</td>
<td>#temp.mSurName</td>
<td>#temp.mEmail</td>
<td>#temp.mCellPhone</td>
</tr>
}
</tbody>
</table>
</div>
Instead of this saying "Name: Contestant" "LastName: #1" etc etc
You will have a table:
First Name | Last Name | Email etc etc
Contestant | #1 | ...
.
.
.

Iterate Multiple input array form values in asp.net 5 controller action

<div class="form-group">
#{
for (int i = 0; i <= 7; i++)
{
<input id="mondayM" name="StartTime[]"
type="text" class="time monday M" />
}
}
</div>
" i am repeating input values as i have to take 7 values.How can i iterate it in controller action to get 7 values"
use an array or list in your model eg: List mondayM { get; set; }
in your view change id="mondayM" to id="mondayM[#i]"
Hopefully this example will help:
// Model
public class DoctorSchedule
{
public string Something { get; set; }
}
public class DoctorScheduleModel
{
public IList<DoctorSchedule> DoctorSchedules { get; set; }
public DoctorScheduleModel()
{
DoctorSchedules = new List<DoctorSchedules>();
for (int i = 0; i < 7; i++)
{
DoctorSchedules.Add(new DoctorSchedule());
}
}
}
// Controller
public class DoctorScheduleController : Controller
{
public ActionResult Index(DoctorScheduleModel model)
{
foreach (DoctorSchedule doctorSchedule in model.DoctorSchedules)
{
var x = doctorSchedule.Something;
}
}
}
// View
#model DoctorScheduleModel
#for (int i = 0; i < Model.DoctorSchedules.Count; i++)
#{
#Html.EditorFor(m => Model.DoctorSchedules[i].Something)
#}

CheckBox List in ASP.net MVC3

I have an SuperVisor Form and I need to show a list of Employees with checkboxes for selection.
Once I click Save , supervisor information and the selected employees id should be saved to DB.
Which is best option to achieve this ?
Model
public class SelectEmployee
{
public int _EmployeeID;
public string _EmployeeName;
public bool _check;
public int EmployeeID { get { return _EmployeeID; } set { _EmployeeID = value; } }
public string EmployeeName { get { return _EmployeeName; } set { _EmployeeName = value; } }
public bool check { get { return _check; } set { _check = value; } }
}
public class DemoManager
{
public static List<SelectEmployee> GetSelectedEmployee()
{
DemoEntities db = new DemoEntities();
var query = (from i in db.EmployeeMasters
select new SelectEmployee { EmployeeID = i.EmployeeID, EmployeeName = i.EmployeeName, check = false }).ToList();
return query;
}
}
View
#using(Html.BeginForm())
{
<table class="table">
#for (var i = 0; i < Model.Count; i++) {
<tr>
<td>
#Html.DisplayFor(modelEmployee => modelEmployee[i].EmployeeID)
</td>
<td>
#Html.CheckBoxFor(modelEmployee => modelEmployee[i].check)
</td>
<td>
#Html.DisplayFor(modelEmployee => modelEmployee[i].EmployeeName)
</td>
</tr>
}
</table>
<input type="submit" value="click" />
}
Controller
public ActionResult Index()
{
return View(DemoManager.GetSelectedEmployee());
}
[HttpPost]
public ActionResult Index(List<SelectEmployee> emp)
{
var query = (from i in emp
where i.check == true
select i);
// Here you can set the insert statements the query will contain only selected items
return View(model);
}

Paged list isn't working

I did the Getting Started with ASP.NET MVC 3 (C#) tutorial by Rick Anderson, is a catalog of products, is already working, but, since i added a long list of products, now i need a pagedList to get just a number of products per page, looking around i found an example but isn't working, to my project i added on the Models file this class named IPagedList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Presupuestos.Models
{
public interface IPagedList
{
int ItemCount
{
get;
set;
}
int PageCount
{
get;
set;
}
int PageIndex
{
get;
set;
}
int PageSize
{
get;
set;
}
bool IsPreviousPage
{
get;
}
bool IsNextPage
{
get;
}
}
public interface IPagedList<T> : IList<T>, IPagedList
{
}
public class PagedList<T> : List<T>, IPagedList<T>
{
private List<Productos> list;
private int p;
private int p_2;
public PagedList(IQueryable<T> source, int index, int pageSize)
{
this.ItemCount = source.Count();
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
this.PageCount = (int)Math.Ceiling((double)this.ItemCount / this.PageSize);
}
public PagedList(List<T> source, int index, int pageSize)
{
this.ItemCount = source.Count();
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
}
public PagedList(List<Productos> list, int p, int p_2)
{
// TODO: Complete member initialization
this.list = list;
this.p = p;
this.p_2 = p_2;
}
public int ItemCount
{
get;
set;
}
public int PageCount
{
get;
set;
}
public int PageIndex
{
get;
set;
}
public int PageSize
{
get;
set;
}
public bool IsPreviousPage
{
get
{
return (PageIndex > 0);
}
}
public bool IsNextPage
{
get
{
return (PageIndex + 1) * PageSize <= ItemCount;
}
}
}
public static class Pagination
{
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
{
return new PagedList<T>(source, index, pageSize);
}
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
{
return new PagedList<T>(source, index, 10);
}
}
}
Also, i added another class named HTMLHelpers.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using Presupuestos.Models;
namespace Presupuestos.Models
{
public static class ListPaging
{
public static MvcHtmlString Paging(this HtmlHelper html, IPagedList pagedList, string url, string pagePlaceHolder)
{
StringBuilder sb = new StringBuilder();
// only show paging if we have more items than the page size
if (pagedList.ItemCount > pagedList.PageSize)
{
sb.Append("<ul class=\"paging\">");
if (pagedList.IsPreviousPage && pagedList.PageIndex != 1)
{
// previous link
sb.Append("<li class=\"prev\"><a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex - 1).ToString()));
sb.Append("\" title=\"Go to Previous Page\">prev</a></li>");
}
for (int i = 0; i < pagedList.PageCount; i++)
{
sb.Append("<li>");
if (i == pagedList.PageIndex)
{
sb.Append("<span>").Append((i + 1).ToString()).Append("</span>");
}
else
{
sb.Append("<a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (i + 1).ToString()));
sb.Append("\" title=\"Go to Page ").Append((i + 1).ToString());
sb.Append("\">").Append((i + 1).ToString()).Append("</a>");
}
sb.Append("</li>");
}
if (pagedList.IsNextPage)
{
// next link
sb.Append("<li class=\"next\"><a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex + 1).ToString()));
sb.Append("\" title=\"Go to Next Page\">next</a></li>");
}
sb.Append("</ul>");
}
return MvcHtmlString.Create(sb.ToString());
}
}
}
Finally this is the view file, i just added the #using presupuestos.models and the last html.paging at the end:
#model IEnumerable<Presupuestos.Models.Productos>
#using Presupuestos.Models
#{
ViewBag.Title = "Productos";
}
<h2>Catalogo de Productos</h2>
<p>
#Html.ActionLink("Agregar Producto", "Create")
</p>
<table>
<tr>
<th>
Marca
</th>
<th>
Codigo
</th>
<th>
Nombre
</th>
<th>
Envase
</th>
<th>
PresentaciĆ³n
</th>
<th>
Linea
</th>
<th>
Categoria
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.marca)
</td>
<td>
#Html.DisplayFor(modelItem => item.codigo)
</td>
<td>
#Html.DisplayFor(modelItem => item.nombre)
</td>
<td>
#Html.DisplayFor(modelItem => item.envase)
</td>
<td>
#Html.DisplayFor(modelItem => item.presentaciĆ³n)
</td>
<td>
#Html.DisplayFor(modelItem => item.linea)
</td>
<td>
#Html.DisplayFor(modelItem => item.categoria)
</td>
<td>
#Html.ActionLink("Editar", "Edit", new { id = item.ID }) |
#Html.ActionLink("Detalles", "Details", new { id = item.ID }) |
#Html.ActionLink("Borrar", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
<div>
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
</div>
Hope you can help me, i have been stuck with this for one day, just last friday i started using mvc3, the good thing was what my boss needs is what is on the tutorial, but, now that i wanted to do this extra thing (pagedlist) i'm really lost!!
It looks as if in this line
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
you are hardcoding the current page index to be 1.
I'd guess that in your Index action method you need might want to have something representing your current page that you can pass through to your view, and replace the hardcoded 1 with that.
e.g.
public void Index(int page = 1)
{
// ... set up your view model
// ...
// ...
// page is added to the url by your paging helper.
ViewBag.CurrentPage = page;
return View(viewModel);
}
And in the view...
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),#ViewBag.CurrentPage,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
Based on what you said in your comment, that the paged list doesn't appear at the bottom of the page, I'd really recommend doing some debugging and seeing which code paths are actually executing. But anyway we can maybe guess the following...
First step is to put a breakpoint in the ListPaging.Paging and check it's actually getting called. If it is, and nothing at all is getting appended to your StringBuilder, then perhaps
if (pagedList.ItemCount > pagedList.PageSize)
{
// ...
is not evaluating to true. I'm assuming there's more items in your list than 10, so it should be true. So maybe the reason this isn't evaluating to true is because neither value is being set.
The constructor that you added looks dubious:
public PagedList(List<Productos> list, int p, int p_2)
{
// TODO: Complete member initialization
this.list = list;
this.p = p;
this.p_2 = p_2;
}
None of the properties that PagedList uses actually get set in here. what's the point of this constructor? What are p and p_2? If this constructor is being called, then ItemCount and PageSize will have no value. I'd suggest getting rid of it and letting the other constructors be called.

Resources