在 ASP.NET 表单中提交更改的 FormData,以便通过 ModelState 和重定向实现正常行为

问题描述 投票:0回答:1

我正在使用 APS.NET Core MVC (.NET 5.0) 开发一个 Web 应用程序。我有一个实体(服务),它有另一个实体(OpeningHours)的动态列表。因此,服务可以有不同的开放时间,例如:

  • 从 08:00 到 20:00
  • 08:00至13:00和17:00至20:00

您可以设置不同的时间段,任意数量。我不知道如何实现这种情况,并寻找我找到的解决方案如何将不同实体的项目动态添加到 ASP.NET Core MVC 中的列表,并按照answer将其适应我的实体。稍微简化一下,这就是代码:

模型(或视图模型):

public class Service
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Description { get; set; }
    public List<ServiceOpeningHours> OpeningHours { get; set; } = new List<ServiceOpeningHours>();
}

public class ServiceOpeningHours
{
    public TimeSpan From { get; set; }
    public TimeSpan To { get; set; }
}

创建.cshtml(视图):

@model MyWebApp.Services.Models.Service

...

<form asp-action="Create" name="createForm" id="createForm">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label class="control-label">Name</label>
            <input asp-for="Name" class="form-control" />
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label class="control-label">Description</label>
            <input asp-for="Description" class="form-control" />
            <span asp-validation-for="Description" class="text-danger"></span>
        </div>
        <fieldset>
            <legend>Opening Hours</legend>
            <div id="openingHoursContainer">
                @foreach (ServiceOpeningHours item in Model.OpeningHours)
                {
                    <partial name="_OpeningHourEditor" manifest model="item" />
                }
            </div>
        </fieldset>

        <div>
            <div class="form-group">
                <input id="addOpeningHourItem" type="button" value="Add Opening Hour" class="btn btn-primary" />
            </div>
            <div class="form-group">
                <input type="submit" id="submit" value="Create" class="btn btn-primary" />
            </div>
        </div>
    </form>

...

@section Scripts {
    $('#addOpeningHourItem').click(function (event) {
        event.preventDefault();
        $.ajax({
            async: true,
            data: $('#form').serialize(),
            type: 'POST',
            url: '/Services/AddBlankOpeningHour',
            success: function (partialView) {
                $('#openingHoursContainer').append(partialView);
            }
        });
    });
    $('#submit').click(function (event) {
        event.preventDefault();
        var formData = new FormData();

        formData.append("Name", $('input[name="Name"]').val());
        formData.append("Description", $('input[name="Description"]').val());

        $("input[name='From']").each(function (i) {
            var from = $(this).val();
            formData.append("OpeningHours[" + i + "].From", from);
        });
        $("input[name='To']").each(function (i) {
            var to = $(this).val();
            formData.append("OpeningHours[" + i + "].To", to);
        });

        formData.append("__RequestVerificationToken", $('form[name="createForm"] input[name="__RequestVerificationToken"]').val());
        
        $.ajax({
            method: 'POST',
            url: '/Services/Create',
            data: formData,
            processData: false,
            contentType: false,
            success: function (returnValue) {
                console.log('Success: ' + returnValue);
            }
        });
    });
}

_OpeningHourEditor.cshtml(开放时间项目的部分视图):

@model MyWebApp.Models.ServiceOpeningHours

<div class="row">
    <div class="col-md-6">
        <div class="form-group">
            <label class="control-label">From</label>
            <input asp-for="From" class="form-control" />
            <span asp-validation-for="From" class="text-danger"></span>
        </div>
    </div>
    <div class="col-md-6">
        <div class="form-group">
            <label class="control-label">To</label>
            <input asp-for="To" class="form-control" />
            <span asp-validation-for="To" class="text-danger"></span>
        </div>
    </div>
</div>

在 javascript 代码中,将创建

FormData
并填充所有字段,并且模型成功到达
Create
操作。

服务控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Service service)
{
    if (ModelState.IsValid)
    {
        // Save data in data base...

        return this.RedirectToAction("Index");
    }
    return View(service);
}

[HttpPost]
public ActionResult AddBlankOpeningHour()
{
    return PartialView("_OpeningHourEditor", new ServiceOpeningHours());
}

使用此代码,当

Create
操作返回响应时,它会到达
success
$.ajax()
块,但这不会导致页面重新加载新数据。

我认为你不应该使用 AJAX 来做到这一点。我应该如何拨打电话才能一切正常?也就是说,如果未填写

Name
Description
字段,则应显示
ModelState
错误消息,如果一切顺利,应将其重定向到
Index
操作。

javascript c# asp.net asp.net-mvc asp.net-core-mvc
1个回答
2
投票

修改了提交脚本以删除 ajax 并最初更改输入字段的名称,以便列表正确绑定到模型。

$('#submit').click(function (event) {
   // initially prevent form submit
   event.preventDefault();
   
   // loop through all input with name From, and change their name with index
   $("input[name='From']").each(function (i) {
      $(this).attr("name", "OpeningHours[" + i + "].From");
   });
   
   // loop through all input with name To, and change their name with index
   $("input[name='To']").each(function (i) {
      $(this).attr("name", "OpeningHours[" + i + "].To");
   });
   
   // submit the form
   $("#createForm").submit();
});
© www.soinside.com 2019 - 2024. All rights reserved.