MVC Ajax.BeginForm - 模型有效且数据已添加到数据库但不断触发 OnFailure

MVC Ajax.BeginForm - Model valid and data added to dbase but constantly triggering OnFailure

我已经筋疲力尽了。我试图在部分视图中使用 Ajax 表单更新页面中的联系人列表,但我一直遇到这个奇怪的错误。对于我的生活,我无法理解为什么会发生这种情况,因为这个动作几乎是我项目中另一个 form/action 组合的克隆,而且那个组合有效!!

当我提交表单时,我一直在用调试器跟踪它。模型 IsValid 并成功将数据保存到数据库。尽管如此,表单还是会触发 OnFailure 方法。在 Chrome 控制台中的进一步探测显示我正在调用

的操作收到 500 服务器错误

我无法理解这是怎么回事,因为我正在将正确的模型发送到控制器操作;调试器显示它是有效的,我的表单数据毕竟正在保存在数据库中。

这是模型

public class ClientContact
{
    public int Id { get; set; }
    public int ClientId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Position { get; set; }
    public string Email { get; set; }
    public string Telephone { get; set; }
    //public virtual Client Client { get; set; }
}

这是我调用的控制器动作

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateContact([Bind(Include = "Id,ClientId,FirstName,LastName,Position,Email,Telephone")] ClientContact clientContact)
    {
        if (ModelState.IsValid)
        {
            db.ClientContacts.Add(clientContact);
            db.SaveChanges();
            return PartialView("AddCanNote", new ClientContact { ClientId = clientContact.ClientId });
        }
        return new EmptyResult();
    }

这是我的局部视图

@model _3KB.Entities.Client_Entities.ClientContact

<div id="clientContactTarget">
<div class="row-fluid">
    <div class="span6">
        @{Html.RenderAction("ContactsForClient", "ClientContacts", new { clientId = Model.ClientId });}
    </div>
    <div class="span6">
        <h5>Add New Contact</h5>
        <hr/>
        @using (Ajax.BeginForm("CreateContact", "ClientContacts", null, new AjaxOptions
        {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "clientContactTarget",
            OnSuccess = "SuccessContact",
            OnFailure = "FailureContact"
        }))
        {
            @Html.AntiForgeryToken()
            <div class="row-fluid">
                <div class="span6">
                    <div class="control-group">
                        @Html.HiddenFor(m => m.Id)
                        @Html.HiddenFor(m => m.ClientId)
                        @Html.Label("First Name")
                        @Html.TextBoxFor(m => m.FirstName)
                    </div>
                </div>
                <div class="span6">
                    <div class="control-group">
                        @Html.Label("Surname")
                        @Html.TextBoxFor(m => m.LastName)
                    </div>
                </div>
            </div>
            <div class="row-fluid">
                <div class="span4">
                    <div class="control-group">
                        @Html.Label("Position")
                        @Html.TextBoxFor(m => m.Position)
                    </div>
                </div>
                <div class="span4">
                    <div class="control-group">
                        @Html.Label("Telephone")
                        @Html.TextBoxFor(m => m.Telephone)
                    </div>
                </div>
                <div class="span4">
                    <div class="control-group">
                        @Html.Label("Email")
                        @Html.TextBoxFor(m => m.Email)
                    </div>
                </div>
            </div>
            <div class="row-fluid">
                <div class="span12">
                    <div class="control-group">
                        <input type="submit" value="Add Contact" class="btn blue"/>
                    </div>
                </div>
            </div>
        }
    </div>
</div>

我在父视图中用

调用它
@Html.Partial("AddClientContact", new ClientContact {ClientId = Model.Id })

我一整天都在看这个。我以为我会弄明白,但我想我已经看得太久了。

有没有人遇到过类似的问题?

欢迎任何建议或建议

谢谢

首先,引发异常的操作不会导致回滚操作中之前完成的任何操作。由于在视图处理之前不会引发异常(这是响应管道中最后发生的事情之一)所有内容都将被保存,这样就很好了。

其次,如果操作 returns 500,OnFailure 将被命中。没关系,它完成了它负责的所有核心工作(写入数据库等)很好,它仍然返回 500,因此失败。

最后,异常非常明确。在某处,您将 ClientContact 传递给仅接受 CandidateComment 的视图。一个常见的原因是在另一个视图中加载部分内容,而忽略显式传递模型。例如,假设您有一个视图 Foo.cshtml,其模型声明为 CandidateComment。如果您要在模型为 ClientContact 的视图中执行以下操作:

@Html.Partial("Foo")

您实际上是在将 ClientContact 实例从主视图传递到该局部视图,就像您要执行的操作一样:

@Html.Partial("Foo", Model)

总而言之,查看为该操作呈现视图所涉及的所有视图。找到包含 CandidateComment 的模型声明行的那个,然后确保在调用它时将 CandidateComment 实例传递给它。