2012-05-30 13 views
8

He estado buscando 100 enlaces durante las últimas 3 horas, por ejemplo, agregando scriptfactory a webconfig , 3 errores, fijando el tipo de contenido, etc.Servicio web de Asmx que devuelve xml en lugar de json, intentando eliminar <string xmlns = "http://tempuri.org/"> del resultado del servicio

no soy capaz de averiguar lo que realmente es el error.

Medio Ambiente: servicio que se ejecuta en .NET 4.0 aplicación Web que se ejecuta en .NET 4.0

Requisitos: que necesitan de obligar a un servicio web con jqGrid asmx que me está volviendo un JSON como una cadena. archivo de servicio de Internet contiene siguiente código.

[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 es el siguiente

<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 es el siguiente

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

salida de servicio Web al hacer clic en el botón de invocación

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

Por favor sugiera qué es lo que me falta. <string xmlns="http://tempuri.org/"> etiquetas mí son irritantes. Estoy asumiendo que estas etiquetas no están dejando que mi rejilla capaz de unirse.

ACTUALIZACIÓN:

servicio ASMX ahora se ve como la siguiente manera.

[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

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

+0

Las preguntas son similares pero las soluciones son diferentes. En la solución vinculada, la solución era modificar el archivo web.config, en esta solución, la solución consiste en modificar el encabezado Content-Type. Sin embargo, puede que no sean soluciones mutuamente excluyentes. – akousmata

Respuesta

6

Al hacer clic en el botón de invocación devuelve XML porque la solicitud no se especifica el contentType: 'application/json; charset=utf-8'. Así que el experimento con hacer clic en el botón invocar la ayuda en realidad no.

El principal problema en su código es que convierte los datos a cadena dentro del método web. La línea

json = Lib.ToJSON(obj); 

no son necesarios. Lo que uno típicamente hace es devolver el objeto. El GetJsonServerProcess debería cambiarse a algo así como

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

El siguiente problema es que el formato de entrada por defecto que esperar jqGrid es otro (ver here). Por lo que la cueva para especificar jsonReader que describen el formato de datos. En su caso, será algo así como

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

Además nunca se debe utilizar http://localhost:1092/ prefijo en Ajax url, ya que sólo CAL obtener datos desde el mismo sitio por razones de seguridad. El parámetro data en jqGrid tiene otro significado que en jQuery, por lo que debe eliminar data: "{}" y mover type: "POST" de ajaxGridOptions a mtype: "POST".Como el resultado que tendrá algo así como

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

No probado el código, pero debe ser más cerca de lo que necesita.

ACTUALIZADO: Se debe corregir el código cambiando jsonReader. Puede descargar la demostración funcional here. Se muestra la cuadrícula

enter image description here

he usado en el lado del servidor el código

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

y en el lado del cliente

$("#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

'nunca debe usar http: // localhost: 1092/prefix en Ajax url' Actualmente he creado dos soluciones diferentes, una para servicios y otra para aplicaciones web. No he alojado el servicio en IIS a partir de ahora y estoy usando directamente este servicio en otra aplicación para fines de prueba. Estaba tratando de implementar jqGrid. Entonces, en este escenario, si estoy usando la ruta completa para el servicio, ¿funcionaría eso? En la aplicación en vivo me ocuparé de la url. Voy a probar todas tus sugerencias. Pero ha sido un momento difícil hasta ahora ejecutar esto. Gracias por tu apoyo. –

+0

@ShantanuGupta: Es solo una restricción común de Ajax. La restricción se conoce con el nombre [misma política de origen] (http://en.wikipedia.org/wiki/Same_origin_policy). Por lo tanto, no puede acceder a * otro host u otro puerto como el host o puerto desde el que realiza la solicitud *. Se el prefijo como 'http: // localhost: 1092 /' no tiene sentido. Si solo debe incluir el servicio web y la página HTML/ASPX correspondiente en * el mismo * servidor web. Alternativamente, puede usar JSONP en lugar de JSON, pero en el caso de que sea más complejo implementar la autenticación de usuario, entonces uno la usa principalmente para los servicios web públicos. – Oleg

+0

Todavía estoy luchando con el problema de los datos. El servicio web no devuelve JSON. Está agregando etiquetas XML en la parte superior. '' –

1

Está bien, tengo el mismo error y después de una carga de prueba y error aquí está mi solución "rápida y sucia";

$.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

Para una respuesta JSON válido utilizar este código ..

[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

Por favor, escriba lo que ha hecho y cómo es útil para el problema. –

-1

El siguiente código debe hacer el truco:

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

Este código funciona perfectamente

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

¿Cómo contribuye esto a una pregunta de 5 años con una respuesta aceptada? .... No mucho... – VDWWD

Cuestiones relacionadas