Overview
I'm using ASP.NET Core with MVC.
I am trying to make a simple helpdesk system as an experiment.
It has 2 objects, an Inquiry and a Comment .
An Inquiry has a list of comments.
A comment has the ID of the Inquiry it belongs to.
My question is
How can I get the ID of the Inquiry (which is a parent of the comment being created) to be added to a property in the comment?
Code examples
CommentsController.Create
I have tried the 2 POST examples, both seem to capture the form data from the comment but I don't know how to also bring in the Inquiry ID in that form data. When I am creating a child comment. The Inquiry ID was added to the model I sent to the Create view but lost when submitting the form in that view. The GET example works as intended.
// GET: Comments/Create
public IActionResult Create([FromRoute] int id) //id = InquiryID
// POST: Comments/Create
public async Task<IActionResult> Create(CommentCreationDTO commentCreationDTO)
public async Task<IActionResult> Create([FromForm]CommentCreationDTO commentCreationDTO)
Views/Comments/Create.cshtml
@model HelpDesk2018.Models.CommentCreationDTO
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>Comment</h4>
<hr/>
<div class="row">
<div class="col-md-4">
<form asp-controller="Comments" asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="@Model.Comment.TimePosted" class="control-label"></label>
<input asp-for="@Model.Comment.TimePosted" class="form-control" />
<span asp-validation-for="@Model.Comment.TimePosted" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Comment.Text" class="control-label"></label>
<input asp-for="@Model.Comment.Text" class="form-control" />
<span asp-validation-for="@Model.Comment.Text" class="text-danger"></span>
</div>
</form>
</div>
Elaboration of the current flow in the MVC program for better understanding
To add comments to the Inquiry I have made the following setup.
Models
/// <summary>
/// Represents one inquiry on the helpdesk.
/// Category, Country and RelatedProduct should perhaps be objects instead of strings.
/// </summary>
public class Inquiry : TextPost
{
public string Title { get; set; }
public bool Solved { get; set; }
public bool Private { get; set; }
public List<Comment> Comments { get; set; } = new List<Comment>();
public string Category { get; set; }
#region optional properties
/// <summary>
/// Which country this inquiry is most relevant for. E.g. Denmark, Sweden, Norway etc., but can also be "All" or the name of a specific market.
/// </summary>
public string Country { get; set; }
/// <summary>
/// In case the inquiry is related to one or more products. Should perhaps be an object in it's own right instead of a string as it is now.
/// </summary>
public string RelatedProduct { get; set; }
#endregion
}
public class Comment : TextPost
{
public int InquiryID { get; set; }
}
public class TextPost
{
[Key]
public int ID { get; set; }
public User User { get; set; }
public DateTime TimePosted { get; set; }
/// <summary>
/// The main text.
/// </summary>
public string Text { get; set; }
}
public class CommentCreationDTO
{
public int IDOfInquiryBelongingTo { get; set; }
/// <summary>
/// The comment that is being created.
/// </summary>
public Comment Comment { get; set; }
}
You need to include a route/query string value in the <form>
or include a hidden input for IDOfInquiryBelongingTo
, so that its value is sent in the request and will be bound to your model.
However, view models should not contain data models when editing data (your Comment
property), and TimePosted
appears to be a property that should not be editable by the user. I recommend you first modify the view model to
public class CommentVM
{
public int? ID { get; set; } // if you also want to use this for editing existing comments
[Required]
public int? InquiryID { get; set; }
[Required(ErrorMessage = "Please enter a comment")]
public string Text { get; set; }
}
Your GET method will now return an instance of CommentVM
to the view
public IActionResult Create([FromRoute] int id) //id = InquiryID
{
CommentVM model = new CommentVM
{
InquiryID = id
}
return View(model);
}
View
@model ....CommentVM
<form asp-controller="Comments" asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="InquiryID" /> // add hidden input
<div class="form-group">
<label asp-for="Text" class="control-label"></label>
<input asp-for="Text" class="form-control" />
<span asp-validation-for="Text" class="text-danger"></span>
</div>
</form>
And in the POST method, map the view model to the data model
public async Task<IActionResult> Create([FromForm]CommentVM model)
{
if (!ModelState.IsValid)
{
return View(model);
}
Comment comment = new Comment
{
InquiryID = model.InquiryID,
Text = model.Text,
TimePosted = DateTime.Now,
.... // set other properties (User etc) as required
};
// save and redirect
....
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.