Erzwingen, dass der ASP.net-Webservice JSON zurückgibt

Ich habe einen ASP.net-Webdienst, den ich für eine Webanwendung verwende, die abhängig von der aufgerufenen Funktion XML- oder JSON-Daten an mich zurückgibt. Dies hat bisher gut funktioniert, aber ich bin auf ein Problem gestoßen. Ich möchte auf meiner Seite einen "Export" -Link erstellen, über den eine JSON-Datei heruntergeladen wird. Der Link ist sehr einfach formatiert:

<a href="mywebserviceaddress/ExportFunc?itemId=2">Export This Item</a>

Wie Sie sich vorstellen können, sollte dies Artikel 2 exportieren. Soweit so gut, ja?

Das Problem ist, dass ASP.net es absolut ablehnt, etwas anderes als XML zurückzusenden, da ich nicht ausdrücklich verlange, dass der akzeptierte Inhaltstyp JSON ist, was für diese Situation einfach nicht geeignet ist. Der Code lautet im Wesentlichen wie folgt:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Item ExportItem(int itemId)
    {
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download

        return GetExportItem(itemId);
    }

Obwohl ich das ResponseFormat als JSON spezifiziere, erhalte ich immer XML zurück, es sei denn, ich fordere diese Methode über AJAX an (unter Verwendung von Google Web Toolkit, BTW):

    RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
    builder.setHeader("Content-type","application/json; charset=utf-8");
    builder.setHeader("Accepts","application/json");
    builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});

Das ist toll, aber AJAX gibt mir keinen Download-Dialog. Gibt es eine Möglichkeit, ASP.net zu zwingen, mir JSON zurückzugeben, unabhängig davon, wie die Daten angefordert werden? Es scheint mir, dass das Fehlen einer manuellen Übersteuerung für dieses Verhalten eine grobe Konstruktionsüberprüfung darstellt.

SCHNELLE ANTWORT:

Lassen Sie mich zunächst sagen, dass ich denke, dass die Antwort von womp wahrscheinlich der bessere Weg ist, um langfristig voranzukommen (In WCF konvertieren), aber Deostroll führte mich zu der Antwort, die ich für die unmittelbare Zukunft verwenden werde. Außerdem sollte beachtet werden, dass dies in erster Linie zu funktionieren scheint, weil ich nur einen Download wollte, der möglicherweise nicht in allen Situationen so gut funktioniert. In jedem Fall ist hier der Code, mit dem ich das gewünschte Ergebnis erzielt habe:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public void ExportItem(int itemId)
    {
        Item item = GetExportItem(itemId);            

        JavaScriptSerializer js = new JavaScriptSerializer();
        string str = js.Serialize(item);

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
        Context.Response.AddHeader("content-length", str.Length.ToString());
        Context.Response.Flush();
        Context.Response.Write(str);
    }

Bitte beachten Sie die Rückgabeart vonLeere (was bedeutet, dass Ihr WDSL für diese Funktion so gut wie unbrauchbar ist). Wenn Sie etwas zurückgeben, wird die Antwort, die von Hand erstellt wird, durcheinander gebracht.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage