为什么我的不显眼的 ajax 停止更新我在 ASP.NET Core 3.1 中的部分视图?

问题描述

我在 kendo 窗口中使用不显眼的 ajax 来更新表单,一旦它被填写。表单应该动态更新 DOM 元素的 Id,并显示表单内的相关数据,作为从控制器返回。

让我们开始吧,这里是包含部分视图的窗口元素,它是一个表单:

@model Requirement
@{
    int localId = Model.Id;
}
<div class="window-content">
    <form method="post" data-ajax-url="/Home/Process_Requirement" data-ajax="true" data-ajax-method="post" data-ajax-loading="#spinner" data-ajax-update="#update-form-requirement" data-ajax-success="form_requirement_success">
        <div id="update-form-requirement">
            <partial name="_Form_Requirement" />
        </div><!--/update-panel-->
        <div class="window-footer">
            <div class="container">
                <div class="row no-gutters">                    
                    <div class="col">
                        <button type="submit" class="input-submit float-right">Save</button>
                    </div>
                </div>
            </div>
        </div>
    </form>
</div>

_Form_Requirement

@model Requirement

@{
    int localId = Model.Id;
}
  
<div class="tab-content">
    <div class="tab-pane fade show active" id="form-requirement-basic-@localId" role="tabpanel" aria-labelledby="requirement-tab">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>    
        <input type="text" id="Id_@localId" name="Id" asp-for="Id" readonly />
        <input type="text" id="CreatedUser_@localId" asp-for="CreatedUser" readonly />

        <div class="container">
            <div class="row">
                <div class="col">
                    <div class="form-group">
                        <label>Vessel Type</label>
                        <kendo-dropdownlist name="VesselType"
                                            for="VesselType"
                                            id="VesselType_@localId"
                                            datatextfield="TypeName"
                                            datavaluefield="Id"
                                            min-length="3"
                                            style="width: 100%"
                                            value-primitive="true"
                                            option-label="Select vessel type"
                                            footer-template="<button class='dropdown-button k-icon k-i-plus-outline' data-object-title='Add vessel type' data-object-function='_Window_Vessel_Type' onclick='open_data_window(this,event)'></button>"
                                            filter="FilterType.Contains">
                            <datasource type="DataSourceTagHelperType.Ajax" page-size="80">
                                <transport>
                                    <read url="/Vessel/ReadVesselTypes" />
                                </transport>
                            </datasource>
                            <popup-animation>
                                <open duration="300" effects="fadeIn" />
                                <close duration="300" effects="fadeOut" />
                            </popup-animation>
                        </kendo-dropdownlist>                       
                    </div>
                </div>
            </div>
        </div>       
    </div>
</div>

提交表单时,控制器操作会执行以下操作:

/Home/Process_Requirement

public IActionResult Process_Requirement(Requirement model)
{
    //Define the partial view we want
    string modal = "_Form_Requirement";

    //If the Id is 0 then create a new requirement
    if (model.Id == 0)
    {
        if (ModelState.IsValid)
        {
            try {
                _requirementService.InsertRequirement(model);
                var getData = _requirementService.GetRequirement(model.Id);
                return PartialView(modal,getData);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    else
    {
        try
        {
            _requirementService.UpdateRequirement(model);
            return PartialView(modal,model);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    return PartialView(modal);
}

因此,当您第一次打开一个窗口来创建新需求时,localId0,因为您没有编辑一个,这是预期的行为。

然后当您填写所有详细信息并提交表单时,数据会发布到数据库并正确保存,但模型似乎没有使用新数据更新,例如 Id 的输入保持为 0 :

<input type="text" id="Id_@localId" name="Id" asp-for="Id" readonly />

但输入的 id 更新为新创建的 id 号。为什么会发生这种情况,我能做些什么吗?

解决方法

你有一个错误。修复最后一次返回

 return PartialView(modal,model);
,

Id 是主键吗?如果是这样,不建议更改主键,您应该添加一个新列作为键。

数据已发布到数据库并正确保存,但模型似乎没有使用新数据更新

这可能是由并发问题引起的。我现在看不到你的更新代码,但你可以

尝试像这样更改您的更新代码:

 public async Task<IActionResult> Process_Requirement(Requirement model)
    {
        string modal = "_Form_Requirement";
        if (model.Id == 0)
        {
            //....
        }
        else //to update
        {
            await  TryUpdateModelAsync<Requirement>(_context.Requirements.FirstOrDefault(x => x.RId ==model.RId),"",c => c.Id,c => c.CreatedUser);
            _context.SaveChanges();
            return PartialView(modal,model);     
        }
        return PartialView(modal);
    }

我的模型:

public class Requirement
{
    [Key]
    public int RId { get; set; } //new column
    public int Id { get; set; }
    public string CreatedUser { get; set; }
}

部分地,传递带有隐藏字段的密钥:

<input type="text" asp-for="RId" hidden/>
<input type="text" id="Id_@localId" name="Id" asp-for="Id"  />
<input type="text" id="CreatedUser_@localId" asp-for="CreatedUser" />

结果:

enter image description here