Ajax 发布到 MVC 控制器列表<T>属性正确计数但为空

问题描述 投票:0回答:3

在使用 Telerik MultiSelect 控件的 MVC 中,我通过 ajax 发回控制器。我的数据是正确的,但我缺少一些关于如何获取 POST 操作来解释 ajax 数据参数的连接,因为它始终是正确的元素数量,但它们为空。

我的型号:

public class SeeAlso
{
    public List<SubCategories> SelectedCategories { get; set; }
    public List<SubCategories> AvailableCategories { get; set; }
}

我的控制器

[AcceptVerbs(HttpVerbs.Post)]
public async Task<ActionResult> SeeAlso_Update(SeeAlso data)
{
   if (data != null && ModelState.IsValid)
   {...}
}

我的cshtml:

<h2>See Also</h2>

@using (Html.BeginForm())
{
<label for="required">Selected</label>
@(Html.Kendo().MultiSelect()
  .Name("SeeAlso")
  .Placeholder("Selected Categories...")
  .BindTo(Model.AvailableCategories.Select(x => x.SubCategoryName).ToList())
  .Value(Model.SelectedCategories.Select(c => c.SubCategoryName).ToArray())
  .Events(e => { e.Change("onChange"); })
)
}

<script type="text/javascript">
function onChange()
{
    $.ajax({
        url: "/Admin/SeeAlso/SeeAlso_Update",
        type: "POST",
        async: true,
        dataType: "json",
        contentType: "application/json",

        data: JSON.stringify({ SelectedCategories: $("#SeeAlso").data("kendoMultiSelect").dataItems() })

    });

}

</script>

当我发布时总是得到正确的计数,但值为空。

按照要求,这里是 json,我知道它很接近,但我不知道如何获取表示的父 SeeAlso 容器。

{"SelectedCategories":["Cat1","Cat2"]}
c# ajax asp.net-mvc
3个回答
1
投票

您无法将

<select multiple>
绑定到复杂对象的集合(它仅回发所选选项的值的数组),因此您需要绑定的属性必须是
IEnumerable<string>
(假设
SubCategoryName
是 typeof
string
)。您查看模型需要是

public class SeeAlso
{
    public IEnumerable<string> SelectedCategories { get; set; }
    public List<SubCategories> AvailableCategories { get; set; }
}

要使用ajax提交模型,您只需序列化表单即可

$.ajax({
    url: "/Admin/SeeAlso/SeeAlso_Update",
    type: "POST",
    dataType: "json",
    data: $('form').serialize();
});

它将正确绑定到

[HttpPost]
public ActionResult SeeAlso_Update(SeeAlso model)

model.SelectedCategories
将是所选选项值的数组。


0
投票

我的猜测是 SubCategories 类中的 JSON 映射与传递的内容不太匹配。如果您暂时将 data 变量更改为 object 类型,然后单步执行它,您应该会看到一个匿名类型,它将显示真正传递的内容。或者,您可以查看 Chrome 中开发人员工具的“网络”选项卡,查看发布的实际 JSON——它可能会有一些细微的差别。


0
投票

最后我需要一个混合的答案,但由于我缺乏知识,我没有把问题说得很清楚。 @Stephen Muecke 非常有帮助,我已经接受了他的回答。这就是我最终让一切正常运转的方法。

型号:

public class SeeAlso
{
    public List<int> SelectedCategories { get; set; }
    public List<SubCategories> AvailableCategories { get; set; }
}

public class SubCategories
{
    public int Id { get; set; }

    public string SubCategoryName { get; set; }

    public int CategoryId { get; set; }

}

cshtml:

<div>
<h2>See Also</h2>

<label for="required">Selected</label>

@(Html.Kendo().MultiSelectFor(m => m.SelectedCategories)
        .Placeholder("Selected Categories...")
        .DataTextField("SubCategoryName")
        .DataValueField("Id")
        .BindTo(Model.AvailableCategories)
        )

<br/>
<button type="submit" name="saveButton" id="saveButton">Save</button>
<br/>

</div>

<script type="text/javascript">
$("#saveButton").click(function () {
    $.ajax({
        url: "/Admin/SeeAlso/Update",
        type: "POST",
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify({ SelectedCategories: $("#SelectedCategories").data("kendoMultiSelect").dataItems() })
    })
});
</script>

控制器:

[RoutePrefix("Admin/SeeAlso")]
public class SeeAlsoController : Controller
{

   [HttpPost]
   [Route("Update")]
   public async Task<ActionResult> SeeAlso_Update(List<SubCategories> SelectedCategories)
   {
        if (SelectedCategories != null && ModelState.IsValid)
        { ... }
        return Json(ModelState.ToDataSourceResult());
   }
} 
© www.soinside.com 2019 - 2024. All rights reserved.