我已经尝试了几乎所有我能想到的东西,但是我仍然遇到了对我的ajax调用WCF服务的问题。
我的WCF服务有如下方法:
//[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "POST")]
[WebGet]
public string Test(int value)
{
return string.Format("You entered: {0}", value);
}
正如Twitter by Patrick Thomas所述,我也尝试过使用[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped)]
和[WebGet(BodyStyle = WebMessageBodyStyle.WrappedResponse)]
而没有运气。
配置如下:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RestEndpoint">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="NoSecurityRestBinding" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="WebServices.TestService">
<endpoint address="" binding="webHttpBinding" contract="WebServices.ITestService" bindingConfiguration="NoSecurityRestBinding" behaviorConfiguration="RestEndpoint" />
</service>
</services>
</system.serviceModel>
该服务位于不同的域上,因此我将数据格式化为JSONP:
$.ajax({
cache: false,
async: true,
type: "GET", // Was "POST"
dataType: "jsonp",
url: "http://mydomain.com/TestService.svc/Test?callback=?",
data: dataToPost,
contentType: "application/json;charset=utf-8",
success: function (msg) {
var testMsg = JSON.parse(msg);
var status = testMsg.TestResult;
alert(status);
},
error: function (msg) {
alert('Please email Jason with this exception: ' + msg.statusText);
}
});
我得到了:
“parsererror”
“jQuery16408722478272714725_1332817261195未被调用”
我可能做错了什么?我确实验证了所有WCF二进制文件都是4.0。
提前感谢您的帮助!
答案 0 :(得分:2)
您不希望将enableWebScript
行为应用于端点。这特别支持Microsoft的ASP.NET AJAX客户端堆栈,该堆栈具有针对所有请求/响应的特定JSON编码。只用webHttp
替换它,看看是否能解决您的问题。其他一切看起来都不错。
我建议的下一步是将webHttp
行为元素的the automaticFormatSelection
attribute设置为true。这样,当它检测到HTTP请求的接受内容类型是JSON时,它确保将响应序列化为JSON。
<强>更新强>
我刚才记得的是,由于这是JSONP,请求将来自<script/>
标记,因此WCF可能默认为XML响应。因此, 也希望在="Json"
行为上设置defaultOutgoingResponseFormat
webHttp
,以便默认情况下使用JSON格式化响应。
作为旁注,在jQuery AJAX请求上设置contentType
是没有意义的,因为JSONP请求没有正文,因为它基于所有查询字符串。
答案 1 :(得分:2)
如果您想避免WCF web.config麻烦,那么您可以将“Factory”属性添加到您的WCF标记中。
如果您还想进行JSONP调用并避免出现parsererror问题,请使用此类:
<%@ ServiceHost Language="C#" Service="MyWebApp.MyWCFService" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>
使用以下类覆盖工厂
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
public class JSONPEnabledWebServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new JSONPEnabledWebServiceHost(serviceType, baseAddresses);
}
private class JSONPEnabledWebServiceHost : WebServiceHost
{
public JSONPEnabledWebServiceHost(Type serviceType, Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
}
protected override void OnOpening()
{
base.OnOpening();
foreach (ServiceEndpoint endpoint in this.Description.Endpoints) {
WebHttpBinding webBinding = endpoint.Binding as WebHttpBinding;
if (webBinding != null) {
webBinding.CrossDomainScriptAccessEnabled = true;
}
}
}
}
}
所以现在你的工厂属性将是
<%@ ServiceHost Language="C#" Service="MyWebApp.MyWCFService" Factory="MyWebApp.JSONPEnabledWebServiceHostFactory" %>
答案 2 :(得分:1)
JSONP和跨域调用不支持POST请求。 JSONP返回由填充(回调函数)包装的JSON片段。在后面,这被处理为页面DOM中动态添加的script
元素,该元素指向跨域地址。加载目标脚本资源后,将执行回调函数。因此,您只能使用GET请求 - script
元素无法执行POST。
答案 3 :(得分:1)
添加jsonpCallback
选项
$.ajax({
jsonpCallback: 'yourCallbackFunctionName',
cache: false,
async: true,
type: "GET", // Was "POST"
dataType: "jsonp",
url: "http://mydomain.com/TestService.svc/Test?callback=?",
data: dataToPost,
contentType: "application/json;charset=utf-8",
success: function (msg) {
var testMsg = JSON.parse(msg);
var status = testMsg.TestResult;
alert(status);
},
error: function (msg) {
alert('Please email Jason with this exception: ' + msg.statusText);
}
});
答案 4 :(得分:1)
这个问题在过去的3年里曾多次被我误认。每次我遇到它并修好它然后忘了记笔记。下次它发生时,我开始抓挠并再次寻找解决方案。所以,让我在这里记录我的解决方案并与可能处理此问题的人分享。按照以下步骤确保您使用的是JQuery 1.8或更高版本的.net framework 4.0,它将起作用。
<behaviors> <endpointBehaviors> <behavior name="webHttpBehavior"> <webHttp /> </behavior> </endpointBehaviors> </behaviors>
<bindings> <webHttpBinding> <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" /> </webHttpBinding> </bindings>
<services> <service name="dpRestService.qcmmsService"> <endpoint address="" behaviorConfiguration="webHttpBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="gwsRestService.qcmmsService" /> </service> </services>
[WebGet(UriTemplate =“您的服务模板”,ResponseFormat = WebMessageFormat.Json)]
$。AJAX({ url:url, type:'GET',// ajax调用的类型 数据:{}, contentType:'application / json', crossDomain:true, dataType:'jsonp',
成功:callBackFun, 错误:errorFun });
我希望这会有所帮助。
答案 5 :(得分:-1)
经过多次的痛苦,我设法得到一个简单的jquery / ajax调用一个简单的休息服务返回带回调的jsonp。在尝试在url中设置回调后我终于来了 设法通过将“jsonpCallback”和回调名称添加到参数来使其工作。
$.ajax({
type : 'GET',
url : 'http://localhost:8080/RestimpleApp/report/extract',
dataType : 'jsonp',
jsonpCallback : "jsoncallback",
success : function(json) {
alert('success');
},
error : function(jqXHR, status) {
alert("Failed " + status + jqXHR);
}
});
在服务器端,我必须将回复JSON包装在回调名称中(“jsoncallback”)。
@GET
@Produces({ MediaType.APPLICATION_JSON })
public String extractData() {
System.out.println("Incoming call = ");
StringBuilder json = new StringBuilder("jsoncallback(");
json.append("{\"sEcho\": 7,");
json.append("\"iTotalRecords\": \"600\",");
json.append("\"iTotalDisplayRecords\": \"12\",");
json.append("\"aaData\": [");
json.append("{");
json.append("\"engine\": \"Gecko\",");
json.append("\"browser\": \"Firefox 1.0\",");
json.append("\"platform\": \"Win 98+ / OSX.2+\",");
json.append("\"version\": \"1.7\",");
json.append("\"grade\": \"A\"");
json.append("},");
json.append("{");
json.append("\"engine\": \"Gecko\",");
json.append("\"browser\": \"Firefox 1.5\",");
json.append("\"platform\": \"Win 98+ / OSX.2+\",");
json.append("\"version\": \"1.8\",");
json.append("\"grade\": \"A\"");
json.append("} ]");
json.append("}");
json.append(");");
return json.toString();
}
浪费了很多时间试图让它发挥作用:(