如何从ASP.NET自定义TagHelper中获取表单提交数据?
自定义TagHelper循环渲染问卷问题,POST提交无法绑定模型数据
我做了一个带问答的问卷,在编辑视图里用自定义TagHelper循环展示各章节和对应的问题。提交表单POST请求时,想获取所有问题的修改数据并存到数据库。一般用asp-for属性就能绑定输入,但我加了ModelExpression还是拿不到数据。相关代码如下:
问卷视图
<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>
Question标签助手
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; } } }
Action方法
[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; } }
内容的提问来源于stack exchange,提问作者Nooty
相关产品推荐
相关产品推荐

