ASP.NET MVC: GET-параметры неправильно десериализованы - PullRequest
3 голосов
/ 03 апреля 2012

Мне нужно передать сложный объект, представляющий фильтр данных, в действие, используя 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 ]

3 голосов
/ 03 апреля 2012

Алгоритм привязки данных в Asp.net MVC не очень хорош для десериализации сложных входных данных в типах .NET. В лучшем случае вы получите странные результаты и / или низкую производительность по сравнению с другими выделенными решениями. В этом случае Json.NET обеспечивает гораздо лучшие результаты при десериализации данных json в типах .NET, и это тоже очень быстро.

Вы должны передать эти фильтры как обычный строковый параметр и, внутри действия, десериализовать его с помощью Json.NET. Как то так:

using Newtonsoft.Json;

public ActionResult MyAction(string myFilters)
{
    var deserializedObject = JsonConvert.DeserializeObject(myFilters);
}
2 голосов
/ 03 апреля 2012

Может связывать сложные объекты / параметры, проблема в том, как отправляются параметры.Например, вы отправляете:

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, хотя.

...