Lets's Say that i have a two model classes; Project, and Comment as following :
public class Project
{
Public int ProjectID { get; set; }
public string Title { get; set; }
public virtual List<Comment> Comments { get; set; }
}
public class Comment
{
Public int CommentID { get; set; }
public string Text { get; set; }
}
I used the CRUD creation feature when i created the "controller and the views" for my Project class.
Now, in the 'Details' view for the Project, i want to add form to add comments to this project, i want the 'Details' view to be something like :
Project Name : -- Project Name Goes Here --
Comments : 1. ---------
2. ---------
[Text Area To Enter Comment] and [SUBMIT] button
The submit button should add comment to the project's comments list.
How do I achieve this?
I recommend creating a ViewModel that represents all the data you need for a view. These ViewModels are specific to MVC.
Model:
public class IndexViewModel
{
public Project Project { get; set; }
public IEnumerable<Comment> Comments { get; set; }
public Comment NewComment { get; set; }
}
Controller Method:
public ActionResult Index()
{
var model = new IndexViewModel();
// populate data, including an empty NewComment
model.NewComment = new Comment();
model.NewComment.ProjectId = model.Project.ProjectId;
return View(model);
}
View:
@model IndexViewModel
@using (Html.BeginForm("Comment", "Create"))
{
@Html.EditorFor(m => m.NewComment.CommentText)
@Html.HiddenFor(m => m.NewComment.ProjectId)
}
This means adding or removing data a view needs is pretty straight forward. The form should only need to be around NewComment. The post model would look like:
Model:
public class CreateCommentViewModel
{
public Comment NewComment { get; set; }
}
Control Method:
public ActionResult Create(CreateCommentViewModel model)
{
// logic for creating comment
}
DotNetFiddle Example. The only problem with Dot Net Fiddle is it only supports a single view (that I know of) so when you pass the Text
of the new comment, I throw an exception with the text of the comment.
Erik Philips was close to answer, actually his solution works, but i found most accurate answer to my question using Html.Action.
// 1. Add this line to Project's Detail View.
@Html.Action("CreateComment","Comment", new { ProjectID = Model.ProjectID })
// 2. Add this method to the Comment Controller class, and send the id
// to the comment view.
public ActionResult CreateComment(int ProjectID)
{
return View(new Comment() { ProjectID = ProjectID });
}
// 3. Create view for the CreateComment controller action
@using (Html.beginForm("SubmitComment","Comment"))
{
@Html.HiddenFor(ProjectID=>Model.ProjectID) // This value you send it
@Html.EditorFor(model=>Model.Text)
<input type="submit" value="Add Comment" />
}
// 4. add method to the comment controller
// since i alreay public ActionResult Details(int id) in the project controller
// to display the project's details and comments. i will call it after adding comment
public ActionResult SubmitComment(Comment comment)
{
dbContext = new myDatabaseContext();
dbContext.Comments.Add(comment);
dbContext.SaveChanges();
return RedirectToAction("Details","Project", new { id=comment.ProjectID })
}
Thanks for contributing in this post