Adding Form For Different Model In Same View

2019-08-28 22:40发布

问题:

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?

回答1:

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.



回答2:

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