我想我已经阅读了XDomainRequest上的每个StackOverflow帖子以及另外几个关于AJAX和WCF的帖子,但我仍然无法使 XDomainRequest AJAX调用工作。我在我的WCF服务上实现了CORS(“Access-Control-Allow-Origin”),我的代码在Chrome和Firefox中使用xmlHttpRequest工作得很好,但是我正在跨域调用,所以对于IE我需要使用XDomainRequest对象。当我对没有args的方法进行GET或POST时,我的xdr工作正常,我甚至可以使用查询字符串成功地使用GET动词到args方法,但是当我尝试 POST 到a方法 with args my xdr抛出一个错误,即使我在BeginRequest方法中放了一个断点,我看到服务器的响应是“200 OK”。我想我已经尝试了配置文件设置的每个组合,但我必须遗漏一些东西。非常感谢任何指导我指向正确方向的帮助。
以下是我的代码的相关部分:
WCF - Global.asax
protected void Application_BeginRequest(object sender, EventArgs e)
{
//for CORS
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
}
WCF - IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST")]
string GetData();
[OperationContract]
[WebInvoke(Method = "POST")]
string GetData2(string param);
}
WCF - Service1.svc
public class Service1 : IService1
{
public string GetData()
{
return "Hello";
}
public string GetData2(string param)
{
return string.Format("Hello - {0}", param);
}
}
WCF - Web.config
<?xml version="1.0"?>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="WcfService1.Service1Behavior" name="WcfService1.Service1">
<endpoint address="AjaxEndpoint" behaviorConfiguration="AjaxBehavior" contract="WcfService1.IService1" bindingConfiguration="AjaxBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<!--<serviceMetadata httpGetEnabled="true" />-->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="AjaxBinding"/>
</webHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
客户端AJAX调用
var WcfURL = "http://localhost/WcfService1/Service1.svc/AjaxEndpoint"
if (window.XDomainRequest) {
//IE - use cross-domain request
xdr = new XDomainRequest();
xdr.onprogress = function () { alert("onprogress: " + xdr.responseText) };
xdr.onload = function () { updateText(xdr.responseText) };
xdr.onerror = function () { alert("xdr error") };
xdr.timeout = 7500;
xdr.ontimeout = function () { alert("xdr timeout") };
var data = "passedInParam";
//var method = "/GetData"; //this works
var method = "/GetData2"; //this throws an error
xdr.open("POST", WcfURL + method);
xdr.send(data);
}
答案 0 :(得分:4)
我找到了解决方案。感谢Fiddler,我能够查看更多我从服务中获得的回复。错误是
传入的消息具有意外的消息格式“Raw”。该 该操作的预期消息格式是'Xml','Json'。这个可以 是因为尚未配置WebContentTypeMapper 结合。
有了这些信息,我开始研究WebContentTypeMapper。我发现this文章很有用,在添加WebContentTypeMapper方法之后,我能够看到来自XDomainRequest的我的请求的contentType是“application / json”类型(正如预期的那样)当我做时没有在XDomainRequest.send()方法中包含一个参数,但在传入参数时更改为键入“application / octet-stream”。(即xdr.send(data))我不知道为什么它更改为八位字节流,但这样做会导致服务方法抛出500错误(使用上面的消息),从而导致xdr请求出错。但WebContentTypeMapper被恰当地命名并使用它来更改contentType很容易。在纠正它以输入Json后,我的xdr运行良好。
以下是方法:
public class CustomContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
if (contentType == "application/octet-stream")
{
return WebContentFormat.Json;
}
else
{
return WebContentFormat.Default;
}
}
}
以下是配置文件中已更新的部分:
<endpoint address="AjaxEndpoint" behaviorConfiguration="AjaxBehaviour" contract="WcfService1.IService1" binding="customBinding" bindingConfiguration="CustomMapper"/>
...
<bindings>
<customBinding>
<binding name="CustomMapper">
<webMessageEncoding webContentTypeMapperType="WcfService1.CustomContentTypeMapper, WcfService1" />
<httpTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>