我需要将表示数据过滤器的复杂对象传递给使用GET的操作,该操作返回csv文件中的过滤数据集。
过滤器对象在客户端上是这样的(实际上要复杂得多,简化为简洁):
var filter = {
Folders = [
{ Positive: true, Reference: { Id: 19, Name: "Container" } },
{ Positive: true, Reference: { Id: 37, Name: "Bullseye" } },
]
}
相应的服务器端类看起来像这样:
public class MyFilter
{
public List<MyComparison> Folders { get; set; }
}
public class MyComparison
{
public bool Positive { get; set; }
public MyReference Reference { get; set; }
}
public class MyReference
{
public int Id { get; set; }
public string Name {get; set; }
}
我的行动如下:
[HttpGet]
public FileContentResult Export(MyFilter filter, string sort, bool sortAscending)
{
string data = GetCsvData(filter, sort, sortAscending);
return this.File(StrToByteArray(data), "text/csv", "Data.csv");
}
我试过从这样的javascript调用此操作:
function exportFilter(aFilter) {
var params = { filter: aFilter, sort: "Name", sortAscending: true };
var destination = "MyController/Export?" + decodeURIComponent($.param(params));
document.location = destination;
}
在操作中,sort和sortAscending参数都已正确填充。过滤器是MyFilter类型的对象,但其Folders属性为null。
ASP.NET MVC是否无法以这种方式正确地反序列化复杂参数(即在GET环境中)?解决这个问题的正确方法是什么?
答案 0 :(得分:3)
Asp.net MVC中的数据绑定算法在反序列化.NET类型中的复杂输入方面不是很好。在最好的情况下,与其他专用解决方案相比,您会得到一些奇怪的结果和/或性能降低。在这种情况下,Json.NET在反序列化.NET类型中的json数据时提供了更好的结果,而且它也非常快。
您应该像普通的字符串参数一样传递这些过滤器,并在操作中使用Json.NET对其进行反序列化。像这样:
using Newtonsoft.Json;
public ActionResult MyAction(string myFilters)
{
var deserializedObject = JsonConvert.DeserializeObject(myFilters);
}
答案 1 :(得分:2)
它可以绑定复杂的对象/参数,问题在于params的发送方式。例如,您正在发送:
http://localhost/Home/Export?filter[Folders][0][Positive]=true&filter[Folders][0][Reference][Id]=19&filter[Folders][0][Reference][Name]=Container&filter[Folders][1][Positive]=true&filter[Folders][1][Reference][Id]=37&filter[Folders][1][Reference][Name]=Bullseye&sort=Name&sortAscending=true
但是MVC模型绑定器需要这种格式:
http://localhost/Home/Export?filter.Folders[0].Positive=true&filter.Folders[0].Reference.Id=19&filter.Folders[0].Reference.Name=Container&filter.Folders[1].Positive=true&filter.Folders[1].Reference.Id=37&filter.Folders[1].Reference.Name=Bullseye&sort=Name&sortAscending=true
我不确定从javascript对象构建匹配该模式的字符串的最简单方法。