为什么这个简单的Web服务拒绝将JSON返回给客户端?
这是我的客户代码:
var params = { };
$.ajax({
url: "/Services/SessionServices.asmx/HelloWorld",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
timeout: 10000,
data: JSON.stringify(params),
success: function (response) {
console.log(response);
}
});
服务:
namespace myproject.frontend.Services
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class SessionServices : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string HelloWorld()
{
return "Hello World";
}
}
}
的web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
回复:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>
无论我做什么,响应总是以XML形式返回。如何让Web服务返回Json?
修改
这是Fiddler HTTP跟踪:
REQUEST
-------
POST http://myproject.local/Services/SessionServices.asmx/HelloWorld HTTP/1.1
Host: myproject.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myproject.local/Pages/Test.aspx
Content-Length: 2
Cookie: ASP.NET_SessionId=5tvpx1ph1uiie2o1c5wzx0bz
Pragma: no-cache
Cache-Control: no-cache
{}
RESPONSE
-------
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 19 Jun 2012 16:33:40 GMT
Content-Length: 96
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>
我已经不知道我现在读了多少文章试图解决这个问题。说明不完整或由于某种原因无法解决我的问题。 一些更相关的包括(都没有成功):
还有其他一些一般性文章。
答案 0 :(得分:44)
终于明白了。
已发布的应用代码正确无误。问题在于配置。正确的web.config是:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<handlers>
<add name="ScriptHandlerFactory"
verb="*" path="*.asmx"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
根据文档,从.NET 4向上注册处理程序应该是不必要的,因为它已被移动到machine.config。无论出于何种原因,这对我不起作用。但是将注册添加到我的应用程序的web.config解决了这个问题。
许多关于此问题的文章都指示将处理程序添加到<system.web>
部分。这不起作用,并导致一大堆其他问题。我尝试将处理程序添加到这两个部分,这会产生一组其他迁移错误,这些错误完全错误地导致了我的故障排除。
如果它对其他人有帮助,如果我再次遇到同样的问题,这里是我要检查的清单:
type: "POST"
?contentType: "application/json; charset=utf-8"
?dataType: "json"
?[ScriptService]
属性?[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
属性? (即使没有这个属性,我的代码仍可正常工作,但很多文章都说这是必需的)ScriptHandlerFactory
添加到<system.webServer><handlers>
?<system.web><httpHandlers>
?希望这可以帮助任何有同样问题的人。并感谢海报提出建议。
答案 1 :(得分:26)
上述解决方案没有成功,我在这里解决了这个问题。
将此行放入您的Web服务中,而不是返回类型只需在响应上下文中写入字符串
this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
答案 2 :(得分:12)
如果您希望继续使用Framework 3.5,则需要按如下方式更改代码。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[ScriptService]
public class WebService : System.Web.Services.WebService
{
public WebService()
{
}
[WebMethod]
public void HelloWorld() // It's IMP to keep return type void.
{
string strResult = "Hello World";
object objResultD = new { d = strResult }; // To make result similarly like ASP.Net Web Service in JSON form. You can skip if it's not needed in this form.
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
string strResponse = ser.Serialize(objResultD);
string strCallback = Context.Request.QueryString["callback"]; // Get callback method name. e.g. jQuery17019982320107502116_1378635607531
strResponse = strCallback + "(" + strResponse + ")"; // e.g. jQuery17019982320107502116_1378635607531(....)
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-length", strResponse.Length.ToString());
Context.Response.Flush();
Context.Response.Write(strResponse);
}
}
答案 3 :(得分:6)
从Web服务返回纯字符串有更简单的方法。我把它称为CROW功能(让它易于记忆)。
[WebMethod]
public void Test()
{
Context.Response.Output.Write("and that's how it's done");
}
如您所见,返回类型为&#34; void&#34;,但CROW函数仍会返回您想要的值。
答案 4 :(得分:1)
我有一个带有返回字符串的方法的.asmx Web服务(.NET 4.0)。该字符串是序列化列表,就像您在许多示例中看到的那样。这将返回未包装在XML中的json。没有更改web.config或需要第三方DLL。
var tmsd = new List<TmsData>();
foreach (DataRow dr in dt.Rows)
{
m_firstname = dr["FirstName"].ToString();
m_lastname = dr["LastName"].ToString();
tmsd.Add(new TmsData() { FirstName = m_firstname, LastName = m_lastname} );
}
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string m_json = serializer.Serialize(tmsd);
return m_json;
使用该服务的客户端部分如下所示:
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json',
url: 'http://localhost:54253/TmsWebService.asmx/GetTombstoneDataJson',
data: "{'ObjectNumber':'105.1996'}",
success: function (data) {
alert(data.d);
},
error: function (a) {
alert(a.responseText);
}
});
答案 5 :(得分:0)
对我而言,它适用于我从这篇文章中获得的代码:
[WebInvoke(UriTemplate = "HelloWorld", Method = "GET"), OperationContract]
public Message HelloWorld()
{
string jsonResponse = //Get JSON string here
return WebOperationContext.Current.CreateTextResponse(jsonResponse, "application/json; charset=utf-8", Encoding.UTF8);
}
答案 6 :(得分:0)
我已经尝试了上述所有步骤(甚至答案),但我没有成功,我的系统配置是Windows Server 2012 R2,IIS 8.以下步骤解决了我的问题。
更改了已管理管道=经典的应用池。
答案 7 :(得分:0)
我知道这是一个很老的问题,但我今天遇到了同样的问题而且我一直在寻找答案,但没有结果。经过长时间的研究,我找到了实现这项工作的方法。要从服务中返回JSON,您需要以正确的格式提供请求中的数据,请在请求之前使用JSON.stringify()
解析数据并且不要忘记contentType: "application/json; charset=utf-8"
,使用此方法应提供预期结果。< / p>
答案 8 :(得分:0)
希望这会有所帮助,看起来您仍然需要在请求中发送一些JSON对象,即使您调用的方法没有参数。
var params = {};
return $http({
method: 'POST',
async: false,
url: 'service.asmx/ParameterlessMethod',
data: JSON.stringify(params),
contentType: 'application/json; charset=utf-8',
dataType: 'json'
}).then(function (response) {
var robj = JSON.parse(response.data.d);
return robj;
});
答案 9 :(得分:-1)
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;