2017-02-21 3 views
1

Ich habe das folgende Objekt, das ich in einer MVC-Controller bin vorbei:Javascript Windows.Location passieren komplexe JSON-Objekt

this.JsonData = { 
    "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val(), 
    "searchMode": { 
     "mode": Number(mode.val()), 
     "pageSize": Number(pagesize.val()) || 5,          "pageNumber": Number(pagenumber.val()) || 1,     
     "sortField": sortfield.val() || "Ref", 
     "sortDirection": sortdirection.val() || "desc" 
    }, 
    "searchData": { 
     "Compare": Number(StdComparison.val()), 
     "SearchTextFrom": searchText.val(), 
     "SearchTextTo": searchTextTo.val() 
    } 

Dies funktioniert ok, aber ich letzte Forderung entstanden ist, wobei ich suche diese kodieren Objekt zur Verwendung mit der JavaScript-Funktion window.location

Vorschläge habe ich verwendet:

how-to-pass-complex-json-object-in-url-using-javascript

window.location + "?SearchCriteria=" + JSON.Stringify(this.JsonData); 

Erzeugt folgende Anfrage:

Controller/Action?SearchCriteria={ 
    "__RequestVerificationToken": "tokenvalue", 
    "searchMode": { 
     "mode": 2, 
     "pageSize": 5, 
     "pageNumber": 1, 
     "sortField": "Ref", 
     "sortDirection": "desc" 
    }, 
    "searchData": { 
     "Compare": 1, 
     "SearchTextFrom": "From A", 
     "SearchTextTo": "To Z" 
    } 
} 

Während

window.location + "?SearchCriteria=" + this.JsonData; 

Produziert folgendes:

Controller/Action?SearchCriteria=[object%20Object] 

Mit einer Seite nicht Fehler auf beiden oben gefunden.

UPDATE:

Ich habe auf der Suche nach einer Antwort vorwärts bewegt.

OK wie auf Anfrage von Helfern, habe ich mehr Quellcode enthalten.

Ich habe drei Klassen.

public class MainSearch 
{ 
    public MainSearch() 
    { 
     SearchData searchData = new SearchData(); 
     SearchMode searchMode = new SearchMode(); 
    } 
    public SearchData searchData { get; set; } 
    public SearchMode searchMode { get; set; } 
    public int? page { get; set; } 
    public object ToPagedListParameters(int pagenumber) 
    { 
     searchMode.pageNumber = pagenumber; 
     return page; 
    } 
    public IList<string> ValidationErrorMessages { get; set; } 
} 
public class SearchData 
{ 
    // Fields used for the ticket number search 
    public int? ticketNumberCompare { get; set; } 
    public string ticketSearchTextFrom { get; set; } 
    public string ticketSearchTextTo { get; set; } 

} 
public class SearchMode 
{ 
    public int? mode { get; set; } 
    public int? pageNumber { get; set; } 
    public int? pageSize { get; set; } 
    public string sortDirection { get; set; } 
    public string sortField { get; set; } 
    public string userURN { get; set; } 
    public string __RequestVerificationToken { get; set; } 
} 

Diese Klassen halten die verwendeten Kriterien für die Suche (search abgeschnitten wurde)

Das folgende ist mein Controller-Code:

[HttpGet] 
public ActionResult DownloadFileCSV(MainSearch search) 
{ 
    string fileName = Server.MapPath("~/Content/Pdf/") + "somefile.pdf"; 
    byte[] fileContents = System.IO.File.ReadAllBytes(fileName); 
    return File(fileContents, "application/pdf", "result.pdf"); 
} 

Und schließlich die Ajax-Aufruf, der gemacht wird aus der cshtml-Datei.

$("#DownloadAttachmentCSV").click(function() { 
    $.ajax(
     { 
      url: '@Url.Action("DownloadFileCSV", "Home")', 
      contentType: 'application/json; charset=utf-8', 
      datatype: 'json', 
      data: JsonData, 
      type: "GET", 
      success: function() { 
       window.location = '@Url.Action("DownloadFileCSV", "Home")' + '?' + JsonData;      
      }, 
      error: function (xhr, ajaxOptions, thrownError) { 
       alert(xhr.status); 
       alert(thrownError); 
      } 
     }); 
    }); 

Merkwürdigerweise wird der Code oben tatsächlich funktionieren und die Datei heruntergeladen ist, aber hier ist das Problem. Die JSON-Daten füllen nicht die MainSearch-Variable.

Der einzige Weg, wie ich die JSON-Daten zum Füllen der C# -Klassen erhalten kann, besteht darin, die Methode in einen POST zu ändern.

Muss dies der Fall sein?

+0

Sie können ein komplexes Javascript-Objekt an eine GET-Methode übergeben.Was ist die Signatur der Methode, die Sie aufrufen? –

+0

Sie verwendet HttpGet auf der MVC-Controller-Aktion – gilesrpa

+0

Ja, ich weiß - wieder, was ist die Signatur der Methode (und wenn es ein Modell ist, zeigen Sie dieses Modell) –

Antwort

0

Sie können keine komplexen JavaScript-Objekte an eine GET-Methode wie diese übergeben. Ein GET hat keinen Körper und um an ein Modell zu binden, müssen die Name/Wert-Paare der Abfragezeichenfolge mit den Eigenschaften des Objekts übereinstimmen, an das Sie binden.Zum Beispiel auf die mode Eigenschaft der SearchMode Eigenschaft MainSearch zu binden, fragen Sie String

....&SearchMode.mode=2.... 

ändern schließen müßten Sie den Code Ihre JavaScript-Objekt zu

var data = { 
    'searchMode.mode': mode.val(), 
    'searchMode.pageSize': pagesize.val() || 5, 
    'searchMode.pageNumber': pagenumber.val() || 1, 
    'searchMode.sortField': sortfield.val() || "Ref", 
    'searchMode.sortDirection': sortdirection.val() || "desc", 
    'searchData.SearchTextFrom': StdComparison.val(), 
    'searchData.Compare': searchText.val(), 
    'searchData.SearchTextTo': searchTextTo.val(), 
} 

und der Ajax zu erzeugen, unter Verwendung von Code

$.ajax(
    { 
     url: '@Url.Action("DownloadFileCSV", "Home")' + '?' + $.param(data), 
     type: "GET", 
     success: function() { 

folgende Anmerkung auch die

  1. Es gibt keinen Punkt Number(..) mit den Werten zu einer Zahl zu konvertieren - es ist alles über den Draht als Text
  2. gesendet Ein GET hat keinen Körper, so die Einstellung der Ajax contentType Option ist sinnlos
  3. Ihre Methode funktioniert nicht zurück json so datatype: 'json' macht nicht Sinn.
  4. die Fälschungs Token auf eine GET-Methode übergeben ist nicht notwendig

gesagt haben, dass seine unklar, was Ihr wollen, hier zu tun. Der Code in Ihrer MainSearch search() Methode verwendet nie Werte des Modells. Und es gibt eine FileResult, die nicht mit einem Ajax-Aufruf arbeiten können (aber es kann mit window.location arbeiten, ist es diesem Fall wird der Code für den Erfolg Rückruf benötigen würde

var baseUrl = '@Url.Action("DownloadFileCSV", "Home")'; 
var queryString = $.param(data); 
window.location = baseUrl + '?' + queryString; 

sein, aber dann seine unklar, warum Sie machen zwei Anrufe die Methode - der Ajax-Aufruf, gefolgt von der Umleitung (der Ajax-Aufruf tut gar nichts)

0

Alles, was Sie als Abfrageparameter verwenden sollten richtig URI codiert sein, vor allem mit so etwas wie JSON:

window.location + "?SearchCriteria=" + encodeURIComponent(JSON.Stringify(this.JsonData)); 

Ich bin nicht sicher, dass das Modell Binder ausgelegt ist JSON in einer GET-Anforderung in eine umwandeln Klasseninstanz, aber die Versuche, die Sie oben gemacht haben, sind definitiv nicht der richtige Weg.

+0

Versucht, dass JL, immer noch nicht funktioniert – gilesrpa

Verwandte Themen