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

ASP.NET MVC: GET params not properly deserialized

本文关键字:反序列化 参数 GET NET MVC ASP      更新时间:2023-09-26

我需要使用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和sortAcending参数都被正确填充。筛选器是MyFilter类型的对象,但其Folders属性为null。

ASP.NET MVC是否无法以这种方式(即在GET上下文中)正确地反序列化复杂参数?解决这个问题的正确方法是什么?

Asp.netMVC中的数据绑定算法在反序列化.net类型中的复杂输入方面不是很好。在最好的情况下,与其他专用解决方案相比,您会得到一些奇怪的结果和/或较慢的性能。在这种情况下,Json.NET在反序列化.NET类型中的Json数据方面提供了更好的结果,而且速度也非常快。

您应该像传递普通字符串参数一样传递这些筛选器,并在操作内部使用Json.NET对其进行反序列化

using Newtonsoft.Json;
public ActionResult MyAction(string myFilters)
{
    var deserializedObject = JsonConvert.DeserializeObject(myFilters);
}

它可以绑定复杂的对象/参数,问题是参数的发送方式。例如,您正在发送:

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