【问题标题】:Ajax POST has null entry for parameter [assetID]?Ajax POST 有参数 [assetID] 的空条目?
【发布时间】:2015-02-24 17:19:08
【问题描述】:

我正在使用GridMVC 在我的一个网格列中呈现一个按钮,以充当资产上的验证按钮。基本上当点击按钮时,我想根据ID在数据库中找到相关资产并将[verified_date]设置为DateTime.Now

columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="#" class="btn btn-default btn-sm noDecoration" onclick="verifyAsset(@o.Id)"><span class="glyphicon glyphicon-ok"></span> @*View*@</a>).SetWidth(15);

使用上面的超链接标签,我正在调用我的verifyAsset() javascript 函数:

@section Scripts {

    <script type="text/javascript">
        function verifyAsset(assetID) {
            alert("The assetID is: " + assetID);
            var data = { verified_date: assetID };
            alert("Got this far...");
            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("verifyAsset", "INV_Assets")',
                data: data,
                success: function (resp) {
                    alert("Success! Asset " + resp.ID + " successfully verified on " + resp.VDate);
                },
                error: function (resp) {
                    alert("There was an error verifying this Asset...");
                }
            });
        }
    </script>
}

但是,当我尝试运行该功能时,我的 ajax 始终是 erroring 并且我的控制器操作 verifyAsset() 上的断点永远不会到达:

    [HttpPost]
    public JsonResult verifyAsset(int assetID)
    {
        INV_Assets asset = db.INV_Assets.Find(assetID);
        asset.verified_date = DateTime.Now;

        try
        {
            if (ModelState.IsValid)
            {
                db.SaveChanges();
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = asset.Id, VDate = asset.verified_date }, JsonRequestBehavior.AllowGet);
    }

我的Elmah 日志中返回的错误是:The parameters dictionary contains a null entry for parameter 'assetID' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.JsonResult verifyAsset(Int32)' in 'InventoryTracker.Controllers.INV_AssetsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

谁能发现我可能出错的地方?在我的脚本的第一个alert() 中,我已经确认正确的ID 值被传递给变量assetID 中的函数,但是我注意到如果我尝试将data 设置为:var data = { verified_date: @Convert.ToInt32(assetID) }; assetID 标记为 not exist in the current context...?


编辑

以下是我以前工作过的类似代码:

脚本

    $('#submitNewModel').click(function () {
        var form = $(this).closest('form');
        var data = { description: document.getElementById('textNewModel').value };
        //var data = { model_description: document.getElementById('textNewModel').value, created_date: @DateTime.Now, created_by: @System.Environment.UserName };
        $.ajax({
            type: "POST",
            dataType: "JSON",
            url: '@Url.Action("createNewModel", "INV_Assets")',
            data: data,
            success: function (resp) {
                $('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
                form[0].reset();
                $('#createModelFormContainer').hide();
            },
            error: function () {
                alert("ERROR!");
            }
        });
    });

INV_AssetsController - createNewModel()

    [HttpPost]
    public JsonResult createNewModel(string description)
    {
        INV_Models model = new INV_Models()
        {
            // ID auto-set during save.
            model_description = description,
            created_date = DateTime.Now,
            created_by = System.Environment.UserName
        };

        try
        {
            if (ModelState.IsValid)
            {
                db.INV_Models.Add(model);
                db.SaveChanges();
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = model.Id, Text = model.model_description }, JsonRequestBehavior.AllowGet);
    }

在查看了gutsmania 的答案后,我意识到他确实是正确的,我已经在精神上跳了枪,宣布我的data 字段作为verified_date 传递,而我只想传递ID值到我的控制器操作中的预期参数。由于verification_date 不等于assetID(预期参数),因此该操作从未被实际调用并以NULL 失败。

更新代码如下:

脚本

<script type="text/javascript">
    function verifyAsset(assetID) {
        alert("The assetID is: " + assetID);
        var data = { asset_ID: assetID };
        alert("Got this far...");
        $.ajax({
            type: "POST",
            dataType: "JSON",
            url: '@Url.Action("verifyAsset", "INV_Assets")',
            data: data,
            success: function (resp) {
                alert("Success! Asset " + resp.ID + " successfully verified on " + resp.VDate);
            },
            error: function (resp) {
                alert("There was an error verifying this Asset...");
            }
        });
    }
</script>

INV_AssetsController - verifyAssets()

    [HttpPost]
    public JsonResult verifyAsset(int asset_ID)
    {
        INV_Assets asset = db.INV_Assets.Find(asset_ID);
        asset.verified_date = DateTime.Now;

        try
        {
            if (ModelState.IsValid)
            {
                db.SaveChanges();
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = asset.Id, VDate = asset.verified_date }, JsonRequestBehavior.AllowGet);
    }

【问题讨论】:

    标签: c# jquery json asp.net-mvc asp.net-mvc-5


    【解决方案1】:

    首先,这可能行不通。

    var data = { verified_date: @Convert.ToInt32(assetID) };
    

    除非您将assetID 限定为服务器端变量(并且错误消息似乎表明您没有)。您不能在 JS 对象上使用 Razor 助手。这就是错误消息所指示的全部内容。

    其次,您正在敲击控制器,这很好,但它没有拾取您的参数,这很糟糕。

    我会看看这一行:

                var data = { verified_date: assetID };
    

    您的控制器正在寻找一个名为assetID 的变量,并且您正在向它传递一个名为verified_date 的东西。我目前没有可用的 VS 进行仔细检查,但我知道当预期的参数名称与通过 ajax 请求传入的参数名称之间存在脱节时,我遇到了这类问题。使用 Fiddler 或其他类似工具检查您实际发送的内容,但由于您没有在 ajax 调用中明确设置 contentType,因此您的消息正文可能类似于 verify_date=someValue 并且您的控制器看不到实际它正在寻找的参数,所以它只需要 NULL。

    【讨论】:

    • 你是对的! (见上面的编辑)。唯一奇怪的是我的最后一个警报alert("Success! Asset " + resp.ID + " successfully verified on " + resp.VDate); 返回Success! Asset 1 succesfully verified on /Date(1424805494397)/,但无论如何它会将2/24/2015 1:18:14 PM 保存在我的数据库中,所以一切都很好。您是否偶然对我如何修改(成功)按钮的颜色以从 default 更改为绿色 success 类有任何想法?理想情况下,我想在加载时设置整个表单,以将过去 3 个月内验证的表单显示为绿色,并将所有其他表单显示为默认值,除非更新。
    • 这样的?成功:function(){ $('#myButton').addClass('success'); }
    【解决方案2】:

    通常我如何处理对服务器的请求是使用像postman 这样的工具来测试它。这将允许您在没有代码的情况下使 Post 调用正常工作。我只会使用表单数据的键值对,然后像这样标记您的调用:

    [HttpPost]
    [Route("{assetID}")]
    public JsonResult verifyAsset(int assetID)
    {
    

    这应该会为您服务。然后你需要把你从邮递员那里学到的东西用 javascript 做同样的事情。

    编辑: 从评论中删除了“首先我不会使用 JSON 将您的 ID 发布到服务器”。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多