I wanna update a list of item in edit page,
a user pass to edit page and update request for a list of question,
a model for request is ready to use,
edit.cshtml is like
#using (Html.BeginForm()){
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
#foreach (var item in Model.Requesttables)
{
<div class="editor-label">
#Html.LabelFor(modelItem => item.request)
</div>
<div class="editor-field">
#Html.EditorFor(modelItem => item.request)
#Html.ValidationMessageFor(modelItem => item.request)
</div>
<p>
<input type="submit" value="Save" />
</p>
}
</fieldset>
}
how the controler will be??
public ActionResult Edit(List <Requesttable> requestlist)
{//some logic here!}
If I understand it right, you want to see the controller. First I think that there is something wrong with your controller signature. It should be like this:
public ActionResult Edit(int id)
{
//search the object, no matter what it is - as long as it is form database by id
var db = new DbContext();
var yourRequestedList=db.Find(id); //or something like that, see linq for the correct sintax
yourRequestedList = objectThatWasEdited;
}
I hope this helps you out, and don't forget to refactor. My cod is not a good practice, you do not instatiate the db inside of a controller method.
Related
I apologize if the heading is not very clear.
So, what I want to do is following.
I have a model class called "Class" that contains a list of "Students". I have a view that shows a checklist of Students. From that checklist I want to pass the selected students back to controller, where I will update the Database and my class will have new students and the added students will have a new class.
Here is what I have done so far but now I am stuck. Thanks in advance.
These are my controller actions
[HttpGet]
public ActionResult AddStudents(int? id)
{
List<Student> students = (from std in db.Students
where std.St_cl_fk_id == null select std).ToList();
//ViewBag.students = students;
return View("Add_Students",students);
}
[HttpPost, ActionName("AddStudents")]
public ActionResult AddStudentsPost(int? id,List<Student> students)
{
if(ModelState.IsValid)
{
var temp = id;
Class #class = db.Classes.Find(id);
foreach (var item in students)
{
if (Request.Form[item.St_id.ToString()] != null)
{
#class.Students.Add(item);
}
}
db.Entry(#class).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Classes");
}
return View("Add_Student");
}
Here is my view
#model IEnumerable<GMASchoolProject.Models.Student>
#{
ViewBag.Title = "Add_Students";
}
<h4>Student List</h4>
#using (Html.BeginForm())
{
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
Check Students
</div>
<div class="form-group">
<div class="col-md-10">
<table>
#foreach (var std in Model)
{
<tr>
<td><input type="checkbox" name="#std.St_id" value="#std.IsSelected" /></td>
<td>#Html.Label((string)std.St_name)</td>
</tr>
}
</table>
</div>
</div>
<div class="form-group" style="margin:15px,0,15px,0;">
<div class="col-md-offset-5 col-md-2">
<input type="submit" value="Add Students" class="btn btn-primary" />
</div>
</div>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn btn-danger" })
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Please let me know if there is anything else that I am doing wrong, I am a newbie in this area. THanks
First, instead of binding the view to a list of students, bind the model to your Class object that has a list of students in it. That way, when you submit (post), you are sending the whole Model object into the Controller.
Change your AddStudentsPost method to take in Class object and do your logic there.
Finally, change the name of the "Class" object to something else, such as, "Course". Class should be reserved for actual classes so not to cause confusion.
You aren't far off, so keep going
I have a page which displays fields from 2 different models. To ensure this works I am using Tuple<> to display them both and have tested to ensure data shows which it does. The issue I had was when I submitted the form to update the database, nothing was passed and the record was wiped clean. Please advise me on how to proceed. I have shortened fields shown to make the post shorter.
View
#model Tuple<CommunityParkletDashboard.Models.COMMUNITY_PARKLET_APPLICATION, CommunityParkletDashboard.ViewModels.CPDashboardModel>
<input type="button" value="Back" onclick="location.href='#Url.Action("CPDashboard", "CPDashboard")'" />
#using (Html.BeginForm("EditCP", "CPDashboard", FormMethod.Post))
{
<p>
Reference Number:
#Html.DisplayFor(i => i.Item1.REF_NUMBER)
</p>
<p>
Name:
#Html.DisplayFor(i => i.Item1.NAME)
</p>
<p>
Notes:
#Html.TextAreaFor(i => i.Item1.NOTES)
</p>
foreach (var item in Model.Item2.lParkletApplicationDtos)
{
<p>
Title:
#Html.DisplayFor(i => item.ParkletTitle)
</p>
<br />
<input type="submit" value="Save" />
}
}
Controller
[HttpPost]
public ActionResult EditCP(COMMUNITY_PARKLET_APPLICATION cpa, int id)
{
_context.UpdateParkletApplication(cpa, id);
return RedirectToAction("CPDashboard");
}
UpdateParkletApplication() is just a method which runs some SQL script to update the data using the model and ID so associate the record with, all this was working fine before I introduced second model. Thanks in advance.
Because you create one form and use foreach form item2 it pass all item in item2.
You can use foreach and inside of it use begin form .
foreach (var item in Model.Item2.lParkletApplicationDtos)
{
#using (Html.BeginForm("EditCP", "CPDashboard", FormMethod.Post))
{
<p>
Reference Number:
#Html.DisplayFor(i => i.Item1.REF_NUMBER)
</p>
<p>
Name:
#Html.DisplayFor(i => i.Item1.NAME)
</p>
<p>
Notes:
#Html.TextAreaFor(i => i.Item1.NOTES)
</p>
<p>
Title:
#Html.DisplayFor(i => item.ParkletTitle)
</p>
<br />
<input type="submit" value="Save" />
}
}
Does it pass id ???
#Html.DisplayFor(i => item.ParkletTitle)
As your view contains model as
#model MyCustomModel
Following method should like this and then access cpa.Item1 just you did in view.
[HttpPost]
public ActionResult EditCP(MyCustomModel cpa, int id)
{
_context.UpdateParkletApplication(cpa, id);
return RedirectToAction("CPDashboard");
}
Your Model Class
public class MyCustomModel
{
public CommunityParkletDashboard.Models.COMMUNITY_PARKLET_APPLICATION Item1 {get;set;}
public CommunityParkletDashboard.ViewModels.CPDashboardModel Item2 {get;set;}
}
Ultimately you have to think like how is model constructed. Even if in View you keep Tuple then you can use above answer.
When the button is pressed it states that the model is invalid as fields are empty.
when looking at the model all fields are empty or null. anyone know how to solve this issue, thanks
Home Controller
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> createOrderLine(Product models)
{
if (ModelState.IsValid)
{
db.OrderLines.Add(new OrderLine
{
productId = models.productId,
productColour = models.productColour,
productDescription = models.productDescription,
productName = models.productName,
productPrice = models.productPrice,
productStock = models.productStock,
//QuantityOrdered = quantityOrdered
});
db.SaveChanges();
return RedirectToAction("Index", "OrderLines");
}
else return RedirectToAction("Index", "Home");
}
Home Index - Displays the product information to the screen
#foreach (var product in Model)
{
using (Html.BeginForm("createOrderLine", "Home", FormMethod.Post, new {
#class = "form-horizontal", role = "form" }))
{
<div class="row">
<div class="blog col-md-6">
<div>
<h1>Product Name</h1>
<h2>#product.productName</h2>
<div>
<h3>Product Description</h3>
<h6><i>#product.productDescription</i></h6>
<br />
<h3>Product Price</h3>
<td>#product.productPrice </td>
<br />
<h1>Product colour</h1>
<td>#product.productColour</td>
<div></div>
<br />
<br />
#Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-buy" value="Add to cart" onclick="btnbuy_Click" />
</div>
</div>
</div>
</div>
<br />
</div>
</div>
}
}
the problem is that none of your field are linked to the model they only display it so to fix this
you can simply add a hiddenfor field that links the product id in your page like so for each of your product :
#Html.HiddenFor(product.Id)
then fill the rest of the informations you need with the id that is gonna be passed to your controller as a parameter
exemple :
public ActionResult createorderline(Product ProductToAdd)
{
// add your product or do your treatment
}
I do not quite understand what are you trying to do, but Louis is right. If you are trying to pass values back, you have to #Html.EditorFor() or some other ways to pass back information to the server.
You could also use #Html.HiddenFor(product.Id) then inside your Actionmethod call the database to get the rest of the info regarding your product or you could use JQuery as well.
In this case I would only use the #Html.HiddenFor(product.Id) and have a static helper method that will map your orderline class from the DB.
public static Product GetProductById(int productId){
return db.Products.FirstOrDefault(x => x.Id == productId);
}
But again you could just add the FirstOrDefault() line inside your controller as you not mapping from a ViewModel to a business Model.
I have a controller with 2 actions: 1 for displaying a form and 2nd for processing the submitted form. Smth like this:
public ActionResult Create()
{
TestModel model = new TestModel() { Value1 = "aaa" };
return View(model);
}
[HttpPost]
public ActionResult Create(TestModel model)
{
model.Value2 = "bbb";
return View(model);
}
As you can see I pre-populate Value1 with "aaa" so it appears on the form - this part works fine. However, when I submit the form I would like to fill other properties of the model object and re-display the form using the same view.
The problem is that on submit the form still displays the original model object and not the updated one i.e. only Value1 is populated with "aaa" and Value2 is empty.
The view I use is the Auto-generated one by scaffolding option:
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>TestModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Value1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Value1)
#Html.ValidationMessageFor(model => model.Value1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Value2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Value2)
#Html.ValidationMessageFor(model => model.Value2)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
You have to call ModelState.Clear() so the result will be the expected. MVC does assumptions when POSTed data is sent back to the client. But beware, clearing it manually might cause undesired results ...
You can read more about here: Asp.net MVC ModelState.Clear and http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx
I work on one of my first ASP MVC-programs at the moment.
The program should show me a list of product, and with a link beneath the name of the product it should be possible to edit the product. No problem so far.
#model MVC3Demo.Product
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm("Save", "Product"))
{
<div>
<input type="hidden" id="ID" name="ID" value="#Model.ID" />
ProduktID #Model.ID
</div>
<div>
Produktname <input id="Name" name="Name" type="text" value=#Model.Name />
</div>
<div>
Preis <input id="Price" name="Price" type="text" value=#Model.Price />
</div>
<div>
<input type="submit" value="Speichern"/>
</div>
}
Now I have written a Save action method that should update my data:
public ActionResult Save(Product p)
{
ProductRepository rep = new ProductRepository();
rep.Update(p);
return RedirectToAction("List");
}
The "List"-View is where I can see all products with the edit-link.
The problem is, that if I press the save-button, it redirects me to the old list, not to the updated one. I debugged my project and I´m sure that the update-method works correct and updates the product.
My List action is:
#model IEnumerable<MVC3Demo.Product>
#{
ViewBag.Title = "List";
}
<h2>List</h2>
<ul>
#foreach (MVC3Demo.Product p in Model)
{
<li>#p.Name #Html.ActionLink("bearbeiten", "Edit", "Product", p, null)</li> //new{ ID = p.id}
}
</ul>
Because you asked, here is the List Action:
public ActionResult List()
{
ProductRepository rep = new ProductRepository();
return View(rep.GetAll());
}
So where could be my mistake?
It looks like you're calling the update, but you're not actually submitting the transaction itself, does your repository have a SubmitChanges, AcceptChanges or Commit or something similar? As with DataTables, your changes won't actually take effect (save to the database) until you call AcceptChanges.
Try include an HttpPost attribute at Save controller method.
[HttpPost]
public ActionResult Save(Product p)
{
ProductRepository rep = new ProductRepository();
rep.Update(p);
return RedirectToAction("List");
}