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

Why has my unobtrusive ajax stopped updating my partial view in ASP.NET Core 3.1?

提问人:Yanayaya 提问时间:5/6/2021 更新时间:5/6/2021 访问量:121

问:

我在剑道窗口中使用不显眼的 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>

提交表单后,控制器操作将执行以下操作:

/首页/ 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 号。为什么会发生这种情况,我能做些什么吗?

ajax 实体框架 asp.net-core unobtrusive-ajax

评论

0赞 Serge 5/6/2021
你能发布UpdateRequirement metod吗?

答:

0赞 Serge 5/6/2021 #1

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

 return PartialView(modal,model);
0赞 Jerry Cai 5/6/2021 #2

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