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

C# 创建子对象时,如何从子对象内部的父对象获取ID?(MVC),c#,asp.net-mvc,asp.net-mvc-viewmodel,C#,Asp.net Mvc,Asp.net Mvc Viewmodel,概述 我正在使用ASP.NET内核和MVC 我正在尝试做一个简单的帮助台系统作为实验 它有两个对象,一个查询和一个评论 调查有一个评论列表 注释具有其所属查询的ID 我的问题是 /// <summary> /// Represents one inquiry on the helpdesk. /// Category, Country and RelatedProduct should perhaps be objects instead of strings. /// <

概述

我正在使用ASP.NET内核和MVC

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

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

  • 调查有一个评论列表

  • 注释具有其所属查询的ID

我的问题是

/// <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; }
}
如何获取要添加到注释中属性的查询ID(它是正在创建的注释的父级)


代码示例

/// <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; }
}
CommentsController.Create

我尝试了两个帖子示例,它们似乎都从评论中捕获了表单数据,但我不知道如何在表单数据中引入查询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)
//获取:注释/创建
public IActionResult Create([FromRoute]int-id)//id=InquiryID
//帖子:评论/创建
公共异步任务创建(CommentCreationTo CommentCreationTo)
公共异步任务创建([FromForm]CommentCreationTo CommentCreationTo)
查看/评论/创建.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>
@model HelpDesk2018.Models.commentCreationTo
@{
ViewData[“标题”]=“创建”;
}
创造
议论


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

为了向查询添加注释,我进行了以下设置

  • “查询详细信息”视图上的按钮触发名为“CreateComment”的查询控制器上的操作。这将重定向到带有查询ID的Comments控制器
  • CommentsController收到了重定向和附加的查询ID。然后,它将返回用于创建注释的创建视图,在该视图中,CommentCreation对象作为模型发送。它保存父查询的ID以及新的/空的注释
  • 在评论创建视图中,我输入评论信息并提交
  • 提交的表单信息现在被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; }
    }
    
    //
    ///表示帮助台上的一个查询。
    ///Category、Country和RelatedProduct可能应该是对象而不是字符串。
    /// 
    公共类查询:TextPost
    {
    公共字符串标题{get;set;}
    公共布尔解{get;set;}
    公共布尔私有{get;set;}
    公共列表注释{get;set;}=new List();
    公共字符串类别{get;set;}
    #区域可选属性
    /// 
    ///此查询与哪个国家最相关,例如丹麦、瑞典、挪威等,但也可以是“全部”或特定市场的名称。
    /// 
    公共字符串国家{get;set;}
    /// 
    ///如果查询与一个或多个产品相关,则可能应该是它自己的对象,而不是现在的字符串。
    /// 
    公共字符串相关产品{get;set;}
    #端区
    }
    公共类评论:TextPost
    {
    公共int查询ID{get;set;}
    }
    公共类TextPost
    {
    [关键]
    公共int ID{get;set;}
    公共用户{get;set;}
    public DateTime TimePosted{get;set;}
    /// 
    ///正文。
    /// 
    公共字符串文本{get;set;}
    }
    公共类CommentCreationTo
    {
    公共int IDOFINQUIRYBELONGING到{get;set;}
    /// 
    ///正在创建的注释。
    /// 
    公共注释注释{get;set;}
    }
    
    您需要在
    中包含路由/查询字符串值,或者为
    IDOFINQUIRYBELONGTO
    包含隐藏输入,以便在请求中发送其值并将其绑定到您的模型

    但是,在编辑数据时,视图模型不应包含数据模型(您的
    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
    //添加隐藏输入
    
    在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
        ....
    }
    
    public异步任务创建([FromForm]CommentVM模型)
    {
    如果(!ModelState.IsValid)
    {
    返回视图(模型);
    }
    注释=新注释
    {
    InquiryID=model.InquiryID,
    Text=model.Text,
    TimePosted=日期时间。现在,
    ..//根据需要设置其他属性(用户等)
    };
    //保存和重定向
    ....
    }
    
    是您显示GET的第一个方法吗?(在这种情况下,它不应该将模型作为参数-just和
    int id
    表示
    InquiryId
    。您需要在
    InquiryId
    的表单中包含路由值,或者包含一个隐藏的输入,以便它被发回。这是一篇文章。添加了一些说明,现在显示我的GET。@StephenMuecke你可以看到任何连接查询和评论的解决方案,请让我知道。这不一定是我现在尝试的方式。你没有展示你的模型,所以我所能做的并不是您需要一个路由值或绑定到您的
    InquiryId
    property@StephenMuecke我现在添加了模型。在GET Create on CommentsController中,查询id正在路由中。但我似乎无法同时获取