ASP.NET MVC 4 - razor empty post in for loop - c#

I have the following code in razor:
#for (int i = 0; i < Model.Count; i++)
{
using (Html.BeginForm("Bonnen", "Bon"))
{
<tr>
<td> #Html.TextBoxFor(model => Model[i].Id)</td>
<td>#Html.DisplayFor(model => Model[i].Date)</td>
<td>#Html.DisplayFor(model => Model[i].Description)</td>
<td><button type="submit" value="Details" class="btn btn-info">Details</button></td>
</tr>
}
}
When i post the data to the controller it becomes empty.
I've already seen a question where it said you can't use a foreach loop here.
On the website itself it does show all the data, but it won't give it to the controller.
Controller:
[HttpPost]
public ActionResult Bonnen(Bon bon)
{
return RedirectToAction("Details", "Bon", bon);
}
Model:
public int Id { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }

Your code needs to be inside the form and button type "submit" wont work. You need to use input type "submit". See code below:
#using (Html.BeginForm("Bonnen", "Bon"))
{
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td> #Html.TextBoxFor(model => Model[i].Id)</td>
<td>#Html.DisplayFor(model => Model[i].Date)</td>
<td>#Html.DisplayFor(model => Model[i].Description)</td>
<td><input type="submit" value="Details" class="btn btn-info"/></td>
</tr>
}
}

#using (Html.BeginForm("Bonnen", "Bon",FormMethod.Post))
{
#foreach (var item in Model)
{
<tr>
<td> #Html.TextBoxFor(model => item.Id)</td>
<td>#Html.DisplayFor(model => item.Date)</td>
<td>#Html.DisplayFor(model => item.Description)</td>
</tr>
}
<input type="submit" value="Details" class="btn btn-info"/>
}
[HttpPost]
public ActionResult Bonnen(int[] Id ,DateTime[] Date,string[] Description)
{
return RedirectToAction("Details", "Bon", bon);
}

Try the following code
#for (int i = 0; i < Model.Count; i++)
{
using (Html.BeginForm("Bonnen", "Bon"))
{
<tr>
<td> #Html.TextBox("Id", Model[i].Id)</td>
<td>#Html.Display("Date", Model[i].Date)</td>
<td>#Html.Display("Description", Model[i].Description)</td>
<td><button type="submit" value="Details" class="btn btn-info">Details</button></td>
</tr>
}
}
If you want the values of Date and Description too in controller then change them from Display to Editor.

managed to solve it with a foreach loop.
#using (Html.BeginForm())
{
<h2>Bon</h2>
<input class="form-control" id="myInput" type="text" placeholder="Zoek..." />
<br />
<table style="width: 100%">
<thead>
<tr>
<th>Id</th>
<th>Datum</th>
<th>Boodschappen</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#using (Html.BeginForm("Bon", "Bon", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ActionLink("Details", "Details", "Bon", new { id = item.Id }, null)
}
</td>
</tr>
}
</tbody>
</table>
}

Related

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted

I got the following entity framework error while trying to save edit page
"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded."
This is my EDIT controller
[HttpPost]
public ActionResult Edit(RESULT results)
{
if (ModelState.IsValid)
{
_context.Entry(results).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Details");
}
return View(results);
}
I need to update multiple rows (Result column value only)
and I checked the solutions in the site
and I added the primary key ID column see the image :
this is the EDIT view code :
<table class="table">
<tr>
<td>
#Html.DisplayNameFor(model => model.FirstOrDefault().ID)
</td>
<td>
#Html.DisplayNameFor(model => model.FirstOrDefault().custid)
</td>
<td>
#Html.DisplayNameFor(model => model.FirstOrDefault().TESTID)
</td>
<td>
#Html.DisplayNameFor(model => model.FirstOrDefault().LabTest.TestName)
</td>
<td>
#Html.DisplayNameFor(model => model.FirstOrDefault().RESULT1)
</td>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
#Html.TextBox("RESULTS[" + #i + "].ID", Model[i].ID, new { #readonly = "readonly" })
</td>
<td>
#Html.TextBox("RESULTS[" + #i + "].custid", Model[i].custid, new { #readonly = "readonly" })
</td>
<td>
#Html.TextBox("RESULTS[" + #i + "].TESTID", Model[i].TESTID, new { #readonly = "readonly" })
</td>
<td>
#Html.TextBox("LabTest[" + #i + "].TestName", Model[i].LabTest.TestName, new { #readonly = "readonly" })
</td>
<td>
#Html.TextBox("RESULTS[" + #i + "].RESULT1", Model[i].RESULT1)
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10" style="margin:100px;">
<input type="submit" value="Save" class="btn btn-danger" />
</div>
</div>
What is the missing in my code please I need your help ?
On your Controller Action, the parameter should be the List. You need to iterate and update.
[HttpPost]
public ActionResult Edit(List<RESULT> results)
{
if (ModelState.IsValid)
{
foreach(var item in results)
{
var model =_context.Find(item.ID);
if(model != null) {
model.TestID = item.TestID;
model.TestName = item.TestName;
//update columns you want to update
_context.SaveChanges();
}
}
ViewBag.Message = "Updated Successfully";
return RedirectToAction("Details");
}
return View(results);
}
View
#if(ViewBag.Message != null){
#ViewBag.Message
}
I found the solution I changed the code as the following :
Edit controller code :
public ActionResult Edit(List<RESULT> list)
{
if (ModelState.IsValid)
{
using (db_Entities db = new db_Entities())
{
foreach (var i in list)
{
var c = db.RESULTS.Where(a => a.ID.Equals(i.ID)).FirstOrDefault();
if (c != null)
{
c.RESULT1 = i.RESULT1;
}
}
db.SaveChanges();
}
// ViewBag.Message("Updated Successfully");
return View(list);
}
else
{
// ViewBag.Message("Failed ! Please try again");
return View(list);
}
}
EDIT view code :
<table class="table">
<tr>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().custid) </td>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().TESTID) </td>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().LabTest.TestName) </td>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().APPROVED_BY) </td>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().APPROVED_DATE) </td>
<td> #Html.DisplayNameFor(model => model.FirstOrDefault().RESULT1) </td>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.HiddenFor(model => model[i].ID)</td>
<td>#Html.EditorFor(model => model[i].custid)</td>
<td>#Html.EditorFor(model => model[i].TESTID)</td>
<td>#Html.EditorFor(model => model[i].LabTest.TestName)</td>
<td>#Html.EditorFor(model => model[i].APPROVED_BY)</td>
<td>#Html.EditorFor(model => model[i].APPROVED_DATE)</td>
<td>#Html.EditorFor(model => model[i].RESULT1)</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10" style="margin:100px;">
<input type="submit" value="Save" class="btn btn-danger" />
</div>
</div>
#*<p style="color:green;font-size:16px;">
#ViewBag.Message
</p>*#
Modified based on #Ram Anugandula Logic we can save data after completion of loop because objects are reference type and we can save the after modify entire object
[HttpPost]
public ActionResult Edit(List<RESULT> Input)
{
if (ModelState.IsValid)
{
foreach(var item in Input)
{
var model =_context.Yourdbsetentity.Find(item.ID);
If(model!=null){
model.TestID = item.TestID;
model.TestName = item.TestName;
//update columns you want to update
}else{
model=new RESULT();
model.TestID = item.TestID;
model.TestName = item.TestName;
//Create columns you want to update
_context.Yourdbsetentity.add(model)
}
}
_context.SaveChanges();
return RedirectToAction("Details");
}
return View(results);
}

C# how to remove a current row from the table by button click

I am trying to remove a table row from the table:
<tbody>
#foreach (var task in Model)
{
<tr>
<td>
#task.time
</td>
<td>
#task.descripiton
</td>
<td>
#task.duedo
</td>
<td>
<form action="#Url.Action("Remove")" method="POST"><input type="submit" value="Delete" /></form>
</td>
</tr>
}
</tbody>
How could I send the index of the row to the controller?
public ActionResult Remove()
{
Task.RemoveAt();
return RedirectToAction("Index");
}
The row where I pressed the button would get removed.
Change view code to:
<tbody>
#{
var idx = 0;
foreach (var task in Model)
{
<tr>
<td>
#task.time
</td>
<td>
#task.descripiton
</td>
<td>
#task.duedo
</td>
<td>
<form action="#Url.Action("Remove", "YourControllerName", new { id = idx++ })" method="POST">
<input type="submit" value="Delete" />
</form>
</td>
</tr>
}
}
</tbody>
Then, change Remove method to:
public ActionResult Remove(int id)
{
Task.RemoveAt(id);
return RedirectToAction("Index");
}

Can I modify multiple items in a BeginForm section in a Razor/MVC view [duplicate]

This question already has answers here:
Multiple checkboxes in razor (using foreach)
(3 answers)
Closed 7 years ago.
I would like to edit a list of items and save them all together in the same submit. Is it possible? If so, how?
I have the following piece of code, but it does not give the wanted result. Or otherwise I don't know what to write for the counterpart in the controller.
#using (Html.BeginForm("Save", "MyController", FormMethod.Post))
{
<fieldset>
<table class="table table-striped table-hover ">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Datum</th>
<th>NewValue</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.HiddenFor(modelItem => item.Id)
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Value)
</td>
<td>
#Html.TextBoxFor(modelItem => item.Value)
</td>
</tr>
}
</tbody>
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Update Thanks to #Jonesopolis I came up with this working solution
#using (Html.BeginForm("Save", "MyController", FormMethod.Post))
{
<fieldset>
<table class="table table-striped table-hover ">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Datum</th>
<th>NewValue</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(modelItem => modelItem[i].Id)
#Html.DisplayFor(modelItem => modelItem[i].Name)
</td>
<td>
#Html.DisplayFor(modelItem => modelItem[i].Value)
</td>
<td>
#Html.TextBoxFor(modelItem => modelItem[i].Value)
</td>
</tr>
}
</tbody>
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
For MyController
public class MyController : Controller
{
[HttpPost]
public ActionResult Save(IEnumerable<NameDoesNotMatter> newValues)
{
...
}
}
public class NameDoesNotMatter
{
public int Id { get; set; }
public decimal? Value { get; set; }
}
Now see if i can work out the thing with the templates. The link of #StephenMuecke should be sufficient
Update 2
Well that's wasn't that hard the code is now
#using (Html.BeginForm("Save", "MyController", FormMethod.Post))
{
<fieldset>
<table class="table table-striped table-hover ">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Datum</th>
<th>NewValue</th>
</tr>
</thead>
<tbody>
#Html.EditorForModel()
</tbody>
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
And for Views/Shared/EditorTemplates/TypeOfModel.cshtml
#model TypeOfModel
<tr>
<td>
#Html.HiddenFor(item => item.Id)
#Html.DisplayFor(item => item.Name)
</td>
<td>
#Html.DisplayFor(item => item.Value)
</td>
<td>
#Html.TextBoxFor(item => item.Value)
</td>
</tr>
The controller remains the same
When you just show items using a for loop then the naming convention used in the resulting html tag doesn't match up with what MVC is expecting when it binds the model upon form submit. The easiest way to fix this is to use #Html.EditorFor and custom editor templates. Here are a couple of examples:
ASP.NET MVC DisplayTemplate and EditorTemplates for Entity Framework DbGeography Spatial Types
Extending Editor Templates for ASP.NET MVC

select all tr of a table and send it to the controller using checkbox , in MVC 4

I want to use the Check box for selecting multiple users and sending the result to my controller.
At first I was only sending the number of mobile users to the controller but it became necessary to send more than the number, I need number and name user, my controller and my view are as follows:
Would somehow send the number and name for example?
#using (Html.BeginForm("Enviar", "Home")) {
<table id="myTable">
<thead>
<tr>
<th>
<input type="checkbox" />
</th>
<th>#Html.DisplayName("Nome")</th>
<th>#Html.DisplayName("CANCELADO")</th>
<th>#Html.DisplayName("Numero")</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
<input type="checkbox" name="CELULAR" value="#item.CELULAR" />
</td>
<td name="Nome">#Html.DisplayFor(modelItem => item.NOME)</td>
<td name="Email">#Html.DisplayFor(modelItem => item.CANCELADO)</td>
<td name="Celular" value="#item.CELULAR">#Html.DisplayFor(modelItem => item.CELULAR)</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Selecionar"/>
}
The controller that receives:
[HttpPost]
public ActionResult Enviar(String[] celular) {
.....
return View();
}
When posting collections, you must index them correctly. Therfore, you must use a for loop instead of a foreach.
Also, why does your HttpPost take a String[] and not your Model? First change that to be your model type.
Assuming your model is: #model List<YourType>
Change your HttpPost to take that:
[HttpPost]
public ActionResult Enviar(List<YourType> model) {
.....
return View();
}
Now we'll rewrite your foreach into a for and use the CheckBoxFor helper. Also, add HiddenFor fields for any properties you want to see on post:
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
#Html.CheckBoxFor(m => m[i].CELULAR)
</td>
<td name="Nome">
#Html.HiddenFor(m => m[i].NOME)
#Html.DisplayFor(m => m[i].NOME)
</td>
<td name="Email">
#Html.HiddenFor(m => m[i].CANCELADO)
#Html.DisplayFor(m => m[i].CANCELADO)
</td>
<td name="Celular" value="#m[i].CELULAR">
#Html.DisplayFor(m => m[i].CELULAR)
</td>
</tr>
}

Why httpPost model always null?

I have get and post controller.
But by httpPost comtroller passing model parameter values are null.
Why my httpPost model parameter values always null ??
[HttpGet]
public ActionResult HireItem()
{
var HireItemListModel = new HireItemModel();
HireItemListModel = new HireItemModel()
{
first_name = Session["first_name"].ToString(),
middle_name = Session["middle_name"].ToString(),
last_name = Session["last_name"].ToString(),
ceremony_date = Session["ceremony_date"].ToString(),
};
var product = _productService.GetAllHireProducts();
if (product.Count != 0)
{
foreach (var proValue in product)
{
var productVarSeparateList = _productService.GetHireProductVariantsByProductIds(proValue.Id, false);
foreach (var HireProSep in productVarSeparateList)
{
var productVarSeparateModel = new HireItemModel.HireItemSeparatetModel()
{
pname = HireProSep.Name,
price =HireProSep.Price,
pId=HireProSep.Id,
};
HireItemListModel.HireItemSeparatetlist.Add(productVarSeparateModel);
}
var productVarSetList = _productService.GetHireProductVariantsByProductIds(proValue.Id, true);
foreach (var HireProset in productVarSetList)
{
var productVarListset = new HireItemModel.HireItemSetModel()
{
pname = HireProset.Name,
price = HireProset.Price,
pId = HireProset.Id,
};
HireItemListModel.HireItemSetList.Add(productVarListset);
}
}
}
return View(HireItemListModel);
}
This controller HireItemModel model parameter values are null. WHY??
[HttpPost,ActionName("HireItem")]
public ActionResult HireItem(string submitB, FormCollection formCollection, HireItemModel HireItemListModel)
{
var graduandList = _graduandService.GetGraduandBynameCeremony(HireItemListModel.ceremony_id, HireItemListModel.first_name, HireItemListModel.middle_name, HireItemListModel.last_name);
foreach (var graduand in graduandList)
{
graduand.height = HireItemListModel.height;
graduand.head_circumference = HireItemListModel.head_circumferenc;
_graduandService.Updategraduand(graduand);
}
this is my view.
#model HireItemModel
#using (Html.BeginForm())
{
<table >
<tr>
<td >
Ceremony :
</td>
<td>
Ceremony at #Model.ceremony_date
</td>
</tr>
<tr>
<td >
Name :
</td>
<td >
#Model.first_name #Model.middle_name #Model.last_name
</td>
</tr>
</table>
<div id="HItemType_1">
#Html.CheckBox("HItemType")
#*<input type="checkbox" name="test" value="test" id="HItemType" />*#
<label> Academic Dress Set</label>
</div>
<div id="HsetItem">
#Html.Partial("_LoadHireSetItem", #Model.HireItemSetList)
</div>
<div id="HseparateItem">
#Html.Partial("_LoadHireSeparateItem", #Model.HireItemSeparatetlist)
</div>
<table >
<tr>
<td colspan="2">
Please tell us your measurement:
</td>
</tr>
<tr>
<td >
Height (in cm):
</td>
<td>
#Html.EditorFor(model => model.height)
</td>
</tr>
<tr>
<td >
Head circumference (in cm):
</td>
<td >
#Html.EditorFor(model => model.head_circumferenc)
</td>
</tr>
</table>
<div>
<input class="productlistaddtocartbutton" type="submit" value="Add to cart" name="submitB" id="btnaddtocart"/>
</div>
}
thanks.
Make sure inside your view you have input fields for all values that you intend to use in your POST action. For example if you want to use the ceremony_id, first_name, middle_name, and last_name properties you need to include them:
#Html.HiddenFor(model => model.ceremony_id)
#Html.HiddenFor(model => model.first_name)
#Html.HiddenFor(model => model.middle_name)
#Html.HiddenFor(model => model.last_name)
You could use hidden fields if the user is not supposed to modify their values but you could also have used text fields depending on your requirements.

Categories