Controller httpGet Action :
[HttpGet]
public ActionResult CalculCom(int id)
{
CalcCom calc = new CalcCom();
ComModel com = calc.CalculCom(id, 10, 2011);
return View(com);
}
This is my View :
// Some code to show my model attribute
#using (Html.BeginForm()) {
#Html.HiddenFor(m=>m.ben)
#Html.HiddenFor(m=>m.centre)
#Html.HiddenFor(m=>m.mtn_brut)
#Html.HiddenFor(m=>m.mtn_net)
#Html.HiddenFor(m=>m.mtn_rs)
#Html.HiddenFor(m=>m.quitaList) // this is a list
#Html.HiddenFor(m=>m.val_rs)
#Html.HiddenFor(m=>m.versNum)
<input type="submit" value="Valider"/>
}
This is my controller HttpPost Action :
[HttpPost]
public ActionResult CalculCom(ComModel model)
{
//some code
foreach (ComModel.quita qi in model.quitaList)
{
var quita = db.QUITA.Find(qi.n_quita);
quita.VERSNUM = vers.VERSNUM;
db.Entry(quita).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ComModel :
public class ComModel
{
public int versNum { get; set; }
public decimal mtn_brut { get; set; }
public decimal mtn_net { get; set; }
public decimal mtn_rs { get; set; }
public decimal val_rs { get; set; }
public string ben { get; set; }
public int centre { get; set; }
public List<quita> quitaList = new List<quita>();
public struct quita
{
public decimal mtn_com { get; set; }
public decimal mtn_net { get; set; }
public decimal mtn_ttc { get; set; }
public decimal comp_prime { get; set; }
public decimal mtn_fq { get; set; }
public decimal mtn_tot { get; set; }
public int n_quita { get; set; }
}
}
So What I'm trying to do Is:
getting the Model (HttpGet Action)
show my model the then user will decide it to validate the model or not.
If Model is valide then I will save it to database.
The problem when user Click on submit button the model is sent but the items in quitaList was missing , After sending , in my HttpPost Controler, quitaList was empty
So how to fix it ? Also is there any other ways to do that, showing modal before saving it to database, instead using From to send model?
For get list back in model during form post you need to loop through the list like this
#using (Html.BeginForm()) {
#Html.HiddenFor(m=>m.ben)
#Html.HiddenFor(m=>m.centre)
#Html.HiddenFor(m=>m.mtn_brut)
#Html.HiddenFor(m=>m.mtn_net)
#Html.HiddenFor(m=>m.mtn_rs)
#for(int i=0;i<Model.quitaList.Count;i++)
{
#Html.HiddenFor(m=>m.quitaList[i].mtn_com)
}
#Html.HiddenFor(m=>m.val_rs)
#Html.HiddenFor(m=>m.versNum)
<input type="submit" value="Valider"/>
}
This will give list back in model, but note that it will only contain value of "mnt_com" property. if you want all property value then you need to define all same as in above code in the loop.
Related
My input model consists of NewForm in which many fields
public class NewForm
{
[Key]
public int Id { get; set; }
public string HeadForm { get; set; }
public List<Field> Fields { get; set; }
}
public class Field
{
public int Id { get; set; }
public bool Check { get; set; }
public string HeadField { get; set; }
}
I want to take values from the base and edit them, but Model.Fields.Count throw exception. Although the string "HeadForm" is displayed. Lists are not displayed.
EditPage:
#model EditFormApplication.Models.NewForm
#using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
#Html.TextBoxFor(model => model.HeadForm)
<h5>Fields:</h5><br>
#for ( var i = 0; i< Model.Fields.Count; i++) {
#Html.TextBoxFor(model => model.Fields[i].HeadField)
#Html.CheckBoxFor(model => model.Fields[i].Check)
}
<input type="button" value="Add Field" onclick="addField(this);">
<input type="submit"value="Save">
}
For example, I am typing data by ID = 3.
Controller:
public ActionResult CreateForm(NewForm model)
{
using (NewFormContext db = new NewFormContext())
{
db.NewForms.Add(model);
db.SaveChanges();
return RedirectToAction("Edit");
}
}
public ActionResult Edit()
{
using (NewFormContext db = new NewFormContext()) {
var model = db.NewForms.Find(3);
return this.View(model);
}
}
used Code First and one to many
Sounds like Model.Fields property still contain null when db.NewForms.Find() is executed to assign the model you want to return into view, indicating that EF doesn't create dependent collection yet. As far as I know you should add collection instance definition inside parameterless constructor of entity class:
public class NewForm
{
public NewForm()
{
// instantiate list here
Fields = new List<Field>();
}
[Key]
public int Id { get; set; }
public string HeadForm { get; set; }
public List<Field> Fields { get; set; }
}
Or if you're using lazy loading, mark the property as virtual to let EF instantiate the collection while necessary:
public virtual List<Field> Fields { get; set; }
Related issue:
EF codefirst : Should I initialize navigation properties?
I want create or edit in collection object. But collection object in return null controller .
ViewModel:
public class ViewModelEditManuscript
{
public int Id { get; set; }
public string ArchiveNumber { get; set; }
public ICollection<ViewModelEditManuscriptAuthor> Authors { get; set;
}
public class ViewModelEditManuscriptAuthor
{
public ViewModelEditPerson Author { get; set; }
}
public class ViewModelEditPerson
{
public int Id { get; set; }
public string TRName { get; set; }
}
Controller:
public ActionResult Edit(ViewModelEdit viewModelEdit)
{
problem this.viewModel.Authors = null;
}
Cshtml:
foreach (var item in #Model.Entity.Authors)
{
#Html.TextBoxFor(m => item.Author.Id)
}
When you use #Html.TextBoxFor(m => item.Author.Id) inside your loop, For all textboxes inside the loop, It is going to generate textbox markup with name property as
name="item.Author.Id"
When the form is submitted the Modelbinder cannot map this form data to an object of the ViewModelEditManuscript class.
For the model binding to work, you need to make sure that you are generating the proper field names which matches with your view model property hierarchy.
Since our ViewModelEditManuscript class has a collection property called Authors and each item of that again has an Author property which again has an Id property, We should tell razor to generate name value for our inputs like
name="Authors[0].Author.Id"
name="Authors[1].Author.Id"
We can do Html.TextBox helper method to do that. The first parameter is the value for the name property of the input.
#model ViewModelEditManuscript
#using (Html.BeginForm())
{
var i = 0;
foreach (var item in #Model.Authors)
{
#Html.TextBox("Authors[" + i+ "].Author.Id",item.Author.Id)
i++;
}
<input type="submit"/>
}
This will work assuming your HttpPost action method's argument is of type ViewModelEditManuscript
[HttpPost]
public ActionResult WhateverYourActionMethodNameIs(ViewModelEditManuscript model)
{
// do something with model and redirect/return something
}
I wantto Authors save.
//this Domain
public class Manuscript
{
public int Id { get; set; }
public string ArchiveNumber { get; set; }
[XmlIgnore]
public virtual ICollection<ManuscriptAuthor> Authors { get; set; }
}
public class ManuscriptAuthor
{
public int ManuscriptId { get; set; }
public int AuthorId { get; set; }
}
//this controller
public ActionResult Edit(ViewModelEdit viewModelEdit)
{
Manuscript manuscript = null;
manuscript.Authors = viewModelEdit.Entity.Authors; // this error
}
I'm trying to use the user selected item from the DropDownList to create a new entry in my Database table that is related/linked?(Not sure of correct wording for this) to the DropDownList item.
Here are my Models
public class TaskInstance
{
public int Id { get; set; }
public DateTime DueDate { get; set; }
public int HowMany { get; set; }
public Task TaskId { get; set; }
public virtual Task Task { get; set; }
}
public class TaskInstanceViewModel
{
[DataType(DataType.DateTime)]
public DateTime DueDate { get; set; }
public int HowMany { get; set; }
public IEnumerable<SelectListItem> TaskList { get; set; }
public virtual ICollection<Task> Task { get; set; }
}
public class Task
{
public Task()
{
TaskInstance = new HashSet<TaskInstance>();
}
public int Id { get; set;}
public string Name { get; set; }
public string Unit { get; set; }
public virtual ICollection<TaskInstance> TaskInstance { get; set; }
}
Controllers
public ActionResult Create()
{
var model = new TaskInstanceViewModel();
model.TaskList = db.Task.ToList().Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
}).ToList();
return View(model);
}
// POST: TaskInstances/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TaskInstanceViewModel model)
{
if (ModelState.IsValid)
{
var taskinstance = new TaskInstance { DueDate = model.DueDate };
db.TaskInstance.Add(taskinstance);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
View - This is the only one I need to show I think, the others are just fields
#Html.DropDownListFor(x => Model.TaskList, (SelectList)Model.Task)
On the controller where it says var taskinstance = new TaskInstance { DueDate = model.DueDate }; Would be where i need to use the selected item from the User but I have no idea how to get it, i've looked through a lot of posts but most of them is just how to make the DropDownList in the first place but not how to use it(Being a link to another table) with a new database entry.
I'd also like to mention that I am still new to MVC so feel free to point out if im going about this the wrong way
Add a new property of type int to store the selected task from the dropdown. Remember view models are specific to the view.so keep only those properties you absolutely need in the view, in your view model.
public class TaskInstanceViewModel
{
public DateTime DueDate { get; set; }
public int HowMany { get; set; }
public IEnumerable<SelectListItem> TaskList { get; set; }
public int SelectedTask {set;get;} // new property
}
And in your view
#model TaskInstanceViewModel
#using(Html.BeginForm())
{
<label> How many</label>
#Html.TextBoxFor(s=>s.HowMany)
<label>Due date</label>
#Html.TextBoxFor(s=>s.DueDate)
<label>Task</label>
#Html.DropDownListFor(s => s.SelectedTask, Model.TaskList)
<input type="submit" />
}
And in your HttpPost action, you can use the SelectedTask property value which will have the Id of the task selected
[HttpPost]
public ActionResult Create(TaskInstanceViewModel model)
{
if (ModelState.IsValid)
{
var taskinstance = new TaskInstance { DueDate = model.DueDate ,
TaskId=model.SelectedTask };
db.TaskInstance.Add(taskinstance);
db.SaveChanges();
return RedirectToAction("Index");
}
model.TaskList = db.Task.ToList().Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
}).ToList();
return View(model);
}
It seems to me that you need you point to a property that represents the selected item in the dropdown. The dropdown items is IEnumerable<SelectListItem> why isn't the selected item a property of type SelectListItem?
Add a property to your view model:
public class TaskInstanceViewModel
{
[DataType(DataType.DateTime)]
public DateTime DueDate { get; set; }
public int HowMany { get; set; }
public IEnumerable<SelectListItem> TaskList { get; set; }
public virtual ICollection<Task> Task { get; set; }
//add this property:
public SelectListItem SelectedItem { get; set; }
}
And modify the view:
#Html.DropDownListFor(x => Model.TaskList, Model.SelectedItem )
I am having problems with filling a drop down list in asp.net mvc 5. So I have this in my view
#using (Html.BeginForm("Getdata", "Data", FormMethod.Get))
{
<p>
Choose your type of data: #Html.DropDownList("SearchString") <br />
<input type="submit" value="Filter" />
</p>
}
And this is the controller method
public JsonResult Getdata(string search)
{
var data = (from m in db.ABC
select search).Distinct();
return Json(data, JsonRequestBehavior.AllowGet);
}
And this is the model
public class ABC
{
public int a { get; set; }
public int b { get; set; }
public int c { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public int ID { get; set; }
public class ABCDBContext : DbContext
{
public DbSet<ABC> ABC { get; set; }
}
}
So what do I need to change in order to fill the drop down list with the data types ABC has?
I am following this MVC tutorial and trying to create a database using DbContext and related model classes. The project name is "odeToFood".
Model classes:
namespace odeToFood.Models
{
public class Restaurant
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public ICollection<RestaurantReview> Reviews { get; set; }
}
public class RestaurantReview
{
public int Id { get; set; }
public string Body { get; set; }
public int Rating { get; set; }
public int RestaurantId { get; set; }
}
public class odeToFoodDb :DbContext
{
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<RestaurantReview> Reviews { get; set; }
}
}
HomeController:
public class HomeController : Controller
{
odeToFoodDb _db = new odeToFoodDb();
public ActionResult Index()
{
var model= _db.Restaurants.ToList();
return View(model);
}
}
Index View
#model IEnumerable<odeToFood.Models.Restaurant>
#{
ViewBag.Title = "Home Page";
}
#foreach (var item in Model)
{
<div>
<h4>#item.Name;</h4>
Restaurant is in : #item.City #item.Country
<hr />
</div>
}
When I run this code, according to this tutorial it should create a database and the values should be fetched (when I enter in table) but in server explorer I cannot find a database.
Neither the Index View gives an error nor can I find a database in server explorer. I tried (Localdb)\v11.0 by going to "add connection" but still it does not show any database.
I would be grateful to know what's wrong.