【问题标题】:Unable to post data to controller's action method using Ajax call无法使用 Ajax 调用将数据发布到控制器的操作方法
【发布时间】:2018-02-06 11:09:09
【问题描述】:

我正在尝试将Partial 视图的数据发布到服务器以将输入字段结果保存到数据库,然后返回到相同的(作为模式对话框打开的部分视图)或返回到父视图称为模态对话框。

但由于某种原因,我没有在控制器中获取从 ajax 方法调用发送的 Action 方法的参数(即weldMaster)。

这是我的控制器方法。

    // GET: WeldMasters/Details/5
    public ActionResult Details(int? ids, bool isPartials = false)
    {
        if (ids == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        WeldMaster weldMaster = db.WeldMasters.Find(ids);
        ViewBag.Readonly = false;
        if (weldMaster == null)
        {
            return HttpNotFound();
        }
        if(isPartials)
            return PartialView(weldMaster);
        else
            return View(weldMaster);
    }

    // POST: WeldMasters/Details/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult Details**(WeldMaster weldMaster)** 
    //{"The parameter conversion from type 'System.String' to type 'IMCC_PAS.Entities.WeldMaster' failed because no type converter can convert between these types."}
    {
        var success = 0;
        if (ModelState.IsValid)
        {
            success = 1;
            db.Entry(weldMaster).State = EntityState.Modified;
            db.SaveChanges();
            return Json(new { success });
        }
        return Json(new { success });
    }

这里是ajax代码

    <script type="text/javascript">
    $(document).ready(function () {
        $(".saveBtn").click(function (e) {
            debugger;
            var token = $('input[name="__RequestVerificationToken"]').val();
            // If I dont pass the token in the `data` parameter of ajax, then action method of controller is not called at all.            
e.preventDefault();
            $.ajax({

                type: "POST",
                url: '@Url.Action("Details", "WeldMasters")',
                data: { __RequestVerificationToken: token, weldMaster: $('#__AjaxAntiForgeryForm').serialize() },
                success: function (result) {
                    alert(result);
                },
                failure: function (response) {
                    alert(result.responseText);
                },
                error: function (response) {
                    alert(result.responseText);
                }
            });
        });
    });
</script>

这里是局部视图的模态

@model IMCC_PAS.Entities.WeldMaster

这是表格

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.id)

        <div class="row">
            <div class="col-md-3 col-sm-12">
                @Html.LabelFor(model => model.weld_no, htmlAttributes: new { @class = "control-label" })
            </div>
            <div class="col-md-3 col-sm-12">
                @Html.LabelFor(model => model.rep_no, htmlAttributes: new { @class = "control-label" })
            </div>
            <div class="col-md-3 col-sm-12">
                @Html.LabelFor(model => model.length, htmlAttributes: new { @class = "control-label" })
            </div>
            <div class="col-md-3 col-sm-12">
                @Html.LabelFor(model => model.normal_size, htmlAttributes: new { @class = "control-label" })
            </div>
        </div>
        <div class="row">
            <div class="col-md-3  col-sm-12">
                @Html.EditorFor(model => model.weld_no, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } } : new { htmlAttributes = new { @class = "form-control" } })
            </div>
            <div class="col-md-3  col-sm-12">
                @Html.EditorFor(model => model.rep_no, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } } : new { htmlAttributes = new { @class = "form-control" } })
            </div>
            <div class="col-md-3  col-sm-12">
                @Html.EditorFor(model => model.length, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } } : new { htmlAttributes = new { @class = "form-control" } })
            </div>
            <div class="col-md-3  col-sm-12">
                @Html.EditorFor(model => model.normal_size, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } } : new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div> 

        <div class="form-group modal-footer">
            <div class="col-md-12">
                <a class="saveBtn" href="javascript:void(0);">Edit</a>
            </div>
        </div>

    </div>
}

编辑: 这是父视图,其中包含用于显示焊接细节的选择参数。然后焊接细节显示在一个 div 中(用于只读目的),并且可以在单击按钮时在弹出的模式对话框中进行编辑。

    <script>
    $(document).ready(function () {

        ... more code for other dropdowns here

        //When Wled No is changed, reload Weld Details in its respective Partial view
        $("#weldddl").change(function () {

            var parameter = { ids: $("#weldddl").val(), isPartials: true };
            $.ajax({
                url: '/WeldMasters/Details/',
                type: 'GET',
                data: parameter,
                success: function (result) {
                    var div = $('#weldDetails');
                    div.html('');
                    div.html(result);
                }
            });
        });

        $(".editWeldBtn").click(function () {
            //debugger;
            $('#MyModal').empty();
            $('#MyModal').append(GetModalDialog());
            var link = '@Url.Action("Details", "WeldMasters")';
            data = { ids: $("#weldddl").val(), isPartials: true };
            LaunchModalDlg(link, data, "View Weld Master Information", "75%");
        });

    });
</script>

<h4>Index</h4>
<script src="~/Scripts/MyScripts.js"></script>
<p>
    @Html.ActionLink("Create New", "Create") | 
    <a class="editWeldBtn" href="javascript:void(0);">Edit</a>
</p>
<div class="row">
    <div class="col-sm-3">
        @Html.LabelFor(model => model.Discipline, htmlAttributes: new { @class = "control-label col-md-12" })
        <div class="col-md-12">
            @Html.DropDownListFor(model => model.Discipline, (SelectList)ViewBag.disciplines, htmlAttributes: new { @class = "form-control", @id = "disciplineddl" })
            @Html.ValidationMessageFor(model => model.Discipline, "", new { @class = "text-danger" })
        </div>

        @Html.LabelFor(model => model.DrawingNo, htmlAttributes: new { @class = "control-label col-md-12" })
        <div class="col-md-12">
            @Html.DropDownListFor(model => model.DrawingNo, (SelectList)ViewBag.drawings, htmlAttributes: new { @class = "form-control", @id = "drawingddl" })
            @Html.ValidationMessageFor(model => model.DrawingNo, "", new { @class = "text-danger" })
        </div>

        @Html.LabelFor(model => model.ComponentNo, htmlAttributes: new { @class = "control-label col-md-12" })
        <div class="col-md-12">
            @Html.DropDownListFor(model => model.ComponentNo, (SelectList)ViewBag.components, htmlAttributes: new { @class = "form-control", @id = "componentddl" })
            @Html.ValidationMessageFor(model => model.ComponentNo, "", new { @class = "text-danger" })
        </div>

        @Html.LabelFor(model => model.WeldNo, htmlAttributes: new { @class = "control-label col-md-12" })
        <div class="col-md-12">
            @Html.DropDownListFor(model => model.WeldNo, (SelectList)ViewBag.components, htmlAttributes: new { @class = "form-control", @id = "weldddl" })
            @Html.ValidationMessageFor(model => model.WeldNo, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="col-sm-9" id="weldDetails"> <!--This is for showing the partial view for showing weld details-->
    </div>
    <div id="MyModal"></div> <!--This is for pop up modal dialog-->
</div>

【问题讨论】:

  • 它只是data: $('#__AjaxAntiForgeryForm').serialize(), - serialize() 方法序列化所有表单控件,包括令牌
  • 你传递了weldMaster: $('#__AjaxAntiForgeryForm').serialize()weldMaster 本身是一个视图模型参数 - $('#__AjaxAntiForgeryForm').serialize() 足以序列化表单内容。

标签: javascript jquery asp.net ajax asp.net-mvc


【解决方案1】:

如果您要序列化完整的表单,则无需显式发送防伪令牌。

使用这个:

 data: $('#__AjaxAntiForgeryForm').serialize(),

【讨论】:

  • 有了这个,我确实在 action 方法中得到了weldMaster,但只使用了发布的原始值。更改后的值不显示
  • @WAQ。 .serialize() 序列化表单控件的值,因此如果您获得原始值,则意味着您没有在视图中编辑任何内容
  • @StephenMuecke 你是对的。我刚刚发现问题在于我在应用程序中放置控件的方式。我的主视图有选择参数(下拉菜单)。然后在做出正确的选择后,焊接的详细信息将显示在一个 div 中(其中包含一个部分视图)。这是只读的 div。但是有一个按钮在弹出模式对话框中显示相同的局部视图。如果我在父视图上有 div 和部分对话框,则内容不会被发回控制器。如果我删除两个之一,那么它工作正常。你能看到问题中的更新吗?
  • @WAQ,你把我弄糊涂了。你是说div class="col-sm-9" id="weldDetails"&gt;&lt;div id="MyModal"&gt;&lt;/div&gt; 都包含你展示的部分吗?如果是这样,你为什么要这样做(但它解释了为什么 - 因为重复的 id 属性是无效的 html,而 $('#__AjaxAntiForgeryForm') 只会得到第一个(来自第一个 &lt;div&gt;,而不是模态)
  • @StephenMuecke 是的,我们的要求是在 div 中显示为只读给那些没有编辑权限的用户和弹出模式给那些可以编辑的用户。实现这一目标的正确方法是什么?对不起,我不明白你提到的这个重复的 id 东西?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 2016-06-21
  • 2020-10-13
  • 2012-05-06
  • 2019-03-30
相关资源
最近更新 更多