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

时间:2016-05-25 16:43:00

标签: c# asp.net-mvc entity-framework asp.net-ajax

我正处于我的束缚之中。我试图在部分视图中使用Ajax表单更新页面中的联系人列表,并且我一直在遇到这个奇怪的错误。对于我的生活,我无法理解为什么会发生这种情况,因为这个动作几乎是我项目中另一个表单/动作组合的克隆,并且一个有效!!

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

上收到500服务器错误

The Offending Error

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

这是模型

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 })

我一整天都在看这个。我以为我会搞清楚,但我想我已经看了太久了。

有没有人遇到类似问题?

欢迎任何建议或建议

由于

1 个答案:

答案 0 :(得分:1)

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

其次,如果操作返回500,OnFailure将被点击。它完成所有负责的核心内容(写入数据库等)并不重要,它是&#39 ; s仍然返回500,所以它失败了。

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

@Html.Partial("Foo")

事实上,您实际上是将ClientContact实例从主视图传递到该部分,就像您要做的那样:

@Html.Partial("Foo", Model)

长和短,查看渲染此操作视图所涉及的所有视图。找到包含CandidateComment的模型声明行的那个,然后确保在调用它时将其传递给CandidateComment实例。