ASP.NET MVC4中的AJAX.BeginForm的AjaxOptions OnSuccess未被调用

9
我正在尝试在使用Razor的MVC4中使用Jquery Model Dialog,对话框显示正常,但是单击更新按钮后AjaxOptions.OnSuccess JavaScript函数不会调用,而是重定向到http://<>:3738/Cars/Edit/1?Length=4,我不知道为什么会发生这种情况。
以下是我的代码:

CarController.cs

public class CarsController : Controller
{
    private ExpDb db = new ExpDb();

    //
    // GET: /Cars/

    public ActionResult Index()
    {
        return View(db.Cars.ToList());
    }



    //
    // GET: /Cars/Edit/5

    public ActionResult Edit(int id = 0)
    {
        CarModel carmodel = db.Cars.Find(id);
        if (carmodel == null)
        {
            return HttpNotFound();
        }
        return PartialView(carmodel);
    }

    //
    // POST: /Cars/Edit/5

    [HttpPost]
    public JsonResult  Edit(CarModel carmodel)
    {
        if (ModelState.IsValid)
        {

            db.Entry(carmodel).State = EntityState.Modified;
            db.SaveChanges();
            //return RedirectToAction("Index");
             return Json(JsonResponseFactory.SuccessResponse(carmodel),JsonRequestBehavior.DenyGet);
        }
      else {
            return Json(JsonResponseFactory.ErrorResponse("Please review your form"), JsonRequestBehavior.DenyGet);
        }
    }

Index.cshtml

@model IEnumerable<AjaxSamples.Models.CarModel>

@{
ViewBag.Title = "Index";
}
<div id="commonMessage"></div>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
    <th>
        @Html.DisplayNameFor(model => model.ImageFileName)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Name)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Description)
    </th>
    <th></th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.ImageFileName)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Name)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Description)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { @class = "editLink" }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })

        <button id="opener">Open Dialog</button>
    </td>
  </tr>



 }

</table>

 <div id="updateDialog" title="Update Car"></div>
 <script type="text/javascript">
 var linkObj;
 $(function () {
    $(".editLink").button();

    $('#updateDialog').dialog({
        autoOpen: false,
        width: 400,
        resizable: false,
        modal: true,
        buttons: {
            "Update": function () {
                $("#update-message").html(''); //make sure there is nothing on the message before we continue                         
                $("#updateCarForm").submit();
            },
            "Cancel": function () {
                alert('sd');
                $(this).dialog("close");
            }
        }
    });

    $(".editLink").click(function () {
        //change the title of the dialog
        linkObj = $(this);
        var dialogDiv = $('#updateDialog');
        var viewUrl = linkObj.attr('href');
        $.get(viewUrl, function (data) {
            alert(data);
            dialogDiv.html(data);
            //validation
            var $form = $("#updateCarForm");
            // Unbind existing validation
            $form.unbind();
            $form.data("validator", null);
            // Check document for changes
            $.validator.unobtrusive.parse(document);
            // Re add validation with changes
            $form.validate($form.data("unobtrusiveValidation").options);
            //open dialog
            dialogDiv.dialog('open');
        });
        return false;
    });

});
function err(data) {
    alert(data);
}


 function updateSuccess(data) {
    alert(data);
}

Edit.cshtml

@model AjaxSamples.Models.CarModel

@{
ViewBag.Title = "Edit";
}

@using (Ajax.BeginForm("Edit", "Cars", new AjaxOptions
    {
        InsertionMode = InsertionMode.Replace, 
        HttpMethod = "POST",
        OnSuccess = "updateSuccess"
    }, new { @id = "updateCarForm" }))
 {
 @Html.ValidationSummary(true)
<div id="update-message" class="error invisible"></div>
<fieldset>
    <legend>CarModel</legend>

    @Html.HiddenFor(model => model.Id)

    <div class="editor-label">
        @Html.LabelFor(model => model.ImageFileName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.ImageFileName)
        @Html.ValidationMessageFor(model => model.ImageFileName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Description)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

2
你是否在页面中将jquery.unobtrusive-ajax.js添加到jquery.js之后? - Alex
是的,我在_Layout.cshtml中完成了它。 - ravikumar
1
你解决了问题吗?我在我的应用程序中也遇到了同样的问题。 - Tamas Ionut
7个回答

19
以下是需要的jQuery文件:

jquery.unobtrusive-ajax.js


2
这对我有用。它不是默认包含在mvc5模板中的。 - decompiled
2
谢谢。你节省了我的时间。 - Nimit Joshi
1
我花了好几个小时来尝试让 Ajax.BeginForm 正常工作。你的帖子为我解决了这个问题。 - Baxter

13
我遇到的问题是在 $(document).ready() 内声明了 success 函数。我将其移到外部后就可以了。

i.e.:

@using (Ajax.BeginForm("DialogTest", "Main", new AjaxOptions { HttpMethod = "Post", OnSuccess = "ajaxSuccess" }))
{
    <input type="button" id="info" value="Info" />
    <input type="button" id="confirm" value="Confirm" />
    <input type="button" id="wait" value="Wait" />
    <input type="button" id="ask" value="Ask" />
    <br /><br />
    <input type="submit" value="Submit" />
}



@section Scripts
{
    <script type="text/javascript">

        var ajaxSuccess = function () {
            alert('this is ajaxSuccess');
        }


        $(document).ready(function () {
            // do not declare ajaxSuccess here

            $('#mainForm').submit(function () {
                radarApp.InfoDialog("form submitted.");
                return false;
            });

// snip

谢谢。救命稻草! - Stephen McCormick
这并不显而易见!谢谢 - davaus

1

您需要在BeginForm调用中添加一个参数:

Ajax.BeginForm("Edit","Cars", null, new AjaxOptions
               {
                   InsertionMode = InsertionMode.Replace,
                   HttpMethod = "POST",
                   OnSuccess = "updateSuccess"
               }, new { @id = ""updateCarForm })

null是用于RouteValueDictionary的。这里列出了Ajax.BeginForm方法的所有重载。


谢谢您的回复。我已经替换了代码,但问题仍然存在。 - ravikumar
我在这里上传了完整的源代码供您使用 [链接]http://rvmicro.com/Ajaxsamples.rar - ravikumar

1

请尝试:

@using (Ajax.BeginForm("Edit", new {controller = "Cars"}, new AjaxOptions


1
我遇到了同样的问题。最初我把脚本放在了局部视图的头部区域... 这导致了我的问题。
我把它移到了承载我的局部视图的视图头部,一切都正常工作了。我的视图是一个托管在MVC应用程序中的Bootstrap页面,布局设置为:"Layout = Nothing"。如果您的控制器操作正在加载视图,则jquery.unobtrusive-ajax.js位置肯定存在问题...


0
你可以在 Script 标签内直接使用 Post 方法来调用控制器方法,例如:
@using (Html.BeginForm("Edit", "Cars", FormMethod.Post, new { id = "updateCarForm" }))
{
  .......Yourdata......
}

然后在Jquery中

function PostForm(url) {
    $("#updateCarForm").valid();
    if ($("#updateCarForm").valid()) {
    $.post(url, $("#updateCarForm").serialize(), function (data) { updateSuccess(data); });
    }
}

感谢您的快速回复。但是当前代码的实际问题是什么? - ravikumar
你为什么要将OP的Ajax.BeginForm()更改为Html.BeginForm() - rexcfnghk
在我的建议中,我没有使用Ajax,而是建议他使用Post方法的其他解决方案,因此我在那里放置了Html.BeginForm() - Anand Thakkar

0

@Alex的代码中有语法错误,应该这样才能正常工作:

Ajax.BeginForm("Edit","Cars", null, new AjaxOptions
           {
               InsertionMode = InsertionMode.Replace,
               HttpMethod = "Post",
               OnSuccess = "updateSuccess"
           }, new { id = "updateCarForm" })
{ /* Razor code */ }

具体来说,您应该查看Ajax.BeginForm()this重载。


仍然无法工作,我已将完整的源代码上传给您[链接]http://rvmicro.com/Ajaxsamples.rar - ravikumar
@ravikumar,哪里出了问题?有没有抛出异常?脚本错误?使用Google Chrome或Fiddler的调试工具以提供更多详细信息。 - rexcfnghk
没有任何异常被抛出,它只是重定向到 http://localhost:3738/Cars/Edit/1?Length=4 并提供 JSON 数据。 - ravikumar
你有包含 null 吗?如果有,它不应该带着查询字符串重定向。 - rexcfnghk
是的,我做了,它重定向了但没有查询字符串,但“updateSuccess”JavaScript没有被调用。 - ravikumar
我已经找到了问题所在。它是与之前使用的Jquery版本有关,我之前使用的是jquery1.9.1.js,现在我已经更改为jquery-1.7.1.js。它现在可以正常工作了。但我不明白为什么高版本的jquery会导致这个问题。 - ravikumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接