Asmx Web服务返回xml而不是json,试图删除< string xmlns ="http://tempuri.org/"从服务输出 [英] Asmx web service returning xml instead of json, Trying to remove <string xmlns="http://tempuri.org/"> from service output
问题描述
最近3个小时我一直在寻找100个链接,例如将scriptfactory添加到webconfig,3个错误,设置内容类型等.
I have been looking for 100's of links for last 3 hours eg adding scriptfactory to webconfig, 3 mistakes, setting content type etc.
我无法弄清楚到底是什么错误.
I am not able to figure out what actually the mistake is.
环境: 在.net 4.0上运行的服务 在.net 4.0上运行的Web应用程序
Environment: Service running on .net 4.0 Web application running on .net 4.0
要求: 我需要将jqGrid与asmx Web服务绑定,该服务将以字符串形式返回json. Web服务文件包含以下代码.
Requirements: I need to bind a jqGrid with asmx web service that is returning me a json as a string. Web service file contains 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如下
<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如下
<table id="jqgajax">
</table>
<div id="jqgajax">
</div>
单击调用"按钮时Web服务输出
Web Service output when clicking on Invoke button
<string xmlns="http://tempuri.org/">
[{"ProcessName":"Dropbox","WorkingSet64":22736896},
{"ProcessName":"fdhost","WorkingSet64":1941504},
{"ProcessName":"IntelliTrace","WorkingSet64":39276544}
]
</string>
请提出我所缺少的内容.
<string xmlns="http://tempuri.org/">
标记使我很恼火.我假设这些标签没有让我的网格能够绑定.
Please suggest what is there that I am missing.
<string xmlns="http://tempuri.org/">
tags are irritating me. I am assuming that these tags are not letting my grid able to bind.
更新:
ASMX服务现在如下所示.
[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; }
}
推荐答案
单击调用"按钮将返回XML,因为请求未指定contentType: 'application/json; charset=utf-8'
.因此,单击调用"按钮的实验并没有真正帮助.
Clicking on the Invoke button returns XML because the request don't specify the contentType: 'application/json; charset=utf-8'
. So the experiment with clicking on Invoke button help not really.
代码中的主要问题是您将数据转换为Web方法内部的字符串.线
The main problem in your code is that you convert the data to string inside of web method. The line
json = Lib.ToJSON(obj);
不需要
.通常要做的是返回对象. GetJsonServerProcess
应该更改为类似
are not needed. What one typically do is returning the object. The 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 which wait jqGrid is another (see here). So you cave to specify jsonReader
which describe 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; }
}
此外,绝对不要在Ajax url
中使用http://localhost:1092/
前缀,因为出于安全原因,您只能从同一站点获取数据. jqGrid中的data
参数具有与jQuery中相同的含义,因此您应该删除data: "{}"
并将type: "POST"
从ajaxGridOptions
移到mtype: "POST"
.结果,您将获得类似
Additionally you should never use http://localhost:1092/
prefix in Ajax url
because you cal only get data from the same site because of security reasons. The data
parameter in jqGrid has another meaning as in jQuery so you should remove data: "{}"
and move type: "POST"
from ajaxGridOptions
to mtype: "POST"
. As the 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 don't tested the code, but it should be more close to what you need.
已更新:您应通过更改jsonReader
来修复代码.您可以在此处下载有效的演示.它显示网格
UPDATED: You should fix the code by changing jsonReader
. You can download the working demo here. It display the grid
我在服务器端使用了代码
I used on the server side the 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; }
}
}
并在客户端
$("#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
这篇关于Asmx Web服务返回xml而不是json,试图删除< string xmlns ="http://tempuri.org/"从服务输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!