创建子对象时如何从子对象内的父对象获取ID? (MVC)

时间:2018-10-28 09:24:39

标签: c# asp.net-mvc asp.net-mvc-viewmodel

概述

我正在将ASP.NET Core与MVC结合使用。

我正在尝试制作一个简单的帮助台系统作为实验。

它有2个对象,一个查询和一个评论

  • 查询包含评论列表。

  • 评论具有其所属查询的ID。

我的问题是

如何获取要添加到评论属性中的查询ID(是正在创建的评论的父级)?


代码示例

CommentsController.Create

我尝试了2个POST示例,似乎都从注释中捕获了表单数据,但是我不知道如何在该表单数据中引入查询ID。当我创建孩子评论时。查询ID已添加到我发送到“创建”视图的模型中,但在该视图中提交表单时丢失了。 GET示例按预期工作。

    // 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)

视图/评论/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>


详细说明MVC程序中的当前流程,以便更好地理解

要在查询中添加评论,我进行了以下设置。

  1. “查询详细信息”视图上的按钮触发名为“ CreateComment”的InquiryController上的操作。这将重定向到带有查询ID的Comments控制器。
  2. CommentsController收到了重定向以及附加的InquiryID。然后,它发送回Create视图以创建注释,在该视图中以模型形式发送CommentCreation对象。这将保留父级咨询的ID以及新的/空的注释。
  3. 在评论创建视图中,输入评论信息并提交。
  4. 现在,提交的表单信息已被Create“捕获”,我可以看到评论的信息。但是,这就是问题,在该过程中丢失了父级查询的ID,现在将其设置为默认值0(因为它是整数)。

模型

/// <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; }
}

1 个答案:

答案 0 :(得分:1)

您需要在<form>中包含路由/查询字符串值,或在IDOfInquiryBelongingTo中包含隐藏输入,以便其值在请求中发送并绑定到模型。 / p>

但是,在编辑数据(您的Comment属性)时,视图模型不应包含数据模型,并且TimePosted似乎是用户不可编辑的属性。我建议您首先将视图模型修改为

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; }
}

您的GET方法现在将CommentVM的实例返回到视图

public IActionResult Create([FromRoute] int id) //id = InquiryID
{
    CommentVM model = new CommentVM
    {
        InquiryID = id
    }
    return View(model);
}

查看

@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>

然后在POST方法中,将视图模型映射到数据模型

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
    ....
}