如何从自定义标签助手获取信息?

How to get information from custom tag helper?

提问人:Nooty 提问时间:3/15/2023 最后编辑:GSergNooty 更新时间:3/15/2023 访问量:96

问:

我创建了一个调查,其中包含带有答案的问题。我正在编辑它,在这个视图中,我正在使用自定义标签助手循环每个部分及其问题,我想知道一旦我在表单中提交发布请求,我如何从所有这些中获取信息。您可以为每个输入使用属性,但在这种情况下,有没有办法从中获取信息?我正在编辑它的值并将其保存到数据库中。asp-for

调查视图:

<form asp-controller="Response" asp-action="Edit" method="post">
    @foreach (Section section in Model.Survey.Metadata.Sections.OrderBy(e => e.Position))
    {
        <div class="card" id="a@(section.Id.Replace("-", ""))">
            <div class="card-body">
                <h1>@(section.Title)</h1>
                @if (!string.IsNullOrEmpty(section.Description))
                {
                    <div>
                        @Html.Raw(section.Description)
                    </div>
                }
                <hr />
                @foreach (QuestionMetadata question in Model.Survey.Questions.Where(e => e.SectionId == section.Id).OrderBy(e => e.Position))
                {
                    <script>
                        @(ViewData["id"])SetValue[@Html.Raw($"\"a{question.Id.ToString().Replace("-", "").Split(":")[1]}\"")] = function (value, modified = true) {
                            $("#@($"{ViewData["id"]}-{question.Id.ToString().Replace("-", "").Split(":")[1]}-value")").val(JSON.stringify(
                                {
                                    Value: value,
                                    QuestionId: "@question.Id",
                                    Modified: modified
                                }
                            ));
                        };
                        @(ViewData["id"])GetValue[@Html.Raw($"\"a{question.Id.ToString().Replace("-", "").Split(":")[1]}\"")] = function () {
                            return JSON.parse(
                                $("#@($"{ViewData["id"]}-{question.Id.ToString().Replace("-", "").Split(":")[1]}-value")").val())
                                .Value;
                        };
                    </script>
                    <question survey="@Model.Survey.Metadata" answers="@Model.Survey.Metadata.Answers.ToArray()" survey-id="@ViewData["id"]" question=@question answer="@Model.Survey.Metadata.Answers.First(e => e.QuestionId == question.Id)" site-id="@Model.Survey.Metadata.SiteId" />
                    <hr />
                }
            </div>
        </div>
    }
    <div class="card">
        <div class="card-body">
                <button type="submit" asp-route-SurveyId="@Model.Survey.Metadata.Id" class=" @($"{ViewData["id"]}-button-{Model.Survey.Metadata.Id.Replace(":", "")}-survey-js")
                button-anchor">
                Submit
            </button>
        </div>
    </div>
</form>

问题标记帮助程序视图:

using ApplicationCore.Entities;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Threading.Tasks;
using Web.Models;

namespace Web.TagHelpers
{
    // You may need to install the Microsoft.AspNetCore.Razor.Runtime package into your project
    [HtmlTargetElement("question")]
    public class QuestionTagHelper : BaseTagHelper
    {
        [HtmlAttributeName("asp-for")]
        public ModelExpression AspFor { get; set; }
        public QuestionMetadata Question { get; set; }
        public Answer Answer { get; set; }
        public string SurveyId { get; set; } = Guid.NewGuid().ToString();
        public string SiteId { get; set; }
        public SurveyMetadata Survey { get; set; }
        public Answer[] Answers { get; set; }

        public QuestionTagHelper(ICompositeViewEngine viewEngine,
            IViewBufferScope viewBufferScope) : base(viewEngine, viewBufferScope)
        {
        }

        public override async Task RunAsync(TagHelperContext context, TagHelperOutput output)
        {
            string name = this.AspFor.Name;

            if (!string.IsNullOrEmpty(name))
            {
                output.Attributes.Add("name", name);    
            }

            ViewContext.ViewData["survey-id"] = SurveyId;
            Model = new QuestionTagHelperModel()
            {
                Question = Question,
                Answer = Answer,
                Required = Question.IsRequired
                    .Invoke(new()
                    {
                        { "Survey", Survey },
                        { "Answers", Answers }
                    }),
                SiteId = SiteId,
                Year = Survey.Year
            };

            output.TagMode = TagMode.StartTagAndEndTag;
        }
    }
}

作用方法:

[HttpPost]
[Authorize(Roles = "Administrator")]
public async Task<IActionResult> Edit(Edit.Command command)
{
    if (!ModelState.IsValid)
    {
        return RedirectToAction("Index");
    }

    Edit.CommandResponse response = await _mediator.Send(command);

    if (response.NotFound)
    {
        return RedirectToAction("Index");
    }
    else
    {
        return View(response);
    }
}

模型:

public class Command : IRequest<CommandResponse>
{
    [Required]
    [HiddenInput]
    public string Id { get; set; }
    public ApplicationCore.Entities.Survey Survey { get; set; }
    public List<QuestionTagHelperModel> Questions { get; set; }
    public string SurveyId { get; set; }
}

我尝试添加ModelExpression For,但它仍然不起作用。

c# asp.net-core-tag-helpers

评论


答:

0赞 Atom 3/15/2023 #1

我会尝试创建一个模型来表示您的部分、问题和答案的结构,然后使用 asp-for 属性将输入字段绑定到模型属性。提交表单后,数据将绑定到模型,并且可以在操作方法中轻松访问。