【问题标题】:How to POST a XDomainRequest call to a WCF service method with parameters如何使用参数将 XDomainRequest 调用发布到 WCF 服务方法
【发布时间】:2012-06-21 18:13:52
【问题描述】:

我想我已经阅读了关于 XDomainRequest 的每篇 StackOverflow 帖子以及关于 AJAX 和 WCF 的另外几十篇文章,但我仍然无法让 XDomainRequest AJAX 调用正常工作。我已经在我的 WCF 服务上实现了 CORS(“Access-Control-Allow-Origin”),并且我的代码在 Chrome 和 Firefox 中与 xmlHttpRequest 一起工作得很好,但是我正在跨域进行调用,所以对于 IE,我需要使用XDomainRequest 对象。当我 GET 或 POST 到没有 args 的方法时,我的 xdr 工作正常,我什至可以使用查询字符串成功地将 GET 动词用于具有 args 的方法,但是当我尝试 POST 到方法 with args 我的 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);

}

【问题讨论】:

    标签: ajax wcf xdomainrequest


    【解决方案1】:

    我找到了解决方案。感谢 Fiddler,我能够查看更多从服务返回的响应。错误是

    传入的消息具有意外的消息格式“原始”。这 该操作的预期消息格式为“Xml”、“Json”。这个可以 是因为没有配置 WebContentTypeMapper 绑定。

    有了这些信息,我开始研究 WebContentTypeMapper。我发现this 文章很有用,在添加 WebContentTypeMapper 方法后,我能够看到来自 XDomainRequest 的请求的 contentType 类型为“application/json”(如预期的那样),而我这样做 not 在 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>
    

    【讨论】:

    • 这是一个很好的解释,我无法以如此简单的方式找到它。谢谢!
    • 当我尝试使用 XDomainRequest 进行 POST 时,我也遇到了关于“WebContentTypeMapper”的相同问题。当我插入 MDK1969 的上述解决方案时,我摆脱了错误,但我仍然收到 HTTP 404 Method not found 错误。请帮忙!
    • 实际上我注意到 Fiddler 中出现“EndPoint Not Found”错误。以下是我的服务端点。
    • 当我将我的配置与上述配置设置进行比较时,我在 web.config 中发现了一个问题。它现在正在工作。这篇文章真的很有帮助。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多