List of checkboxes always null MVC - c#

I'm having trouble with sending checkboxes and EditorFor values in MVC. I have two classes:
public class CompleteReceiving
{
public List<SiteOrderReceiving> order_detail { get; set; } //<- Data from DB. It contains all items for Order Receiving.
public List<SomeClass> new_form { get; set; } //<- Fields for form
}
public class SomeClass
{
[RegularExpression("^[0-9]*$", ErrorMessage = "Receive Quantity can only contain number")]
public decimal? receive_quantity { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "Damaged Quantity can only contain number")]
public decimal? damaged_quantity { get; set; }
public bool IsSelected { get; set; }
}
This is my View:
#for(int i = 0; i < Model.order_detail.Count; i++)
{
<tr>
<td>#Html.CheckBoxFor(m => m.new_form[i].IsSelected, new { id = "site_rec_checkbox", #class= "site_rec_checkbox" })
</td>
<td>#Html.EditorFor(m => m.new_form[i].receive_quantity, new { htmlAttributes = new { #class = "form-control fm", #autocomplete = "off", #autofocus = "autofocus", #placeholder = "Receiving Quantity" } })
#Html.ValidationMessageFor(m => m.new_form[i].receive_quantity, "", new { #class = "text-danger" })
</td>
}
And this is my Controller Action Code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SiteOrderReceiving(CompleteReceiving sor)
{
//Code for post
}
The problem is that whenever i select checkbox at any other index than 1 or 2 the List is always null. But for the first time if i select 3 or 4 and after that i select 1 or 2 than it works fine.
I don't know what i am doing wrong here.
Any help would be much appreciated.
Update
This is my Controller Action Code
[HttpGet]
public ActionResult SiteOrderReceiving(int? order_id)
{
var get_detail = (from oa in db.order_send
where oa.order_id == order_id
select new SiteOrderReceiving()
{
quantity_send = oa.send_quantity,
date_send = oa.send_date,
order_id = oa.order_id
}).ToList();
var a = new CompleteReceiving();
a.order_detail = get_detail;
return View(a);
}
And this is my View
#using (Html.BeginForm("SiteOrderReceiving", "Site", FormMethod.Post, new { id = "receive_form" }))
{
#Html.AntiForgeryToken();
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#for(int i = 0; i < Model.order_detail.Count; i++)
{
<tr>
<td>#Html.CheckBoxFor(m => m.new_form[i].IsSelected, new { id = "site_rec_checkbox", #class= "site_rec_checkbox" })
</td>
<td>#Html.EditorFor(m => m.new_form[i].receive_quantity, new { htmlAttributes = new { #class = "form-control fm", #autocomplete = "off", #autofocus = "autofocus", #placeholder = "Receiving Quantity" } })
#Html.ValidationMessageFor(m => m.new_form[i].receive_quantity, "", new { #class = "text-danger" })
</td>
}
}

So i solved my problem. What i did was move properties of my form to existing class in which i was getting the data from DB.
Now my ViewModel looks like this:
public class CompleteReceiving
{
public List<SomeClass> order_detail { get; set; }
//Some Other properties
}
And then:
public class SomeClass
{
[RegularExpression("^[0-9]*$", ErrorMessage = "Receive Quantity can only contain number")]
public decimal? receive_quantity { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "Damaged Quantity can only contain number")]
public decimal? damaged_quantity { get; set; }
public bool IsSelected { get; set; }
public string item_name { get; set; }
}
After updating my code like above, everything started working fine. Hope it helps someone in the future.

Related

MVC All DropdownListsFor are returning Error : "The value Cannot be Null, Parameter name:Items" After POST, Works Perfectly populating when GET

this is my issue, please I need Help :(
Populating the dropdownlists Works Perfectly, in my GET Action result, but after POST, the values of all the dropdownlists return null, I've tried with debugging and also the values seems to be null after POST.
Honestly, I don't know what I'm doing Wrong here, I've tried the same method with other ViewModels, Controllers an Views in my project and works perfectly fine, but in this case when I try to Create/Edit registers after POST, gives me this error: [enter image description here][1]
This is my ViewModel
public class CrearBugsViewModel
{
public int id { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public string Nombre { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
[DataType(DataType.MultilineText)]
[Display(Name = "Descripción")]
public string Descripcion { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Fecha Cración")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public Nullable<System.DateTime> FechaCreacion { get; set; }
public Nullable<int> UsuarioQueReporta { get; set; }
public Nullable<int> UsuarioAsignadoAlBug { get; set; }
public Nullable<int> Proyecto { get; set; }
public Nullable<int> Categoria { get; set; }
public Nullable<int> Prioridad { get; set; }
public Nullable<int> Estado { get; set; }
public Nullable<int> UltimoUsuarioQueEdito { get; set; }
[DataType(DataType.Date)]
[Display(Name = "última fecha de Edición")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public Nullable<System.DateTime> UltimaFechaEdicion { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
[DataType(DataType.MultilineText)]
[Display(Name = "Ingrese su Query")]
public string query { get; set; }
public IEnumerable<SelectListItem> ListaUsuariosQueReporta { get; set; }
public IEnumerable<SelectListItem> ListaUsuariosAsignadoAlBug { get; set; }
public IEnumerable<SelectListItem> ListaProyectos { get; set; }
public IEnumerable<SelectListItem> ListaCategorias { get; set; }
public IEnumerable<SelectListItem> ListaPrioridades { get; set; }
public IEnumerable<SelectListItem> ListaEstados { get; set; }
public IEnumerable<SelectListItem> ListaUltimosUsuariosQueEditaron { get; set; }
}
This is my Controller
private Bug_TrackEntities db = new Bug_TrackEntities();
CrearBugsViewModel agregarBugViewModel = new CrearBugsViewModel();
public ActionResult Crear()
{
agregarBugViewModel = new CrearBugsViewModel()
{
ListaUsuariosQueReporta = db.Usuarios.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.usuario
}),
ListaUsuariosAsignadoAlBug = db.Usuarios.Select(d => new SelectListItem
{
Value = d.id.ToString(),
Text = d.usuario
}),
ListaProyectos = db.Proyecto.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaCategorias = db.Categoria.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaPrioridades = db.Prioridad.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
};
return View(agregarBugViewModel);
}
//POST: Crear
[HttpPost]
public ActionResult Crear(CrearBugsViewModel crearBug)
{
try
{
var Bug = new Models.Bugs();
if (ModelState.IsValid)
{
Bug.Nombre = crearBug.Nombre;
Bug.Descripcion = crearBug.Descripcion;
Bug.FechaCreacion = DateTime.Now;
Bug.UsuarioQueReporta = crearBug.UsuarioQueReporta;
Bug.UsuarioAsignadoAlBug = crearBug.UsuarioAsignadoAlBug;
Bug.Proyecto = crearBug.Proyecto;
Bug.Categoria = crearBug.Categoria;
Bug.Prioridad = crearBug.Prioridad;
Bug.Estado = 1;//enviado
Bug.UltimaFechaEdicion = DateTime.Now;
Bug.UltimoUsuarioQueEdito = null;
Bug.query = crearBug.query;
db.Bugs.Add(Bug);
db.SaveChanges();
return Redirect("/Bugs/Index");
}
agregarBugViewModel = new CrearBugsViewModel()
{
ListaUsuariosQueReporta = db.Usuarios.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.usuario
}),
ListaUsuariosAsignadoAlBug = db.Usuarios.Select(d => new SelectListItem
{
Value = d.id.ToString(),
Text = d.usuario
}),
ListaProyectos = db.Proyecto.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaCategorias = db.Categoria.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaPrioridades = db.Prioridad.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
};
return View(crearBug);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
This is my view
#model BugTrack.Models.ViewModels.Bugs.CrearBugsViewModel
#{
ViewBag.Title = "Nuevo Bug";
}
<h2>#ViewBag.Title</h2>
#using (Html.BeginForm("Crear", "Bugs", FormMethod.Post))
{
<div class="row">
<div class="col-lg-12">
<div>
#Html.LabelFor(d => d.Nombre)
#Html.TextBoxFor(d => d.Nombre, "", new { #class = "form-control" })
#Html.ValidationMessageFor(d => d.Nombre, null, new { #class = "rojo-errores" })
</div>
<div>
#Html.LabelFor(d => d.Descripcion)
#Html.TextBoxFor(d => d.Descripcion, "", new { #class = "form-control" })
#Html.ValidationMessageFor(d => d.Descripcion, null, new { #class = "rojo-errores" })
</div>
<div>
#Html.LabelFor(d => d.FechaCreacion)
#Html.EditorFor(model => model.FechaCreacion, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(d => d.FechaCreacion, null, new { #class = "rojo-errores" })
</div>
<div>
#Html.LabelFor(model => model.UsuarioQueReporta, "UsuarioQueReporta")
#Html.DropDownListFor(model => model.UsuarioQueReporta, new SelectList(Model.ListaUsuariosQueReporta, "Value", "Text"), "--Seleccione un usuario--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.UsuarioQueReporta, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.UsuarioAsignadoAlBug, "UsuarioAsignadoAlBug")
#Html.DropDownListFor(model => model.UsuarioAsignadoAlBug, new SelectList(Model.ListaUsuariosAsignadoAlBug, "Value", "Text"), "--Seleccione usuario asignado al bug--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.UsuarioAsignadoAlBug, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.Proyecto, "Proyecto")
#Html.DropDownListFor(model => model.Proyecto, new SelectList(Model.ListaProyectos, "Value", "Text"), "--Seleccione un proyecto--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Proyecto, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.Categoria, "Categoria")
#Html.DropDownListFor(model => model.Categoria, new SelectList(Model.ListaCategorias, "Value", "Text"), "--Seleccione una categoría--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Categoria, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.Prioridad, "Prioridad")
#Html.DropDownListFor(model => model.Prioridad, new SelectList(Model.ListaPrioridades, "Value", "Text"), "--Seleccione prioridad--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Prioridad, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(d => d.query)
#Html.TextBoxFor(d => d.query, "", new { #class = "form-control" })
#Html.ValidationMessageFor(d => d.query, null, new { #class = "rojo-errores" })
</div>
<br />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
</div>
}
And This is What I've tried in the past with another ViewModel,Controller,View and worked fine for me:
ViewModel
public class CrearUsuariosAsignadosAlProyectoViewModel
{
[HiddenInput(DisplayValue = false)]
public int id { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public Nullable<int> Proyecto { get; set; }
public IEnumerable<SelectListItem> ListaProyectos { get; set; }
[Display(Name = "Usuario que desea asignar al Proyecto")]
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public Nullable<int> Usuario { get; set; }
public IEnumerable<SelectListItem> ListaUsuarios { get; set; }
public string NombreUsuario { get; set; }
public string NombreProyecto { get; set; }
}
Controller
public ActionResult Crear()
{
crearUsuariosAsignadosAlProyectoView = new CrearUsuariosAsignadosAlProyectoViewModel
{
ListaProyectos = db.Proyecto.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaUsuarios = db.Usuarios.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.usuario
})
};
return View(crearUsuariosAsignadosAlProyectoView);
}
//POST: Crear
[HttpPost]
public ActionResult Crear(CrearUsuariosAsignadosAlProyectoViewModel agregarUsuariosAsignados)
{
try
{
var usuarioAsignado = new Models.UsuariosAsignadosAlProyecto();
if (ModelState.IsValid)
{
usuarioAsignado.Proyecto = agregarUsuariosAsignados.Proyecto;
usuarioAsignado.Usuario = agregarUsuariosAsignados.Usuario;
db.UsuariosAsignadosAlProyecto.Add(usuarioAsignado);
db.SaveChanges();
return Redirect("/UsuariosAsignadosAlProyecto/Index");
}
var listas = new CrearUsuariosAsignadosAlProyectoViewModel
{
ListaProyectos = db.Proyecto.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.Nombre
}),
ListaUsuarios = db.Usuarios.Select(x => new SelectListItem
{
Value = x.id.ToString(),
Text = x.usuario
})
};
return View(agregarUsuariosAsignados);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
View
<div>
#Html.LabelFor(model => model.Proyecto, "Proyecto")
#Html.DropDownListFor(model => model.Proyecto, new SelectList(Model.ListaProyectos, "Value", "Text"), "--Seleccione un proyecto--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Proyecto, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.Usuario, "Usuario")
#Html.DropDownListFor(model => model.Usuario, new SelectList(Model.ListaUsuarios, "Value", "Text"), "--Seleccione un usuario para asignar--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Usuario, "", new { #class = "text-danger" })
</div>
As you can see, first I declare Ienumerable SelectListItems objects in ViewModel, then in the controller I Select data from my database and store it in these SelectItems Objects, which are the same in the GET action result and POST, then In my view I pass these objects as dropdownlistsfor Items which are populated perfectly fine, and finally when user selects options it store the register in the database.
[1]: https://i.stack.imgur.com/rmpRY.png
return View(crearBug);
You are returning your posted model, not the viewmodel created after post filled up. Should be
return View(agregarBugViewModel);
After I've tried 4 ways to do the same behavior an getting the same bug, I decided to clear my viewmodel and started from zero, which made me figure out that the validation "[Required(ErrorMessage = "*Campo {0} obligatorio")]" used in most of my attributes (including the ones used to get the values from the dropdownlistsfor) we're affecting the POST behavior, this is my viewmodel now:
public int id { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public string Nombre { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public string Descripcion { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public Nullable<System.DateTime> FechaCreacion { get; set; }
public Nullable<int> UsuarioQueReporta { get; set; }
public Nullable<int> UsuarioAsignadoAlBug { get; set; }
public Nullable<int> Proyecto { get; set; }
public Nullable<int> Categoria { get; set; }
public Nullable<int> Prioridad { get; set; }
public Nullable<int> Estado { get; set; }
public Nullable<int> UltimoUsuarioQueEdito { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> UltimaFechaEdicion { get; set; }
[Required(ErrorMessage = "*Campo {0} obligatorio")]
public string query { get; set; }
public IEnumerable<SelectListItem> ListaUsuariosQueReporta { get; set; }
public IEnumerable<SelectListItem> ListaUsuariosAsignadoAlBug { get; set; }
public IEnumerable<SelectListItem> ListaProyectos { get; set; }
public IEnumerable<SelectListItem> ListaCategorias { get; set; }
public IEnumerable<SelectListItem> ListaPrioridades { get; set; }
public IEnumerable<SelectListItem> ListaEstados { get; set; }
public IEnumerable<SelectListItem> ListaUltimosUsuariosQueEditaron { get; set; }
now I'm able to create registers as always

How to store data from form with dropdown using enum

I am trying to store the details from form to database using entity framework, i am using enum to store dropdown content.while submitting i am facing issue.
issue: System.InvalidOperationException: 'The entity type socialwebtable is not part of the model for the current context.'
[HttpPost]
public ActionResult register(socialwebtable c1)
{
socialwebsiteEntities db = new socialwebsiteEntities();
//data1 is a table name
socialwebtable data23 = new socialwebtable();
data23.name = c1.name;
data23.bloodgroup = c1.bloodgroup;
data23.city = c1.city;
data23.phonenumber = c1.phonenumber;
db.socialwebtables.Add(data23);
// db.socialwebtables.InsertOnSubmit(data23);
db.SaveChanges();
return View();
}
View:
<div class="form-group">
#Html.LabelFor(model => model.bloodgroup, htmlAttributes: new {
#class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(
x => x.bloodgroup,
"Select My Type",
new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.bloodgroup, "", new {
#class = "text-danger" })
</div>
</div>
Model:
public enum enum1
{
[Display(Name = "O+")]
O,
[Display(Name = "A+")]
B,
[Display(Name = "B+")]
A,
[Display(Name = "AB+")]
AB,
[Display(Name = "O-")]
O1,
[Display(Name = "A-")]
B1,
[Display(Name = "B-")]
A1,
[Display(Name = "AB-")]
AB1,
}
public partial class socialwebtable
{
public int id { get; set; }
public string name { get; set; }
public enum1 bloodgroup { get; set; }
public string city { get; set; }
public decimal phonenumber { get; set; }
}
}
This error occurs if the table(s) are not created at startup. Please place below code in your custom DBContext class to address the issue.
protected void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Estate>().ToTable("socialwebtable");
}
Hope this helps you..

How can I take data from two separated column to be shown in DropDownList using .Net MVC 5

I am new student developer in ASP.Net MVC 5. I need to take one data from my two seperated table column in SQL while inserting but I am taking only one value into my DropDownList. How can I do this? There is not properly info or source according to my research. Does anyone help me ?
Model:
public class PersonelModel
{
public int pid { get; set; }
public string pAd { get; set; }
public string pSoyad { get; set; }
public string yonetici { get; set; }
}
My Add Method:
public ActionResult PersonelAdd()
{
/*it does not work
ViewBag.yonetici = new SelectList(db.Personel, "pAd", "pAd" +" "+ "pSoyad");*/
/*it work*/
ViewBag.yonetici = new SelectList(db.Personel, "pAd", "pAd");
return View();
}
[HttpPost]
public ActionResult PersonelAdd(Personel pModel)
{
var personel = new Personel();
personel.pAd = pModel.pAd;
personel.pSoyad = pModel.pSoyad;
personel.yonetici = pModel.yonetici;
/*it works*/
ViewBag.yonetici = new SelectList(db.Personel, "pAd", "pAd", pModel.yonetici
);
// it does not work
// ViewBag.yonetici = new SelectList(db.Personel, "pAd", "pAd"+" "+"pSoyad", pModel.yonetici);
db.Personel.Add(personel);
db.SaveChanges();
return RedirectToAction("Index", "AdminUI");
}
My form:
<div class="form-group">
#Html.LabelFor(model => model.yonetici, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("yonetici", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.yonetici, "", new { #class = "text-danger" })
</div>
</div>
SelectList constructor takes field names (dataValueField and dataTextField) which have to exist in your model class.
You can add new field to describe what do you want to show as Text (note new Description property):
public class PersonelModel
{
public int pid { get; set; }
public string pAd { get; set; }
public string pSoyad { get; set; }
public string yonetici { get; set; }
public string Description
{
get
{
return pAd + " " + pSoyad;
}
}
}
Now you can show pAd + pSoyad as Text Value of SelectList:
ViewBag.yonetici = new SelectList(db.Personel, "pAd", "Description")

Return list from Razor View to Action

I have an Action where I loop through an unknown number of values. These are channels that relate to a device, the user selects the device from a dropdown and the form is created based on the number of channels the device has, it could be 1 or 50 or anywhere in between.
//This is the model I use
[Display(Name = "Select a customer")]
public IEnumerable<SelectListItem> CustomerNames { get; set; }
public string CustomerNameSelected { get; set; }
[Display(Name = "Select a device")]
public IEnumerable<SelectListItem> Devices { get; set; }
public string DeviceSelected { get; set; }
[Display(Name = "Channel Name")]
public string ChannelName { get; set; }
[Display(Name = "Channel Type")]
public string ChannelType { get; set; }
[Display(Name = "Calculated")]
public bool Calculated { get; set; }
public int ChannelCount { get; set; }
public List<ChannelManagerModel> ChannelNames { get; set; }
private List<string> UomList {
get
{
var l = new List<string>();
l.Add("Electricity");
l.Add("Gas");
l.Add("Water");
l.Add("Heat");
l.Add("kWh");
l.Add("Wh");
l.Add("kVarh");
l.Add("Wh");
l.Add("Volts 1");
l.Add("Volts 2");
l.Add("Volts 3");
l.Add("Current 1");
l.Add("Current 2");
l.Add("Current 3");
l.Add("Hz");
l.Add("Litres");
l.Add("Cubic Metres");
l.Add("Cubic Feet");
return l;
}
}
public IEnumerable<SelectListItem> Uom {
get {
List<SelectListItem> sl = new List<SelectListItem>();
foreach (var item in UomList)
{
sl.Add(new SelectListItem() { Text = item, Value = item });
};
return sl;
}
set { }
}
public string UomSelected { get; set; }
As I have now created new form elements using the loop, how do I pass this extra information back to the action using the ViewModel.
#{List<string> channelName = Model.ChannelNames.Select(x => x.ChannelName).OrderByDescending(x => Model.ChannelName).ToList();
int count = 0;
foreach (var channel in channelName)
{
count++;
var ddlId = ("ddlId" + count).ToString();
var txtBoxId = ("txtBoxId" + count).ToString();
<tr>
<td>
#Html.Label(#channel)
</td>
<td>
#Html.DropDownListFor(x => x.UomSelected, Model.Uom, "Select", new { #class = "form-control form-control-sm", #id = #ddlId, #data_val = false })
<script type="text/javascript">
$('##ddlId').change(function () {
$('##txtBoxId').val($(this).val());
});
</script>
</td>
<td>
#Html.EditorFor(model => model.ChannelType, new { htmlAttributes = new { #id = #txtBoxId, #class = "form-control form-control-sm" } })
#Html.ValidationMessageFor(model => model.ChannelType, "", new { #class = "text-danger" })
</td>
<td>
#Html.CheckBoxFor(model => model.Calculated)
</td>
</tr>
}
}
I suppose in my head I am thinking of creating another List to pass back to the view, but I can't work out how to do it, or if it is the correct method.
This is the action in the controller I want to pass the new data back to.
public async Task<ActionResult> SaveData(ChannelManagerViewModel cvm)
{
var cm = new channelManagerModel();
//Maybe loop through the ViewModel and add to the EF Model
var channelManagerModel = new ChannelManagerModel();
if (ModelState.IsValid)
{
db.ChannelManager.Add(channelManagerModel);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(channelManagerModel);
}
Did this the other day, use a for(int count... loop instead of foreach in your view like below;
for(int count=0;count<channelName.Count;count++) {
<tr>
<td>
#Html.Label(#channelName[count])
</td>
<td>
#Html.DropDownListFor(x => x[count].UomSelected, Model.Uom, "Select", new { #class = "form-control form-control-sm", #data_val = false })
</td>
<td>
#Html.EditorFor(x => x[count].ChannelType, new { htmlAttributes = new { #id = #txtBoxId, #class = "form-control form-control-sm" } })
#Html.ValidationMessageFor(x => x[count].ChannelType, "", new { #class = "text-danger" })
</td>
<td>
#Html.CheckBoxFor(x => x[count].Calculated)
</td>
</tr>
}
Now in your controller you can have something like below
public async Task<ActionResult> SaveData(List<ChannelManagerViewModel> cvm)

Binding complex model and DropDownListFor

My entities:
public class Meal
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[Required(ErrorMessage = "Proszę podać nazwę posiłku")]
public string Name { get; set; }
[Required(ErrorMessage = "Proszę podać ilość białka")]
[Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
public double Protein { get; set; }
[Required(ErrorMessage = "Proszę podać ilość węglowodanów")]
[Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
public double Carbohydrates { get; set; }
[Required(ErrorMessage = "Proszę podać ilość tłuszczy")]
[Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
public double Fat { get; set; }
[Required(ErrorMessage = "Proszę podać ilość kalorii")]
[Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
public double Calories { get; set; }
}
public class EatenMeal
{
public int Id { get; set; }
public virtual Meal Meal { get; set; }
public virtual MealType MealType { get; set; }
public double Serving { get; set; }
public string Username { get; set; }
public DateTime Date { get; set; }
}
public class MealType
{
public int Id { get; set; }
public string Name { get; set; }
}
In MealController's view MealList which displays meals from datebase. And there is a button "Add" which refers to action AddEatenMeal in EatenMealController.
public ActionResult AddEatenMeal(int id)
{
var meal = mealRepository.GetMeal(id);
EatenMeal eatenMeal = new EatenMeal() { Meal = meal, Username = User.Identity.Name };
return View(eatenMeal);
}
[HttpPost]
public ActionResult AddEatenMeal(EatenMeal eatenMeal)
{
if(ModelState.IsValid)
{
eatenMealRepository.AddEatenMeal(eatenMeal);
RedirectToAction("Index", "Home");
}
return RedirectToAction("Index", "Home");
}
I am creating there object EatenMeal and partially initializing this object. Then I am passing this object to View to further initializing.
#model Domain.Entities.EatenMeal
#{
ViewBag.Title = "Dodawanie posiłku do dziennika";
}
#using (Html.BeginForm("AddEatenMeal","EatenMeal", FormMethod.Post, new {#class = "form"}))
{
#Html.HiddenFor(x => x.Meal.Name)
#Html.HiddenFor(x => x.Username)
#Html.HiddenFor(x => x.Meal.Calories)
#Html.HiddenFor(x => x.Meal.Carbohydrates)
#Html.HiddenFor(x => x.Meal.Fat)
#Html.HiddenFor(x => x..Meal.Protein)
#Html.HiddenFor(x => x.Meal.Id)
#Html.HiddenFor(x=>x.Username)
<div class="form-group">
#Html.Label("Nazwa posiłku")
#Html.Label(Model.Meal.Name, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Porcja (g)")
#Html.TextBoxFor(x => x.Serving, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Typ posiłku")
#Html.DropDownListFor(x=>x.MealType)????
</div>
<div class="form-group">
#Html.Label("Data spożycia")
#Html.TextBoxFor(x => x.Date, new { #class = "form-control", #id="date-eaten", #Value=DateTime.Today.ToShortDateString()})
</div>
<input type="submit" class="btn btn-info" value="Dodaj" />
}
Now I have a question. Is it correct to hiding fields? I don't know how I can save data from first controller to second in other way.
And is a second question. How I can make DropDownListFor for property MealTye in EatenMeal?
Rather than sending and receiving a whole lot of unused data across the wire and opening yourself to over posting attack, create a view model that represents what you want to display and edit. See What is a view model in MVC?
View model
public class EatenMealVM
{
public int MealID { get; set; }
[Display(Name="Nazwa posiłku")]
public string MealName { get; set; }
[Display(Name = "Typ posiłku")]
[Required(ErrorMessage = "Please select a meal")]
public int? MealTypeID { get; set; }
[Display(Name = "Porcja (g)")]
public double Serving { get; set; } // is this really double?
[Display(Name = "Data spożycia")]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public SelectList MealTypeList { get; set; }
}
Controller
public ActionResult AddEatenMeal(int id)
{
var meal = mealRepository.GetMeal(id);
var mealTypes = // get the list of meal types from the database
EatenMealVM model = new EatenMealVM()
{
MealID = meal.Id,
MealName = meal.Name,
MealTypeList = new SelectList(mealTypes, "ID", "Name")
};
return View(model);
}
View
#model EatenMealVM
....
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.MealID)
#Html.DisplayNameFor(m => m.MealName)
#Html.DisplayFor(m => m.MealName)
#Html.LabelFor(m => m.MealTypeID)
#Html.DropDownListFor(m => m.MealTypeID, Model.MealTypeList, "--Please select--")
#Html.ValidationMessageFor(m => m.MealTypeID)
#Html.LabelFor(m => m.Serving)
#Html.TextBoxFor(m => m.Serving, new { #class = "form-control")
#Html.ValidationMessageFor(m => m.Serving)
#Html.LabelFor(m => m.Date)
#Html.TextBoxFor(m => m.Date)
#Html.ValidationMessageFor(m => m.Date, new { #class = "form-control" })
<input type="submit" class="btn btn-info" value="Dodaj" />
}
Post method
[HttpPost]
public ActionResult AddEatenMeal(EatenMealVM model)
{
if (!ModelState.IsValid)
{
var mealTypes = // get the list of meal types from the database
model.MealTypeList = new SelectList(mealTypes, "ID", "Name");
return View(model);
}
// Initialize new EatenMeal class
// Map properties from view model (including setting user name)
// Save and redirect
}
Note also the use of [Display] attribute and #Html.LabelFor(). Currently you not creating 'real' labels (they are not associated with the corresponding control)

Categories

Resources