How to display combobox in a table?RSS - asp.net

How to display a combobox for the current model in the table?
How to make the model correctly in order to display a combobox in the table?
Currently, I get the result, which is shown in the picture.
ASP.NET Core 3.1
Problems:
  - in the field with the combo box the current value of the field for recording is not displayed.
Company.cs
public class Company
{
public int Id { get; set; }
public string Picture { get; set; }
public string Name { get; set; }
public string Description{ get; set; }
public bool Status { get; set; }
public Status2 Status2Value { get; set; }
public class Status2
{
public int ID { get; set; }
public string Status { get; set; }
}
}
HomeController.cs
public class HomeController : Controller
{
public IActionResult Index()
{
List<Company> companies_List = new List<Company>();
companies_List = MockCompanyData.CompanyList_prop;
List<Company.Status2> status2_List = new List<Company.Status2>();
status2_List = MockCompanyData.CompanyStatus2_prop;
IndexVM indexVM = new IndexVM { Companies = companies_List, companyStatus2 = status2_List };
return View(indexVM);
}
}
IndexVM.cs
public class IndexVM
{
public IEnumerable<Company> Companies { get; set; }
public IEnumerable<Company.Status2> companyStatus2 { get; set; }
}
MockCompanyData.cs
static class MockCompanyData
{
static string mainPathForImg = #"";
static List<Company.Status2> companyStatus2List = new List<Company.Status2>
{
new Company.Status2 {ID=1, Status = ""},
new Company.Status2 {ID=2, Status = "Yes"},
new Company.Status2 {ID=3, Status = "No"}
};
static List<Company> companyList = new List<Company>
{
new Company {Id = 1, Picture = mainPathForImg + #"~/img/number_1_blue.png", Name ="Name_Company_1", Description ="Description_1", Status = true, Status2Value = companyStatus2List[0]},
new Company {Id = 2, Picture = mainPathForImg + #"~/img/number_2_blue.png", Name ="Name_Company_2", Description ="Description_2", Status = false, Status2Value = companyStatus2List[1]},
new Company {Id = 3, Picture = mainPathForImg + #"~/img/number_3_blue.png", Name ="Name_Company_3", Description ="Description_3", Status = true, Status2Value =companyStatus2List[0]}
};
public static List<Company> CompanyList_prop
{
get
{
return companyList;
}
set
{
companyList = value;
}
}
public static List<Company.Status2> CompanyStatus2_prop
{
get
{
return companyStatus2List;
}
set
{
companyStatus2List = value;
}
}
}
Index.cshtml
#using WebApplCore.Core.ViewModels;
#using WebApplCore.Models;
#model IndexVM;
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<head>
<link href="~/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<table class="table table-sm table-hover table-striped">
<thead class="thead-dark">
#{var headerMetadata = Model.Companies.FirstOrDefault();}
<tr>
<th>
#Html.DisplayNameFor(model => headerMetadata.Id)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Picture)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Name)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Description)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Status)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Status2Value)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (Company item in Model.Companies)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
#*#item.Id*#
</td>
<td>
<img src=#Html.DisplayFor(modelItem => item.Picture) class="rounded-circle" asp-append-version="true" alt="No Picture">
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<input type="checkbox" value=#Html.DisplayFor(modelItem => item.Status)>
</td>
<td>
<select name="companyId" class="form-control">
#foreach (Company.Status2 status2 in Model.companyStatus2)
{
<option value="#status2.ID">#Html.DisplayFor(modelItem => status2.Status)</option>
}
</select>
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</body>
Picture-1
Picture-2

As I understand, You want to set dropdown value: here is changes in you code:
Model:
public class Company
{
public int Id { get; set; }
public string Picture { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool Status { get; set; }
public int SelectedStatus2Value { get; set; }
public class Status2
{
public int ID { get; set; }
public string Status { get; set; }
}
}
static class MockCompanyData
{
static string mainPathForImg = #"";
static List<Company.Status2> companyStatus2List = new List<Company.Status2>
{
new Company.Status2 {ID=1, Status = ""},
new Company.Status2 {ID=2, Status = "Yes"},
new Company.Status2 {ID=3, Status = "No"}
};
static List<Company> companyList = new List<Company>
{
new Company {Id = 1, Picture = mainPathForImg + #"~/img/number_1_blue.png", Name ="Name_Company_1", Description ="Description_1", Status = true, SelectedStatus2Value = companyStatus2List[1].ID},
new Company {Id = 2, Picture = mainPathForImg + #"~/img/number_2_blue.png", Name ="Name_Company_2", Description ="Description_2", Status = false, SelectedStatus2Value = companyStatus2List[2].ID},
new Company {Id = 3, Picture = mainPathForImg + #"~/img/number_3_blue.png", Name ="Name_Company_3", Description ="Description_3", Status = true, SelectedStatus2Value =companyStatus2List[2].ID}
};
public static List<Company> CompanyList_prop
{
get
{
return companyList;
}
set
{
companyList = value;
}
}
public static List<Company.Status2> CompanyStatus2_prop
{
get
{
return companyStatus2List;
}
set
{
companyStatus2List = value;
}
}
View :
#using WebApplCore.Core.ViewModels;
#using WebApplCore.Models;
#model IndexVM;
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<head>
<link href="~/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<table class="table table-sm table-hover table-striped">
<thead class="thead-dark">
#{var headerMetadata = Model.Companies.FirstOrDefault();}
<tr>
<th>
#Html.DisplayNameFor(model => headerMetadata.Id)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Picture)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Name)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Description)
</th>
<th>
#Html.DisplayNameFor(model => headerMetadata.Status)
</th>
<th>
Status2Value
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (Company item in Model.Companies)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
#*#item.Id*#
</td>
<td>
<img src=#Html.DisplayFor(modelItem => item.Picture) class="rounded-circle" asp-append-version="true" alt="No Picture">
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<input type="checkbox" value=#Html.DisplayFor(modelItem => item.Status)>
</td>
<td>
<select name="companyId" class="form-control">
#foreach (Company.Status2 status2 in Model.companyStatus2)
{
if (status2.ID != item.SelectedStatus2Value)
{
<option value="#status2.ID">#Html.DisplayFor(modelItem => status2.Status)</option>
}
if (status2.ID == item.SelectedStatus2Value)
{
<option selected value="#status2.ID">#Html.DisplayFor(modelItem => status2.Status)</option>
}
}
</select>
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</body>
Output Here:

Related

How can I filter my database records on ASP.NET by a dropdownlist?

I'm trying to filter my records from a table created with Entity Framework where I want it to show my records with a specific condition.
I have this controller called ProductoesController, which is from the model Productos, that has the following attributes:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int idProducto { get; set; }
public String nombre { get; set; }
public String descripcion { get; set; }
public float precio { get; set; }
//ENUMS ---------------------
[EnumDataType(typeof(Talle))]
public Talle talle { get; set; }
[EnumDataType(typeof(ColorProducto))]
public ColorProducto ColorProd { get; set; }
[EnumDataType(typeof(CategoriaProducto))]
public CategoriaProducto CategoriaProd { get; set; }
public int CurrentNegocioId { get; set; }
public Negocio Negocio { get; set; }
This is the Enum I want to use to filter the products I loaded:
namespace MVCShopping.Models {
public enum ColorProducto {
ROJO,
ROSA,
VERDE,
AMARILLO,
NEGRO,
BLANCO,
GRIS
}
}
I had created a Viewbag.colors in the Index method of the controller where it creates a list with the loaded Enums
public async Task<IActionResult> Index()
{
ViewBag.colors = new SelectList(Enum.GetNames(typeof(ColorProducto)), ColorProducto.AMARILLO);
return View(await _context.Producto.ToListAsync());
}
My Index.cshtml has the following content:
#model IEnumerable<MVCShopping.Models.Producto>
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
#Html.DropDownList("ColorProducto", (ViewBag.colores as SelectList))
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.nombre)
</th>
<th>
#Html.DisplayNameFor(model => model.descripcion)
</th>
<th>
#Html.DisplayNameFor(model => model.precio)
</th>
<th>
#Html.DisplayNameFor(model => model.talle)
</th>
<th>
#Html.DisplayNameFor(model => model.ColorProd)
</th>
<th>
#Html.DisplayNameFor(model => model.CategoriaProd)
</th>
<th>
#Html.DisplayNameFor(model => model.CurrentNegocioId)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.nombre)
</td>
<td>
#Html.DisplayFor(modelItem => item.descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.precio)
</td>
<td>
#Html.DisplayFor(modelItem => item.talle)
</td>
<td>
#Html.DisplayFor(modelItem => item.ColorProd)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoriaProd)
</td>
<td>
#Html.DisplayFor(modelItem => item.CurrentNegocioId)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.idProducto">Edit</a> |
<a asp-action="Details" asp-route-id="#item.idProducto">Details</a> |
<a asp-action="Delete" asp-route-id="#item.idProducto">Delete</a>
</td>
</tr>
}
</tbody>
</table>
I added the #Html.DropDownList("ColorProducto", (ViewBag.colores as SelectList)) line, but I don't know how to configure this to filter my records by my selection.
This is a screenshot of how it is showing:
How do I code the records of the table to show up only if ColorProd has the same value than that DropDownList?
Thank you so much!
Table In Html
<div class="table-responsive">
<table class="table table-hover table-bordered mb-0 text-center" id="detailsTable">
<thead style="background-color:#f1f1f1;">
<tr>
<th style="width:10%;">ItemID</th>
<th style="width:40%">Item Name</th>
<th hidden="hidden" style="width:8%;">Unite No</th>
<th style="width:10%">Unite Name</th>
<th hidden="hidden" style="width:10%">F</th>
<th style="width:10%">Count</th>
<th style="width:10%">Price</th>
<th style="width:10%">Total</th>
</tr>
</thead>
<tbody id="contacts"></tbody>
</table>
</div>
Use Ajax in view
$('#BLDItemID').bind('change', function () {
$("#detailsTable tbody tr").remove();
$('#BLDCount').val(1);
$("#ITMNM").val('');
$("#ItemEXP").val('');
$.ajax({
url: '#Url.Action("RefrishItemList", "Manufacturings")',
type: "GET",
contentType: "application/json; charset=utf-8",
data: { id: $("#BLDItemID").val() },
dataType: "json",
success: function (data) {
var row = '';
var PRS = '';
var dtExpert = '';
$.each(data, function (index, item) {
row += '<tr><td>' + item.Id + '</td><td>' + item.Name + '</td><td hidden="hidden">' + item.Unite + '</td><td>' + item.UnitName + '</td><td hidden>' + item.UnTOT + '</td><td>' + item.Count + '</td><td>' + item.Price + '</td><td>' + item.Total + '</td></tr>';
PRS = item.ITPrice;
dtExpert = item.ITDTEXP;
});
$("#contacts").html(row);
$("#BLDPrice").val(PRS);
$("#ItemEXP").val(dtExpert);
$("#ITMNM").val($("#BLDItemID option:selected").text());
},
error: function (result) {
alert("Error");
}
});
})
in Control
public JsonResult RefrishItemList(int? id)
{
string DTExprVL = "";
var ITMPrice = db.TBLItems.Where(s => s.ItemID == id).Select(x => x.ItemInvoicePR).FirstOrDefault();
var EXPDT = db.TBLItems.Where(s => s.ItemID == id).Select(x => x.ItemNoticeDateActive).FirstOrDefault();
if (EXPDT == true)
{
DTExprVL = "1";
}
else
{
DTExprVL = "0";
}
var CusList = db.TBLColecteItems.Include(t => t.TBLItem).Include(t => t.TBLItem1).Where(s => s.TMainItemID == id).Select(x => new
{
Id = x.TBLItem1.ItemID,
Name = x.TBLItem1.ItemName,
Unite = x.TUnite,
UnitName = x.TBLUnite.UnitesName,
UnTOT = x.TUnTOT,
Count = x.TCount,
Price = x.TPrice,
Total = x.TTotal,
ITPrice = ITMPrice,
ITDTEXP = DTExprVL
}).ToList();
return Json(CusList, JsonRequestBehavior.AllowGet);
}
just Change the Parmeters

How to Bind ViewModal to Dropdownlist in asp.net mvc

Suppose that we have a doctor with its weekday schedule. I want to display this weekday schedule and update it in the view. My WeekDay class looks like this:
public class WeekDay
{
public int Id { get; set; }
public string DayName { get; set; }
public string EightTen { get; set; }
public string TenTwelve { get; set; }
public string TwelveFourteen { get; set; }
public string FourteenSixteen { get; set; }
public int DoctorId { get; set; }
public Doctor Doctor { get; set; }
}
And Here is the ViewModel I've created to pass it to the view:
public class DoctorWeekDaysViewModel
{
public DoctorWeekDaysViewModel()
{
WeekDays = new List<WeekDay>();
}
public DoctorWeekDaysViewModel(IEnumerable<WeekDay> weekDay = null)
{
WeekDays = weekDay ?? new List<WeekDay>();
}
public IEnumerable<WeekDay> WeekDays { get; set; }
}
In the controller, the corresponding action will return 6 objects of WeekDay Class. In this situation, I've converted it into list and created a ViewModel and returned the ViewModel to the view:
public ActionResult EditTimeTable()
{
string username = Session["Username"].ToString();
var doctor = _context.Doctors.FirstOrDefault(a => a.Username.Equals(username));
var weekdays = _context.WeekDays.Include(a => a.Doctor).Where(a => a.DoctorId.Equals(doctor.Id)).ToList();
DoctorWeekDaysViewModel viewModel = new DoctorWeekDaysViewModel(weekdays);
return View(viewModel);
}
Then In the view I've took it and showed it this way:
#model ClinicWebApp.Models.ViewModel.DoctorWeekDaysViewModel
#using (Html.BeginForm(FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="calendar-main mb-30">
<div class="row">
#{
var listItems = new List<ListItem> {
new ListItem { Text = "استراحت", Value = "استراحت" },
new ListItem { Text = "ویزیت", Value = "ویزیت" },
new ListItem { Text = "نهار", Value = "نهار" },
new ListItem { Text = "صبحانه", Value = "صبحانه" },
new ListItem { Text = "خالی", Value = "خالی" },
};
}
<table class="mb-0 table table-hover table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">8 تا 10</th>
<th scope="col">10 تا 12</th>
<th scope="col">12 تا 14</th>
<th scope="col">14 تا 16</th>
</tr>
</thead>
<tbody>
#foreach (var weekday in Model.WeekDays)
{
<tr>
<th scope="row">#weekday.DayName</th>
<td>
#Html.DropDownListFor(model => weekday.EightTen, new SelectList(listItems), weekday.EightTen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(model => weekday.TenTwelve, new SelectList(listItems), weekday.TenTwelve, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(model => weekday.TwelveFourteen, new SelectList(listItems), weekday.TwelveFourteen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(model => weekday.FourteenSixteen, new SelectList(listItems), weekday.FourteenSixteen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<footer class="bg-white p-4">
<div class="row">
<div class="col-md-12">
<div class="pull-left">
<button type="submit" class="btn btn-primary">save</button>
</div>
</div>
</div>
</footer>
}
The Output of This View is fine and everything is shown correctly:
Actual Html Output
But when I change the dropdownlist values and submit it to the corresponding action, The ViewModel will be null. here is my ActionResult:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditTimeTable(DoctorWeekDaysViewModel viewModel)
{
...
}
I think the problem is my viewModel or dropdownlist that configured incorrectly. please help me to solve this problem.
You should custome Name of dropdown to make it correctly.
#Html.DropDownListFor(model => weekday.EightTen, new SelectList(listItems), weekday.EightTen, new {#class = "custom-select my-1 mr-sm-2", Name = "WeekDays[0].EightTen"})
Note: Name = WeekDays[0].EightTen
0: Index, increase for each loop.
EightTen: Name of each property follow up your dropdown accordingly.
Instead of using foreach, use for loop to iterate the weekday list.
#for (var weekday=0; weekday < Model.WeekDays.Count; weekday++)
{
<tr>
<th scope="row">#weekday.DayName</th>
<td>
#Html.DropDownListFor(m => m.WeekDays.ElementAt(weekday).EightTen, new SelectList(listItems), Model.WeekDays.ElementAt(weekday).EightTen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(m => m.WeekDays.ElementAt(weekday).TenTwelve, new SelectList(listItems), Model.WeekDays.ElementAt(weekday).TenTwelve, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(m => m.WeekDays.ElementAt(weekday).TwelveFourteen, new SelectList(listItems), Model.WeekDays.ElementAt(weekday).TwelveFourteen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
<td>
#Html.DropDownListFor(m => m.WeekDays.ElementAt(weekday).FourteenSixteen, new SelectList(listItems), Model.WeekDays.ElementAt(weekday).FourteenSixteen, new {#class = "custom-select my-1 mr-sm-2"})
</td>
</tr>
}

how to insert multiple rows database in asp.net core 2.1

I have one table which contains static data with 5 columns and 4 rows. I have another table which would accept input based on static table. I am trying to build a view with table where all field from static Db table is displayed and few text box so that user could fill in the data. But when I click on submit button no data is saved in second table. Can anyone help me with this. How could I submit multiple rows to database based on static database table.
Following are the codes:
View Model:
public class DBM2BillingViewModel
{
public List<DatabaseM2> databaseM2List { get; set; }
[Display(Name = "Items")]
public string Name { get; set; }
[Display(Name = "PO Item No.")]
public int POItemNo { get; set; }
[Display(Name = "Date of Effect")]
public DateTime DateOfEffect { get; set; }
[Display(Name = "Baseline Volume")]
public float baselineVolume { get; set; }
[Display(Name = "Billing Month")]
public string BillingMonth { get; set; }
[Display(Name = "Monthly Device Count")]
public float DeviceCount { get; set; }
}
**Controller**
//Get Method
public IActionResult Create()
{
DBM2BillingViewModel dbm2billingVM = new DBM2BillingViewModel();
dbm2billingVM.databaseM2List = _context.databaseM2s.ToList();
return View(dbm2billingVM);
}
//Post Method
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(DBM2BillingViewModel model)
{
foreach(var dbm2 in model.databaseM2List)
{
DeviceBilling addModel = new DeviceBilling();
addModel.Name = dbm2.Name;
addModel.TrackName = "Database M2";
addModel.POItemNo = dbm2.POItemNo;
addModel.DateOfEffect = dbm2.DateOfEffect;
addModel.baselineVolume = dbm2.BaselineVolume;
addModel.BillingMonth = model.BillingMonth;
addModel.DeviceCount = model.DeviceCount;
_context.deviceBillings.Add(addModel);
}
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
enter code here
View
#model FinancantPro.Models.DeviceCountModel.DBM2BillingViewModel
#{
ViewData["Title"] = "Create";
}
<div class="container">
<table class="table table-striped border">
<thead>
<tr class="table-info">
<th>#Html.DisplayName("Item Name")</th>
<th>#Html.DisplayName("PO Item No#")</th>
<th>#Html.DisplayName("Date Of Effect")</th>
<th>#Html.DisplayName("Baseline Volume")</th>
<th>#Html.DisplayName("Billing Month")</th>
<th>#Html.DisplayName("Device Count")</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.databaseM2List.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(d => d.databaseM2List[i].Id)
#Html.DisplayFor(d => d.databaseM2List[i].Name)
</td>
<td>
#Html.DisplayFor(d => d.databaseM2List[i].POItemNo)
</td>
<td>
#Html.DisplayFor(d => d.databaseM2List[i].DateOfEffect)
</td>
<td>
#Html.DisplayFor(d => d.databaseM2List[i].BaselineVolume)
</td>
<td>
#Html.TextBoxFor(d => d.BillingMonth, new { #class = "form-control" })
</td>
<td>
#Html.TextBoxFor(d => d.DeviceCount, new { #class = "form-control" })
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Create" />
</div>
</div>
**************************
If I add list in View I am not able to resolve the Model

Posted model is empty

I have a ViewModel as following
public class MetalStockAddVM
{
public MetalStock MetalStock { get; set; }
public MetalStockAddVM()
{
this.MetalStock=new MetalStock();
}
}
Here is My controller
public class MetalStockController : Controller
{
private readonly IMetalStockRepository iMetalStockRepository;
public MetalStockController(IMetalStockRepository iMetalStockRepository)
{
this.iMetalStockRepository = iMetalStockRepository;
}
// GET: MetalStock
[HttpGet]
public ActionResult AddMetalStock()
{
MetalStockAddVM addVm=new MetalStockAddVM();
return View(addVm);
}
[HttpPost]
public ActionResult AddMetalStock([Bind(Include = "MetalStock")]MetalStockAddVM metalStock)
{
MetalStockDto metalStockDto = new MetalStockDto();
metalStockDto = Mapper.Map<MetalStock, MetalStockDto>(metalStock.MetalStock);
iMetalStockRepository.Insert(metalStockDto);
return RedirectToAction("Index","Home") ;
}
}
Here is my view
#model LearningSpike.Models.ViewModels.MetalStockAddVM
#using (Html.BeginForm("AddMetalStock","MetalStock",FormMethod.Post))
{
<table>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.MetalId)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.MetalId)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.GlobalMaterialId)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.GlobalMaterialId)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.Length)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.Length)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.ColourCode)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.ColourCode)
</td>
</tr>
<tr>
<th>
#Html.LabelFor(m => m.MetalStock.QuantityInStock)
</th>
<td>
#Html.EditorFor(m => m.MetalStock.QuantityInStock)
</td>
</tr>
</table>
<input type="submit" value="Create"/>
}
When I post the model that is passed to the controller action method is empty .
Please tell me what I'm doing wrong? I am creating an architectural spike for the first time so I can learn a lot.Thus its my first time implementing all heavy stuff (DI , DTO's , REpositories etc.) . I am still struggling with putting things in right places.
Thanks!
Cheers!
First remove [Bind(Include = "MetalStock")] and second rename metalStock to some something like metalStockVm and see does it works or not.
[HttpPost]
public ActionResult AddMetalStock(MetalStockAddVM metalStockVm)
Please try the below one
change your model code like below
public class MetalStockAddVM
{
public MetalStock MetalStock { get; set; }
}
And then change you Action method code for HTTPPOST in AddMetalStock as below
[HttpPost]
public ActionResult AddMetalStock(MetalStockAddVM metalStock)
{
MetalStockDto metalStockDto = new MetalStockDto();
metalStockDto = Mapper.Map<MetalStock, MetalStockDto>(metalStock.MetalStock);
iMetalStockRepository.Insert(metalStockDto);
return RedirectToAction("Index","Home") ;
}

ASP.Net MVC Posted form values not mapping back onto viewmodel in controller

My ViewModel is:
public class ObjectiveVM
{
public string DateSelected { get; set; }
public List<string> DatePeriod { get; set; }
public IList<ObList> obList { get; set; }
public class ObList
{
public int ObjectiveId { get; set; }
public int AnalystId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string AnalystName { get; set; }
public bool Include { get; set; }
}
}
This is passed to the view, populated as expected - and displays correctly in the view.
My problem is when it is posted back to the controller. My controller code to accept it back is:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Analyst(ObjectiveVM ovm)
ovm.obList is always showing as null:
My View html is:
#model Objectives.ViewModels.ObjectiveVM
#{
ViewBag.Title = "Analyst";
}
<h2>Copy Objectives for Analyst</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Objective</legend>
#Html.DropDownListFor(model => model.DateSelected, new SelectList(Model.DatePeriod))
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.obList[0].Include)
</th>
<th>
#Html.DisplayNameFor(model => model.obList[0].AnalystName)
</th>
<th>
#Html.DisplayNameFor(model => model.obList[0].Title)
</th>
<th>
#Html.DisplayNameFor(model => model.obList[0].Description)
</th>
</tr>
#foreach (var obList in Model.obList)
{
<tr>
<td>
#Html.HiddenFor(modelItem => obList.ObjectiveId)
#Html.HiddenFor(modelItem => obList.AnalystId)
#Html.HiddenFor(modelItem => obList.Title)
#Html.HiddenFor(modelItem => obList.Description)
#Html.CheckBoxFor(modelItem => obList.Include)
</td>
<td>
#Html.DisplayFor(modelItem => obList.AnalystName)
</td>
<td>
#Html.DisplayFor(modelItem => obList.Title)
</td>
<td>
#Html.DisplayFor(modelItem => obList.Description)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Copy Selected Objectives" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Looking in Developer Tools at the Posted form values, they appear to be ok:
Can anyone see any reason the posted form values, are not mapping back onto my viewmodel in the Controller HTTP post?
Thank you, Mark
You need to use a for...loop here, not a foreach....loop.
#for (int idx = 0;idx < Model.obList.Count;idx++){
#Html.HiddenFor(_ => Model.obList[idx].ObjectiveId)
// ... etc....
}
Without the indexer (idx), the model binder will not know how to bind the values back to the right collection item.
When working with collections in my views, I typically write out my markup without the use of helpers:
#for (int i = 0;i < Model.obList.Count();i++){
<input type="hidden" name="ObList[#i].ObjectiveId" id="ObList[#i].ObjectiveId" value="#ObList[i].ObjectiveId" />
<input type="hidden" name="ObList[#i].AnalystId" id="ObList[#i].AnalystId" value="#ObList[i].AnalystId" />
...
}
This will conform to the wire format the model binder expects, and will slot your values into your ViewModel: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

Resources