C# 来自具有IEnumerable model/viewmodel的razor视图的多个ajax请求

C# 来自具有IEnumerable model/viewmodel的razor视图的多个ajax请求,c#,asp.net-mvc,razor,ajax.beginform,C#,Asp.net Mvc,Razor,Ajax.beginform,在我的ASP.NETMVC项目中,我有以下ViewModel public class ApproveItemViewModel { [Required] public int ItemId { get; set; } [Required] public string ItemCode { get; set; } } 在控制器中我有以下两种方法 [HttpGet] public ActionResult List

在我的ASP.NETMVC项目中,我有以下ViewModel

public class ApproveItemViewModel
{
        [Required]
        public int ItemId { get; set; }

        [Required]
        public string ItemCode { get; set; }
}
在控制器中我有以下两种方法

    [HttpGet]
    public ActionResult ListPendingItems()
    {
        var items = new List<ApproveItemViewModel>();
        //add few items here in above list
        return View(vms);
    }

    [HttpPost]
    public JsonResult ApproveItem(ApproveItemViewModel viewmodel)
    {
        return Json(new { success = success }, JsonRequestBehavior.AllowGet);
    }
[HttpGet]
公共行动结果列表PendingItems()
{
var items=新列表();
//在上面的列表中添加一些项目
返回视图(vms);
}
[HttpPost]
公共JsonResult ApproveItem(ApproveItemViewModel viewmodel)
{
返回Json(新的{success=success},JsonRequestBehavior.AllowGet);
}
现在在我的razor视图中,我想要的是使用Ajax调用每个单独的项来调用ApproveItem方法。所以我使用下面的代码创建了多个ajax表单

@model IEnumerable<ApproveItemViewModel>
@foreach (var item in Model)
{
    using (Ajax.BeginForm("ApproveItem", new AjaxOptions()
                        {
                            InsertionMode = InsertionMode.Replace,
                            HttpMethod = "POST",
                            UpdateTargetId = "dane"
                        }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <table>
            <tr>
                <td>@Html.LabelFor(m => item.ItemId)</td>
                <td>@Html.DisplayFor(m => item.ItemId)</td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => item.ItemCode)</td>
                <td>@Html.TextBoxFor(m => item.ItemCode))</td>
            </tr>
            <tr>
                <td><input type="submit" value="Approve" /></td>
            </tr>
        </table>
    }
}
@model IEnumerable
@foreach(模型中的var项目)
{
使用(Ajax.BeginForm(“approvitem”,新的AjaxOptions())
{
InsertionMode=InsertionMode.Replace,
HttpMethod=“POST”,
UpdateTargetId=“丹麦”
}))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@LabelFor(m=>item.ItemId)
@DisplayFor(m=>item.ItemId)
@LabelFor(m=>item.ItemCode)
@Html.TextBoxFor(m=>item.ItemCode))
}
}

然而,在控制器操作方法参数中,我得到的ItemId和ItemCode分别为0和null。这里有什么问题,有人能帮忙吗?如何使用ajax将viewmodel传递给操作?

问题很可能是视图中的模型绑定器不知道如何绑定您的ApprovietViewModel列表

有关解释,请参见此答案:

@model IEnumerable
@for(int i=0;iModel[i].ItemId)
@DisplayFor(m=>Model[i].ItemId)
@LabelFor(m=>Model[i].ItemCode)
@Html.TextBoxFor(m=>Model[i].ItemCode))
}
}

问题很可能是视图中的模型绑定器不知道如何绑定ApprovitemViewModel列表

有关解释,请参见此答案:

@model IEnumerable
@for(int i=0;iModel[i].ItemId)
@DisplayFor(m=>Model[i].ItemId)
@LabelFor(m=>Model[i].ItemCode)
@Html.TextBoxFor(m=>Model[i].ItemCode))
}
}

此问题的原因是“参数”名称。您需要在cshtml端为控制器post操作的参数(即viewmodel)和迭代模型(item)保留相同的名称,然后只应发生绑定。请参阅下面两种不同的解决方案

解决方案1:修改cshtml页面:- 将@foreach(模型中的var项)替换为@foreach(模型中的var viewmodel) 即

解决方案2:修改控制器操作:-更改批准项操作的参数名称。 即


此问题的原因是“参数”名称。您需要在cshtml端为控制器post操作的参数(即viewmodel)和迭代模型(item)保留相同的名称,然后只应发生绑定。请参阅下面两种不同的解决方案

解决方案1:修改cshtml页面:- 将@foreach(模型中的var项)替换为@foreach(模型中的var viewmodel) 即

解决方案2:修改控制器操作:-更改批准项操作的参数名称。 即


您已包含@Html.AntiforgeryToken,因此请确保您的请求也包含@u requestVariationToken。您的查看没有任何意义。一次只能回发一个表单,为什么要为集合中的每个项目生成表单。视图中的模型是
List
,因此POST方法需要是
public JsonResult approvietem(List-viewmodel)
,您可以在
for
循环或
EditorTemplate
中为一个表单(一次发回所有更改)生成表单控件,或者,仅以文本形式生成表,并使用模式表单编辑所选项目并发回公共JsonResult ApproveItem(ApproveItemViewModel viewmodel),虽然您的方法建议您只需“批准”项目,但为什么用户可以编辑
项目ID
项目代码
属性?@StephenMuecke最初只有项目ID存在,作为批准的一部分,我们需要更新ItemCode.OK,因此,如果您希望用户编辑大多数或所有项目并一次全部发回,那么可以在一个表单中生成所有控件,或者包含一个对话框表单,当您单击某个项目并使用ajax提交它时,该对话框表单将打开。您已包含@Html.AntiforgeryToken,因此,请确保您的请求也包含_requestVariationToken。您的视图没有任何意义。你一次只能回寄一张表格,那你为什么要这样做
@model IEnumerable<ApproveItemViewModel>
@for (int i = 0; i < Model.Count; i++)
{
    using (Ajax.BeginForm("ApproveItem", new AjaxOptions()
                        {
                            InsertionMode = InsertionMode.Replace,
                            HttpMethod = "POST",
                            UpdateTargetId = "dane"
                        }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <table>
            <tr>
                <td>@Html.LabelFor(m => Model[i].ItemId)</td>
                <td>@Html.DisplayFor(m => Model[i].ItemId)</td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => Model[i].ItemCode)</td>
                <td>@Html.TextBoxFor(m => Model[i].ItemCode))</td>
            </tr>
            <tr>
                <td><input type="submit" value="Approve" /></td>
            </tr>
        </table>
    }
}
@foreach (var viewmodel in Model)
[HttpPost]
public JsonResult ApproveItem(ApproveItemViewModel item)
{
    return Json(new { success = success }, JsonRequestBehavior.AllowGet);
}