2012-06-19 35 views
2

將XDomainRequest調用POST到WCF服務方法我認爲我已經閱讀了XDomainRequest上的每個StackOverflow後和AJAX和WCF上的另外幾十個,但我仍然無法獲得XDomainRequest AJAX調用上班。我在我的WCF服務上實現了CORS(「Access-Control-Allow-Origin」),我的代碼可以在Chrome和Firefox中使用xmlHttpRequest,但是我正在調用跨域,所以對於IE我需要使用XDomainRequest對象。我的xdr工作正常,當我GET或POST到一個沒有參數的方法時,我甚至可以使用GET動詞成功地將一個方法與使用查詢字符串的參數,但是當我嘗試POST到方法和參數我的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 - 服務1。 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); 

}

回答

4

我找到了解決方案。感謝Fiddler,我能夠查看更多來自服務的回覆。錯誤是

傳入消息具有意外的消息格式'原始'。預期的操作消息格式爲'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> 
+0

這是我沒有管理這樣一個簡單的找到一個很好的解釋辦法。謝謝! – pencilCake

+0

當我使用XDomainRequest嘗試POST時,我也遇到了關於'WebContentTypeMapper'的相同問題。當我插入MDK1969的上述解決方案時,我擺脫了錯誤,但仍然收到HTTP 404 Method未找到錯誤。請幫忙! –

+0

其實我注意到了提琴手中的「EndPoint Not Found」錯誤。以下是我服務的終點。 <端點地址=「」binding =「webHttpBinding」behaviorConfiguration =「web」contract =「ItemService.IItemSerivce」/>