2017-06-26 37 views
5

Próbuję wywołać usługę WCF z wywołania ajax z jQuery. Udaje mi się wywołać WCF z SOAP-UI iz Excel/VBA. Mój problem pochodzi z żądania opcje, które wysłał i nie POST następująco:Jak wywołać usługę WCF z javascript?

  • jeśli ustawić adres URL do http://mywcf/service.svc OPTIONS jest wysyłany i uzyskać status 400 Bad Request i żądanie POST nie zostanie wysłana. W tym przypadku brakuje nagłówka HTTP/1.1 (w porównaniu z nagłówkami SOAP-UI).
  • jeśli ustawię URL na http://mywcf/service.svc HTTP/1.1, OPTIONS zostanie wysłane i otrzymam status 200 OK, ale żądanie POST nie zostanie wysłane. W tym przypadku HTTP/1.1 wydaje się być interpretowany jako nazwa pliku.

Czy ktoś może mi powiedzieć, jak wywołać akcję POST na WCF z javascript i dodać nagłówek HTTP/1.1 bez uszkodzenia adresu URL usługi?

Oto wyciąg z mojego ajax rozmowy:

var soapData = '' 
     +'<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mic="http://microsoft.wcf.documentation">' 
     +' <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://docs.oasis-open.org/ws-rx/wsrm/200702">' 
     +'  <wsrm:Sequence>' 
     +'   <wsrm:Identifier>s:Sender a:ActionNotSupported</wsrm:Identifier>' 
     +'   <wsrm:MessageNumber>1</wsrm:MessageNumber>' 
     +'  </wsrm:Sequence>' 
     +'  <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>' 
     +'  <wsa:ReplyTo>' 
     +'   <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>' 
     +'  </wsa:ReplyTo>' 
     +'  <wsa:MessageID>uuid:'+ MsgUid +'</wsa:MessageID>' 
     +'  <wsa:To>'+ Url +'</wsa:To>' 
     +' </soap:Header>' 
     +' <soap:Body xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">' 
     +'  <wsrm:CreateSequence>' 
     +'   <wsrm:AcksTo xmlns:wsa="http://www.w3.org/2005/08/addressing">' 
     +'    <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>' 
     +'   </wsrm:AcksTo>' 
     +'   <wsrm:Offer>' 
     +'    <wsrm:Identifier>urn:soapui:'+ SeqUid +'</wsrm:Identifier>' 
     +'   </wsrm:Offer>' 
     +'  </wsrm:CreateSequence>' 
     +' </soap:Body>' 
     +'</soap:Envelope>'; 

$.ajax({ 
    type: 'POST', 
    url: 'http://mywcf/service.svc', // with or without +' HTTP/1.1' 
    data: soapData, 
    contentType: 'application/soap+xml;charset=UTF-8', 
    dataType: 'xml' 
}); 

Wartości w moim WCF web.config:

<system.webServer> 
    <httpProtocol> 
     <customHeaders> 
      <add name="Access-Control-Allow-Origin" value="*" /> 
      <add name="Access-Control-Allow-Methods" value="POST, OPTIONS" /> 
      <add name="Access-Control-Allow-Headers" value="*" /> 
     </customHeaders> 
    </httpProtocol> 
</system.webServer> 
+1

Jednym z oczywistych problemów jest adres URL połączenia. Musisz podać nazwę metody WCF w url – Sparrow

+0

@Sparrow Udaje mi się wywołać WCF z VBA i SOAP-UI bez ustawiania nazwy metody. Kiedy dodaję nazwę metody do mojego wywołania ajax, wydaje się, że jest interpretowana jako nazwa pliku. Nie sądzę, żeby to było rozwiązanie. – sinsedrix

+0

Niech głosowanie w dół wyjaśni ich wybór, dziękuję. – sinsedrix

Odpowiedz

0

Dodaj końcowego webHttpBinding

<services> 
    <service name="Contract"> 
    <endpoint address="json" binding="webHttpBinding" contract="IContract" bindingConfiguration="ActionsHttpBinding" behaviorConfiguration="ActionrestfulBehavior"/> 
    </service> 

następnie wywołać końcowy z Ajax jako POST lub GET, patrz poniżej przykład:

var data = JSON.stringify({ 
    param1: val1, 
    param2: val2 
}); 
$.ajax({ 
    url: "http://mywcf/service.svc/json/FunctionName", 
    type: "POST", 
    data: data, 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    processData: true 
}).then(function (rsutlt) { 

}).fail(function (fail) { 
}); 
0

Dodaj poniżej kod do Global.asax.cs i usunąć customHeaders z config internetowej.

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 

     if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
     { 
      //These headers are handling the "pre-flight" OPTIONS call sent by the browser 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
      HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
      HttpContext.Current.Response.End(); 
     } 

    } 

Potrzebujesz również usunąć OPTIONSVerbHandler w celu włączenia cors.

<system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <handlers> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <remove name="OPTIONSVerbHandler" /> 
     <remove name="TRACEVerbHandler" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
</system.webServer> 
1

Aby zużywają usługi sieci web przy użyciu jQuery, który jest, aby nawiązać połączenie z usługą WCF, możesz albo użyć jQuery.ajax() lub jQuery.getJSON(). W tym artykule użyłem metody jQuery.ajax().

Aby ustawić żądanie, najpierw zdefiniuj zmienną. Będzie to pomocne podczas wywoływania wielu metod i tworzenia innego pliku js w celu wywołania usługi WCF.

<script type="text/javascript"> 

    var Type; 
    var Url; 
    var Data; 
    var ContentType; 
    var DataType; 
    var ProcessData; 

Następująca funkcja inicjuje zmienne zdefiniowane powyżej, aby nawiązać połączenie z usługą.

function WCFJSON() { 
    var userid = "1"; 
    Type = "POST"; 
    Url = "Service.svc/GetUser"; 
    Data = '{"Id": "' + userid + '"}'; 
    ContentType = "application/json; charset=utf-8"; 
    DataType = "json"; varProcessData = true; 
    CallService(); 
} 

Funkcja CallService wysyła żądania do usługi, ustawiając dane w $ .ajax.

// Function to call WCF Service  
function CallService() { 
    $.ajax({ 
     type: Type, //GET or POST or PUT or DELETE verb 
     url: Url, // Location of the service 
     data: Data, //Data sent to server 
     contentType: ContentType, // content type sent to server 
     dataType: DataType, //Expected data format from server 
     processdata: ProcessData, //True or False 
     success: function(msg) {//On Successfull service call 
      ServiceSucceeded(msg); 
     }, 
     error: ServiceFailed// When Service call fails 
    }); 
} 

function ServiceFailed(result) { 
    alert('Service call failed: ' + result.status + '' + result.statusText); 
    Type = null; 
    varUrl = null; 
    Data = null; 
    ContentType = null; 
    DataType = null; 
    ProcessData = null; 
} 

Uwaga: Poniższy kod sprawdza oświadczenie result.GetUserResult, więc obiekt wynik uzyskuje własność swój serwis nazwę metody + wynik. W przeciwnym razie wystąpi błąd podobny do obiektu, który nie występuje w JavaScript.

function ServiceSucceeded(result) { 
    if (DataType == "json") { 
     resultObject = result.GetUserResult; 

     for (i = 0; i < resultObject.length; i++) { 
      alert(resultObject[i]); 
     } 

    } 

} 

function ServiceFailed(xhr) { 
    alert(xhr.responseText); 

    if (xhr.responseText) { 
     var err = xhr.responseText; 
     if (err) 
      error(err); 
     else 
      error({ Message: "Unknown server error." }) 
    } 

    return; 
} 

$(document).ready(
    function() { 
     WCFJSON(); 
    } 
); 
</script> 
Powiązane problemy