简体   繁体   中英

400 Bad Request JQuery WCF Service

I created a WCF web service in ASP.NET 4.5 in VS2012 that returns a JSON response. The service works fine with the built in webservice client and I got the endpoints set up correctly in the Web.config file.

On the client side, I have a simple test script in Jquery, however, after running the script, I get a HTTP/1.1 400 Bad Request.

The web service requires no input at all - so data: is set to an empty string.

Here is what I get when calling the service (using HTTP Live Headers add-on in FireFox).

http://localhost:58234/CCSVC.svc/Get_BTCE_BTC_USD

OPTIONS /CCSVC.svc/Get_BTCE_BTC_USD HTTP/1.1
Host: localhost:58234
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Origin: http://localhost:59099
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive

HTTP/1.1 400 Bad Request
Cache-Control: private
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcc2l0ZXMyXENyeXB0b0NvaW5TZXJ2aWNlc1xDQ1NWQy5zdmNcR2V0X0JUQ0VfQlRDX1VTRA==?=
X-Powered-By: ASP.NET
Date: Mon, 23 Dec 2013 16:08:27 GMT
Content-Length: 0

And the script:

$(document).ready(function () {


    $('#btnRefresh').click(function () {

       $.ajax({
            type: 'GET',
            url: 'http://localhost:58234/CCSVC.svc/Get_BTCE_BTC_USD',
            data: '',
            contentType: 'application/json',
            dataType: 'json',
            processData: true,
            crossDomain: true,
            success: function (msg) {
                ServiceSucceeded(msg);
            },
            error: function (msg) {
                ServiceFailed(msg);
            }
        });


        function ServiceSucceeded(result) {
            alert("success");
        };

        function ServiceFailed(result) {
            alert("fail");
        };


    });




});

naturally, it fails. I've tried several different combinations with no luck and POST, as well as GET. crossDomain true/false, processData true/false, etc. nothing seems to work.

Here's the CONTRACT for the webservice:

<OperationContract()>
<WebInvoke(BodyStyle:=WebMessageBodyStyle.Bare, RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json)>
Function Get_BTCE_BTC_USD() As TradeData

This appears to be a problem with the request, but the error does not indicated what that might be.

Here is the inside of the web.config in the WCF service:

  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="CryptoCoinServices.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="metadataBehavior" name="CryptoCoinServices.Service1">
        <!-- leave address empty for localhost -->
        <endpoint
            address="" 
            binding="basicHttpBinding"
            contract="CryptoCoinServices.IService1"
           />
        <endpoint
          address="mex"
          binding="mexHttpBinding"
          contract="IMetadataExchange" />
      </service>
    </services>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

Here are recommended changes in the jQuery script (still doesn't work, but the {} for the data is mandatory, apparently):

   $.ajax({
        type: 'POST',
        url: 'http://localhost:58234/CCSVC.svc/Get_BTCE_BTC_USD',
        data: '{}',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        processData: true,
        crossDomain: true,
        success: function (msg) {
            ServiceSucceeded(msg);
        },
        error: function (msg) {
            ServiceFailed(msg);
        }
    });

New Error after change to webHttpBinding:

http://localhost:58234/CCSVC.svc/Get_BTCE_BTC_USD

OPTIONS /CCSVC.svc/Get_BTCE_BTC_USD HTTP/1.1
Host: localhost:58234
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Origin: http://localhost:59099
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Length: 513
Content-Type: application/xml; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcc2l0ZXMyXENyeXB0b0NvaW5TZXJ2aWNlc1xDQ1NWQy5zdmNcR2V0X0JUQ0VfQlRDX1VTRA==?=
X-Powered-By: ASP.NET
Date: Mon, 23 Dec 2013 17:02:44 GMT

As your are doing cross domain communication and by default WCF does not support cross domain communication.Check out following link for complete example

Calling cross domain wcf service using Jquery

I created a sample WCF and it works with the scenario you explained. However the code is in c#. You can try the below config and code.

  namespace WCF
{
    [ServiceContract(Namespace = "Testing")]
    //[ServiceContract]
    public interface ITestWCF
    {
        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        String HelloWorld();

    }
}



namespace WCF
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService2" in both code and config file together.
    class TestWCF : ITestWCF
    {
        public string HelloWorld()
        {

            return "Hello!!!";
        }

    }
}

Ajax call:

$.ajax({
            url: "Service1.svc/rest/HelloWorld?",
            type: "POST",
            data: "{}",       
            success: fnsuccesscallback,
            contentType: "application/json; charset=utf-8",
            error: fnerrorcallback,
            dataType: "json"
        });

Web.config:

<system.serviceModel>   
<client />
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpEndpointBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="None" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>        
  <service name="WCF.TestWCF" behaviorConfiguration="TestWCFBehaviour">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:1991/Service1.svc"/>
      </baseAddresses>
    </host>
    <endpoint address="rest" binding="webHttpBinding" contract="WCF.ITestWCF" behaviorConfiguration="TestWCFEndPointBehaviour" name="httpEndpoint"></endpoint>
    <endpoint address="soap" binding="basicHttpBinding" contract="WCF.ITestWCF" bindingConfiguration="BasicHttpEndpointBinding"/>
    <endpoint address="mex"  binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="TestWCFBehaviour">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="TestWCFEndPointBehaviour">
      <!--<enableWebScript/>-->
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Please note that i have exposed a endpoint with webHttpBinding and i have named it rest

You can also refer http://www.wcf.dotnetarchives.com/2013/12/invoking-restful-wcf-service-with_20.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM