2012-05-30 17 views
8

Ho cercato 100 di collegamenti per le ultime 3 ore, ad esempio aggiungendo scriptfactory a webconfig , 3 errori, impostazione del tipo di contenuto ecc.Servizio Web Asmx restituendo xml invece di json, cercando di rimuovere <string xmlns = "http://tempuri.org/"> dall'output del servizio

Non sono in grado di capire cosa sia effettivamente l'errore.

Ambiente: servizio in esecuzione su .NET 4.0 Web in esecuzione su .NET 4.0

Requisiti: ho bisogno di impegnare un jqGrid con servizio web ASMX che mi restituisce un JSON come una stringa. Il file del servizio Web contiene il seguente codice.

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.ComponentModel.ToolboxItem(false)] 
[ScriptService] 
public class SampleService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public string GetJsonServerProcess() 
    { 
     int memory = 1; 
     string json = string.Empty; 
     var obj = (System.Diagnostics.Process.GetProcesses().Where(r => r.WorkingSet64 > memory).Select(p => new { p.ProcessName, p.WorkingSet64 }).ToArray()); 
     json = Lib.ToJSON(obj); 
     return json; 
    } 
} 

Javascript è la seguente

<script type="text/javascript"> 
    $(document).ready(function() { 
     jQuery("#jqgajax").jqGrid({ 
      ajaxGridOptions: { type: "POST", contentType: 'application/json; charset=utf-8' }, 
      url:'http://localhost:1092/SampleService.asmx/GetJsonServerProcess', 
      datatype: "json", 
      data: "{}", 
      colNames: ['ProcessName', 'WorkingSet64'], 
      colModel: [ 
         { name: 'ProcessName', index: 'ProcessName', width: 55 }, 
         { name: 'WorkingSet64', index: 'WorkingSet64', width: 90 } 
        ], 
      rowNum: 10, 
      width: 700, 
      rowList: [10, 20, 30], 
      sortname: 'invdate', 
      viewrecords: true, 
      sortorder: "desc", 
      caption: "New API Example" 
     }); 
    }); 
</script> 

HTML è il seguente

<table id="jqgajax"> 
</table> 
<div id="jqgajax"> 
</div> 

uscita Web Service quando si fa clic sul pulsante Invoke

<string xmlns="http://tempuri.org/"> 
[{"ProcessName":"Dropbox","WorkingSet64":22736896}, 
{"ProcessName":"fdhost","WorkingSet64":1941504}, 
{"ProcessName":"IntelliTrace","WorkingSet64":39276544} 
] 
</string> 

Si prega di suggerire cosa c'è che mi manca. I tag <string xmlns="http://tempuri.org/"> mi irritano. Suppongo che questi tag non consentano alla mia rete di legarsi.

UPDATE:

servizio ASMX ora sembra come di seguito.

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.ComponentModel.ToolboxItem(false)] 
[ScriptService] 
public class SampleService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public List<demo> GetJsonServerProcess() 
    { 
     List<demo> test = new List<demo>(); 

     for(int i=1;i<=10;i++) 
      test.Add(new demo { ProcessName = string.Format("Sample {0}",i), WorkingSet64 = i }); 

     var re = test; 
     return re; 
    } 
} 

public class demo 
{ 
    public string ProcessName { get; set; } 
    public int WorkingSet64 { get; set; } 
} 
+0

Possibile duplicato: http: //stackoverflow.com/questions/11088294/asp-net-asmx-web-service-returning-xml-instead-of-json –

+0

Le domande sono simili ma le soluzioni sono diverse. Nella soluzione collegata, la correzione consisteva nel modificare il file web.config, in questa soluzione la correzione è modificare l'intestazione Content-Type. Tuttavia, potrebbero non essere soluzioni reciprocamente esclusive. – akousmata

risposta

6

Facendo clic sul pulsante Invoke ritorna XML perché la richiesta che sia precisata la contentType: 'application/json; charset=utf-8'. Quindi l'esperimento con il clic sul pulsante Richiama non aiuta davvero.

Il problema principale nel codice è la conversione dei dati in stringa all'interno del metodo web. La riga

json = Lib.ToJSON(obj); 

non sono necessari. Quello che in genere si fa è restituire l'oggetto. Il GetJsonServerProcess dovrebbe essere cambiato in qualcosa di simile

[ScriptService] 
public class SampleService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public List<Process> GetJsonServerProcess() 
    { 
     int memory = 1; 
     return System.Diagnostics.Process.GetProcesses() 
        .Where(r => r.WorkingSet64 > memory) 
        .Select(p => new { p.ProcessName, p.WorkingSet64 }) 
        .ToList(); 
    } 
} 

Il problema successivo è che il formato di input di default che attendere jqGrid è un altro (vedi here). Quindi spunti per specificare jsonReader che descrivono il formato dei dati. Nel tuo caso, sarà qualcosa di simile a

jsonReader: { 
    repeatitems: false, 
    id: "ProcessName", 
    root: function (obj) { return obj; }, 
    page: function() { return 1; }, 
    total: function() { return 1; }, 
    records: function (obj) { return obj.length; } 
} 

Inoltre si dovrebbe mai usare http://localhost:1092/ prefisso Ajax url perché si cal ottiene solo i dati dallo stesso sito per motivi di sicurezza. Il parametro data in jqGrid ha un altro significato come in jQuery, quindi è necessario rimuovere data: "{}" e spostare type: "POST" da ajaxGridOptions a mtype: "POST".Come risultato si avrà qualcosa di simile

$(document).ready(function() { 
    $("#jqgajax").jqGrid({ 
     mtype: "POST", 
     ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }, 
     url: '/SampleService.asmx/GetJsonServerProcess', 
     postData: "{}", // remove all parameters which jqGrid send typically 
     datatype: "json", 
     colNames: ['ProcessName', 'WorkingSet64'], 
     colModel: [ 
      { name: 'ProcessName', index: 'ProcessName', width: 155 }, 
      { name: 'WorkingSet64', index: 'WorkingSet64', width: 190 } 
     ], 
     jsonReader: { 
      repeatitems: false, 
      id: "ProcessName", 
      root: function (obj) { return obj; }, 
      page: function() { return 1; }, 
      total: function() { return 1; }, 
      records: function (obj) { return obj.length; } 
     }, 
     rowNum: 10, 
     loadonce: true, 
     gridview: true, 
     height: 'auto', 
     rowList: [10, 20, 30], 
     viewrecords: true, 
     sortorder: "desc", 
     caption: "New API Example" 
    }); 
}); 

Non provato il codice, ma dovrebbe essere più vicino a quello che vi serve.

AGGIORNATO: È necessario correggere il codice modificando jsonReader. È possibile scaricare la demo di lavoro here. Si visualizzare la griglia

enter image description here

ho usato sul lato server il codice

using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Web.Services; 

namespace jqGridWebASMX 
{ 
    [WebService(Namespace = "http://tempuri.org/")] 
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [System.ComponentModel.ToolboxItem(false)] 
    [System.Web.Script.Services.ScriptService] 
    public class SampleService : WebService 
    { 
     [WebMethod] 
     public List<Demo> GetJsonServerProcess() 
     { 
      const int memory = 1; 
      return Process.GetProcesses() 
       .Where (r => r.WorkingSet64 > memory) 
       .Select(p => new Demo { 
        Id = p.Id, 
        ProcessName = p.ProcessName, 
        WorkingSet64 = p.WorkingSet64 
       }) 
       .ToList(); 
     } 
    } 

    public class Demo 
    { 
     public int Id { get; set; } 
     public string ProcessName { get; set; } 
     public long WorkingSet64 { get; set; } 
    } 
} 

e sul lato client

$("#list").jqGrid({ 
    mtype: "POST", 
    ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }, 
    url: '/SampleService.asmx/GetJsonServerProcess', 
    postData: "{}", // remove all parameters which jqGrid send typically 
    datatype: "json", 
    colNames: ['ProcessName', 'WorkingSet64'], 
    colModel: [ 
     { name: 'ProcessName', index: 'ProcessName', width: 200 }, 
     { name: 'WorkingSet64', index: 'WorkingSet64', width: 120, 
      formatter: 'integer', sorttype: 'int', align: 'right' } 
    ], 
    jsonReader: { 
     repeatitems: false, 
     id: "Id", 
     root: function (obj) { return obj.d; }, 
     page: function() { return 1; }, 
     total: function() { return 1; }, 
     records: function (obj) { return obj.d.length; } 
    }, 
    rowNum: 10, 
    loadonce: true, 
    gridview: true, 
    height: 'auto', 
    pager: '#pager', 
    rowList: [10, 20, 30], 
    rownumbers: true, 
    viewrecords: true, 
    sortorder: "desc", 
    caption: "New API Example" 
}); 
$("#pager_left").hide(); // hide unused part of the pager to have more space 
+0

'non dovresti mai usare http: // localhost: 1092/prefisso nell'URL Ajax 'attualmente ho creato due soluzioni diverse una per i servizi un'altra per l'applicazione web. Finora non ho ospitato il servizio su IIS e sto utilizzando direttamente questo servizio in un'altra applicazione a scopo di test. Stavo cercando di implementare jqGrid. Quindi, in questo scenario, se sto utilizzando il percorso completo per il servizio, funzionerebbe? Nell'applicazione live mi prenderò cura dell'URL. Proverò tutti i tuoi suggerimenti. Ma è stato un momento difficile fino ad ora gestirlo. Grazie per il vostro sostegno. –

+0

@ShantanuGupta: È solo una restrizione comune di Ajax. La restrizione è nota sotto il nome [same origin policy] (http://en.wikipedia.org/wiki/Same_origin_policy). Quindi non è possibile accedere a * un altro host o un'altra porta come l'host o la porta da cui si effettua la richiesta *. Se il prefisso come 'http: // localhost: 1092 /' non ha senso. Se dovessi includere solo il servizio web e la corrispondente pagina HTML/ASPX su * lo stesso * server web. In alternativa è possibile utilizzare JSONP anziché JSON, ma nel caso in cui sia più complesso implementare l'autenticazione dell'utente, quindi lo si utilizza principalmente per i servizi Web pubblici. – Oleg

+0

Sto ancora lottando con il problema dei dati. Il servizio Web non restituisce JSON. Sta aggiungendo il tag XML in alto. '' –

1

Va bene, ho ottenuto lo stesso errore e dopo un carico di prove ed errori ecco la mia soluzione "veloce e sporca";

$.get(url, {var1: parameter1, var2: parameter2}, function(data){ 
    data = JSON.parse($(data).find("string").text()); 
    alert("data.source: " + data.source); 
}); 
0
response = await client.GetAsync(RequestUrl, HttpCompletionOption.ResponseContentRead); 
       if (response.IsSuccessStatusCode) 
       { 
        _data = await response.Content.ReadAsStringAsync(); 
        try 
        { 
         XmlDocument _doc = new XmlDocument(); 
         _doc.LoadXml(_data); 
         return Request.CreateResponse(HttpStatusCode.OK, JObject.Parse(_doc.InnerText)); 
        } 
        catch (Exception jex) 
        { 
         return Request.CreateResponse(HttpStatusCode.BadRequest, jex.Message); 
        } 
       } 
       else 
        return Task.FromResult<HttpResponseMessage>(Request.CreateResponse(HttpStatusCode.NotFound)).Result; 
-1

Per risposta JSON valido utilizzare questo codice ..

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.ComponentModel.ToolboxItem(false)] 
[ScriptService] 
public class SampleService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public void GetJsonServerProcess() 
    { 
     int memory = 1; 
     string json = string.Empty; 
     var obj = (System.Diagnostics.Process.GetProcesses().Where(r => r.WorkingSet64 > memory).Select(p => new { p.ProcessName, p.WorkingSet64 }).ToArray()); 
     json = Lib.ToJSON(obj); 
     this.Context.Response.ContentType = "application/json; charset=utf-8"; 
      this.Context.Response.Write(json); 

    } 
} 
+0

Si prega di scrivere quello che hai fatto, e come è utile al problema. –

-1

Il seguente codice dovrebbe fare il trucco:

this.Context.Response.ContentType = "application/json; charset=utf-8"; 
this.Context.Response.Write(json); 
-1

Questo codice funziona perfettamente

SqlDataAdapter sda = new SqlDataAdapter(strsql, ConfigurationManager.ConnectionStrings["BTConString"].ToString()); 
DataSet das = new DataSet(); 
sda.Fill(das); 
Context.Response.Output.Write(JsonConvert.SerializeObject(das, Newtonsoft.Json.Formatting.Indented)); 
Context.Response.End(); 

return string.Empty; 
+0

In che modo questo contribuisce a una domanda di 5 anni con una risposta accettata? .... Non molto... – VDWWD

Problemi correlati