【问题标题】:passing parameter in ajax gets null value在ajax中传递参数得到空值
【发布时间】:2016-09-25 16:26:31
【问题描述】:

我正在使用 ajax 调用动作控制器,但是当动作控制器接收到它时,我使用 data 属性传递的参数始终为空... 这里会发生什么?

jQuery 函数:

function PostOrder()
{      
    var id = $(".aslink").data("customerid");
    var url = $("#btnAddOrderPost").data("url_add_order");       
    $.ajax({
        type:"post",
        url: url,
        data: JSON.stringify( { orderVM: $("#frmCreatePV").serialize()}),
        datatype: "json",
        contentType: "application/json",
        success: function () {
            alert("it was inserted");
        }
    })
}

动作控制器:

[HttpPost]
   // [ValidateAntiForgeryToken]
    public ActionResult CreatePV(OrderVM orderVM)
    {
        if (ModelState.IsValid)
        {
            List<string> top = new List<string>();
            decimal tempPrice = 0M;
            for (int i = 0; i < orderVM.Toppings.Count; i++)
            {
                if (orderVM.Toppings[i].IsSelected == true)
                {
                    top.Add(orderVM.Toppings[i].SpecificTopping);
                    tempPrice += orderVM.Toppings[i].Price;
                }
            }
            Order order = new Order
            {                 
                Toppings = top,
                TotalPrice = tempPrice
            };
            db.Orders.Add(order);
            db.SaveChanges();
            return RedirectToAction("Index");
        }            
        return View(orderVM);
    }

这是我使用这种类型参数的 OrderVM ViewModel:

public class OrderVM
{           
    public virtual List<ToppingVM> Toppings { get; set; }
    public decimal TotalPrice { get; set; }
}

这是包含在部分视图中的表单:

@using (Html.BeginForm(null,null,FormMethod.Post, htmlAttributes: new { @id="frmCreatePV"}))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @{
                for (int i = 0; i < Model.Toppings.Count; i++)
                {
                    <div class="col-xs-4">
                        @Html.HiddenFor(model => model.Toppings[i].SpecificTopping)                       
                        @Html.CheckBoxFor(model => model.Toppings[i].IsSelected, htmlAttributes: new { data_price = Model.Toppings[i].Price, @id = "chbkPrice" })                      
                        @Html.HiddenFor(model => model.Toppings[i].Price)
                         @Html.LabelFor(model => model.Toppings[i].IsSelected , Model.Toppings[i].SpecificTopping)                        
                        <p>Price: @Model.Toppings[i].Price</p>
                    </div>
                }
            }
        </div>
        <div class="form-group">
            <div class="col-md-10">
                <input type="button" value="Add order" id="btnAddOrderPost" class="btn btn-primary"
                       data-url_add_order="@Url.Action("CreatePV", "Orders")" />
            </div>
        </div>
    </div>
                }

更新

最后这就是 Action Controller 的样子:

  [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult CreatePV(OrderVM orderVM)
    {
        int id = Convert.ToInt32(TempData["License"]);
        if (ModelState.IsValid)
        {
            List<string> top = new List<string>();
            decimal tempPrice = 0M;
            for (int i = 0; i < orderVM.Toppings.Count; i++)
            {
                if (orderVM.Toppings[i].IsSelected == true)
                {
                    top.Add(orderVM.Toppings[i].SpecificTopping);
                    tempPrice += orderVM.Toppings[i].Price;
                }
            }
            Order order = new Order
            {
                Customer = db.Customers.Where(c => c.LicenseNumber == id).First(),
                LicenseNumber = id,
                Toppings = top,
                TotalPrice = tempPrice
            };
            db.Orders.Add(order);
            db.SaveChanges();
            return Json(new { success= true, JsonRequestBehavior.AllowGet});
        }           
        return Json(new { success = false, JsonRequestBehavior.AllowGet});
    }

还有 JQuery 函数,注意我使用了 serializeArray() 向未绑定到 html 表单的数据中添加了一个元素:

function PostOrder()
{
    var orderVM = {};   
    id = $(".aslink").data("customerid");
    alert($("#btnGetOrderAdd").data("customerid"));
    var url = $("#btnAddOrderPost").data("url_add_order");
    var datavar = $("#frmCreatePV").serializeArray();
    datavar.push({name: "LicenseNumber" ,value : id})  
    $.ajax({
        type:"post",
        url: url,       
        data: datavar,
        datatype: "json",      
        success: function () {
            alert("it was inserted");
        }
    })
}

【问题讨论】:

  • 尝试删除 contentType。并尝试使用控制台进行调试,它确实在传递给 ajax 之前出现在 jquery 上
  • @Loading.. 我删除了 contentType,现在可以工作了,为什么?您可以发布答案,我会接受的
  • 删除contentType 选项不可能工作,除非您也将data 选项更改为data: $("#frmCreatePV").serialize(), 并删除datatype: "json",(并将其更改为dataType: "html")。不知道为什么您接受了一个似乎与 PHP 有关的错误答案。而return RedirectToAction("Index"); 不可能工作 - 你进行 ajax 调用并且 ajax 调用永远不会重定向。
  • 因为您在编辑之前的代码返回的是视图 (html) 而不是 json。但是既然您返回了JsonResult,那么您可以将其保留为datatype:"json"
  • 请注意,您应该避免使用.serializeArray()(如果您在视图中使用了CheckBoxFor(),它将无法正常工作)。最好使用.serialize(),如果你想添加其他值,你可以使用$.param()(例如参考this answer)或者你可以简单地为LicenseNumber添加一个隐藏的输入,所以它会被序列化

标签: c# jquery ajax asp.net-mvc razor


【解决方案1】:

删除 contentType 对你有用。

contentType 是您要发送的数据类型,所以 application/json; charset=utf-8 是常见的,application/x-www-form-urlencoded 也是如此; charset=UTF-8,这是默认值。

当使用contentType: 'application/json' 时,您将无法依赖 $_POST 被填充。 $_POST 仅用于表单编码的内容类型。

在这种情况下,您可以访问 PHP 原始数据。

$input = file_get_contents('php://input');
$object = json_encode($input);

希望对你有帮助:)

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 2021-04-17
    • 2011-06-13
    • 1970-01-01
    • 2014-07-12
    • 2018-05-15
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多