Как получить идентификатор из родительского объекта внутри дочернего объекта при его создании?(MVC) - PullRequest
0 голосов
/ 28 октября 2018

Обзор

Я использую ASP.NET Core с MVC.

Я пытаюсь сделать простую службу поддержки в качестве системыэксперимент.

Имеет 2 объекта: Запрос и Комментарий .

  • Запрос имеет список комментариев..

  • Комментарий содержит идентификатор запроса, которому он принадлежит.

Мой вопрос

Как получить идентификатор запроса (который является родительским для создаваемого комментария), добавляемый к свойству в комментарии?


Примеры кода

CommentsController.Create

Я пробовал 2 примера POST, оба, кажется, собирают данные формы из комментария, но я не знаю, как также ввестиИдентификатор запроса в данных этой формы.Когда я создаю детский комментарий.Идентификатор запроса был добавлен в модель, которую я отправил в представление «Создать», но потерял при отправке формы в этом представлении.Пример 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. Кнопка в подробном представлении запросазапускает действие на контроллере InquiryControl с именем «CreateComment».Это перенаправляет на контроллер комментариев с идентификатором запроса.
  2. CommentsController получил перенаправление плюс прикрепленный идентификатор InquiryID.Затем он отправляет обратно представление Create для создания комментариев, в котором объект CommentCreation отправляется как модель.Он содержит идентификатор родительского запроса, а также новый / пустой комментарий.
  3. В представлении создания комментария я ввожу информацию о комментарии и отправляю.
  4. Отправленная информация о форме теперь "перехвачена""Создать и я могу видеть информацию из комментария.Тем не менее, и это проблема , идентификатор родительского запроса был потерян в процессе и теперь имеет значение по умолчанию 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 голосов
/ 28 октября 2018

Вам необходимо включить значение строки маршрута / запроса в <form> или включить скрытый ввод для IDOfInquiryBelongingTo, чтобы его значение отправлялось в запросе и было привязано к вашей модели.

Однако модели представления не должны содержать моделей данных при редактировании данных (ваше свойство 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
    ....
}
...