Asmx web service returns xml instead of json, trying to remove <string xmlns = "http://tempuri.org/"> from service output
I searched for 100 links in the last 3 hours, for example, adding a scriptfactory to webconfig, 3 errors, setting the content type, etc.
I can’t understand what is really a mistake.
Environment: The service runs on .net 4.0 A web application running on .net 4.0
Requirements: I need to associate jqGrid with the asmx web service, which returns me json as a string. The web service file contains the following code.
[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 is as follows
<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 is as follows
<table id="jqgajax"> </table> <div id="jqgajax"> </div> Web service exit when you click the Call button
<string xmlns="http://tempuri.org/"> [{"ProcessName":"Dropbox","WorkingSet64":22736896}, {"ProcessName":"fdhost","WorkingSet64":1941504}, {"ProcessName":"IntelliTrace","WorkingSet64":39276544} ] </string> Please suggest what is missing from me. The tags <string xmlns="http://tempuri.org/"> annoy me. I assume that these tags do not allow my grid to bind.
UPDATE:
The ASMX service now looks like this.
[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; } } Pressing the Call button returns XML because the request does not specify contentType: 'application/json; charset=utf-8' contentType: 'application/json; charset=utf-8' . Therefore, the experiment with pressing the "Call" button does not help.
The main problem in your code is that you convert the data to a string inside the web method. Line
json = Lib.ToJSON(obj); Not needed. Usually usually returns an object. GetJsonServerProcess should be changed to something like
[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(); } } The next problem is that the default input format that jqGrid expects is different (see here ). Therefore, you can specify jsonReader , which describes the data format. In your case, it will be something like
jsonReader: { repeatitems: false, id: "ProcessName", root: function (obj) { return obj; }, page: function () { return 1; }, total: function () { return 1; }, records: function (obj) { return obj.length; } } In addition, you should never use the http://localhost:1092/ prefix in the Ajax url , because for security reasons you only get data from the same site. The data parameter in jqGrid has a different meaning, as in jQuery, so you must delete data: "{}" and move type: "POST" from ajaxGridOptions to mtype: "POST" . As a result, you will have something like
$(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" }); }); I have not tested the code, but it should be closer to what you need.
UPDATED . You must fix the code by modifying jsonReader . You can download a working demo here . It displays a grid

I used server side code
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; } } } and client side
$("#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 Ok, I got the same error and after loading trial and error here is my “quick and dirty” solution;
$.get(url, {var1: parameter1, var2: parameter2}, function(data){ data = JSON.parse($(data).find("string").text()); alert("data.source: " + data.source); }); This code works great
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; 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; The following code should do the trick:
this.Context.Response.ContentType = "application/json; charset=utf-8"; this.Context.Response.Write(json); Before you start, place below
[System.Web.Services.WebMethod(EnableSession = true)] [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] make function empty
when the function ends, put below the line
this.Context.Response.ContentType = "application/json; charset=utf-8"; this.Context.Response.Write(json); Program example
[System.Web.Services.WebMethod(EnableSession = true)] [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] public void testJson() { string json = "{}"; this.Context.Response.ContentType = ""; this.Context.Response.Write(json); } For a valid JSON response, use this code.
[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); } }