在使用 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"]}
您无法将
<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
将是所选选项值的数组。
我的猜测是 SubCategories 类中的 JSON 映射与传递的内容不太匹配。如果您暂时将 data 变量更改为 object 类型,然后单步执行它,您应该会看到一个匿名类型,它将显示真正传递的内容。或者,您可以查看 Chrome 中开发人员工具的“网络”选项卡,查看发布的实际 JSON——它可能会有一些细微的差别。
最后我需要一个混合的答案,但由于我缺乏知识,我没有把问题说得很清楚。 @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());
}
}