ASP.NET MVC:GET参数未正确反序列化

时间:2012-04-03 18:27:17

标签: javascript asp.net-mvc http-get

我需要将表示数据过滤器的复杂对象传递给使用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环境中)?解决这个问题的正确方法是什么?

2 个答案:

答案 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对象构建匹配该模式的字符串的最简单方法。