Domanda

Ho un servizio web ASP.net che sto usando per un'applicazione web che mi restituisce dati XML o JSON, a seconda della funzione che chiamo. Finora ha funzionato bene, ma ho riscontrato un problema. Voglio creare un " export " link sulla mia pagina che scaricherà un file JSON. Il link è formattato in modo molto semplice:

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

Come puoi immaginare, questo dovrebbe esportare l'articolo 2. Fin qui tutto bene, sì?

Il problema è che poiché non sto specificatamente richiedendo che il tipo di contenuto accettato sia JSON, ASP.net rifiuta assolutamente di rispedire qualsiasi cosa tranne XML, che non è proprio appropriato per questa situazione. Il codice è essenzialmente il seguente:

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

Nonostante abbia specificato ResponseFormat come JSON, ottengo sempre XML a meno che non richieda questo metodo tramite AJAX (utilizzando 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(){...});

È fantastico, ma AJAX non mi darà una finestra di download. Esiste un modo per forzare ASP.net a restituirmi JSON, indipendentemente da come vengono richiesti i dati? Mi sembra che non avere una sostituzione manuale per questo comportamento sia una grave supervisione del design.


RISPOSTA RAPIDA:

Prima di tutto, lasciami dire che penso che la risposta di Womp sia probabilmente il modo migliore per andare a lungo termine (Converti in WCF), ma deostroll mi ha portato alla risposta che userò per l'immediato futuro. Inoltre, va notato che questo sembra funzionare principalmente perché volevo solo un download, potrebbe non funzionare anche in tutte le situazioni. In ogni caso, ecco il codice che ho finito per usare per ottenere il risultato che volevo:

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

Nota: il tipo di ritorno void (il che significa che il tuo WDSL sarà quasi inutile per questa funzione). Restituire qualsiasi cosa rovinerà la risposta che viene costruita a mano.

È stato utile?

Soluzione

Ecco due discussioni sui forum come riferimento:

http://forums.asp.net/t/1118828.aspx

http://forums.asp.net/p/1054378/2338982 aspx # 2338982

Non ho idea chiara. Dicono di concentrarsi sull'impostazione del tipo di contenuto su application / json. Non ho mai lavorato con wcf prima, ma penso che tu possa usare l'oggetto Response.

Imposta il tipo di contenuto sull'oggetto risposta. Esegui un response.write passando i tuoi dati json come stringa e quindi esegui un response.end.

Altri suggerimenti

I servizi Web Asp.net sono servizi Web basati su SOAP. Restituiranno sempre XML. Sono arrivate le librerie Ajax e sono state introdotte le cose ScriptMethod, ma non cambia il concetto sottostante di esso.

Ci sono un paio di cose che puoi fare.

I metodi Web sono obsoleti al limite con l'introduzione di WCF. Puoi considerare migrare i tuoi servizi web in WCF , in cui avere un controllo molto maggiore sul formato di output.

Se non vuoi farlo, puoi serializzare manualmente il risultato delle tue chiamate al servizio web in JSON e il servizio lo avvolgerà in un'intestazione SOAP. Dovresti quindi eliminare le cose SOAP.

Ho pensato di buttarlo lì perché non era stato menzionato in precedenza ... se usi WebServices con ASP.NET 3.5, JSON è il formato di ritorno predefinito. Inoltre viene fornito con il serializzatore JSON in modo da poter smettere di usare il JavascriptSerializer.

Questo articolo sul blog di Rick Strahl parla del forte- conversione tipizzata che puoi eseguire tra classi lato server e oggetti JSON dal client.

Di recente ho completato un progetto usando questo nuovo materiale JSON in .NET 3.5 e sono estremamente impressionato dalle prestazioni. Forse vale la pena dare un'occhiata ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top