2012-04-03 5 views
3

Ich muss ein komplexes Objekt, das einen Datenfilter darstellt, an eine Aktion übergeben, die GET verwendet, die einen gefilterten Datensatz in einer CSV-Datei zurückgibt.ASP.NET MVC: GET Parameter nicht richtig deserialisiert

Das Filterobjekt ist so etwas auf dem Client (viel komplexer in der Wirklichkeit, der Kürze halber vereinfacht):

var filter = { 
    Folders = [ 
    { Positive: true, Reference: { Id: 19, Name: "Container" } }, 
    { Positive: true, Reference: { Id: 37, Name: "Bullseye" } }, 
    ] 
} 

Die entsprechenden Serverseite Klassen wie folgt aussehen:

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; } 
} 

Meine Aktion sieht so aus:

[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"); 
} 

Ich habe versucht, diese Aktion f rom javascript wie folgt aus:

function exportFilter(aFilter) { 
    var params = { filter: aFilter, sort: "Name", sortAscending: true }; 
    var destination = "MyController/Export?" + decodeURIComponent($.param(params)); 
    document.location = destination; 
} 

Innerhalb der Aktion, sowohl die Art und SortAscending Parameter richtig besiedelt sind. Der Filter ist ein Objekt vom Typ MyFilter, die Eigenschaft Folders ist jedoch null.

Kann ASP.NET MVC komplexe Parameter auf diese Weise nicht richtig deserialisieren (dh im Kontext eines GET)? Was ist der richtige Weg, um dieses Problem anzugehen?

+0

Es ist in der Lage, aber schwer zu sagen, was genau in Ihrem Fall geschieht ohne Debuggen ..:/ –

+0

was in aFilter los ist? – Dave

+0

aFilter erhält ein JavaScript-Objekt wie "filter" aus dem ersten Codebeispiel –

Antwort

2

Es kann komplexe Objekte/Parameter binden, das Problem ist die Art, wie die Parameter gesendet werden. Zum Beispiel, Sie senden:

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 

Aber das MVC-Modell Binder erwartet Sie dieses Format:

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 

Ich bin der einfachste Weg, nicht sicher, ob ein String-Matching dieses Muster aus einer Javascript zu bauen Objekt jedoch.

3

Der Datenbindungsalgorithmus in ASP.net MVC ist nicht sehr gut beim Deserialisieren komplexer Eingaben in .NET-Typen. Im besten Fall würden Sie im Vergleich zu anderen dedizierten Lösungen einige seltsame Ergebnisse und/oder eine langsame Leistung erhalten. In diesem Fall liefert Json.NET viel bessere Ergebnisse beim Deserialisieren von JSON-Daten in .NET-Typen, und das ist auch sehr schnell.

Sie sollten diese Filter wie einen normalen String-Parameter übergeben und in der Aktion mit Json.NET deserialisieren. Etwas wie folgt aus:

using Newtonsoft.Json; 

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