0

I have WCF service in web application and have Ajax client in another web application. In terms of cross-domain issue, I have no problem with GET ajax call, but I have a problem with POST ajax call. I am not sure this is from cross-domain issue though. Anyway, when GET ajax invokes WCF service successfully, but it does not in case of POST ajax invocation.

WCF Service

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UserService/AddUser", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public User AddUser(User input)
{
    var user = input;

    // Do something business logic

    return user;
}

Global.asax in web application that WCF Service resides

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }

Ajax code

<script type="text/javascript">
        $(document).ready(function () {

            $("#submit").click(function () {
                $.ajax({
                    cache: false,
                    type: "POST",
                    async: false,
                    url: "http://localhost:2000/UserService/AddUser",
                    data: { "LoginId" : $("#LoginId").val(), "Name" : $("#Name").val() },
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    processData: true,
                    success: function (userViewModel) {
                        var user = userViewModel;
                        alert(user);
                    }
                });
            });
        });
    </script>

I debugged it with developers tool in Chrome browser and I got following message

Request URL:http://localhost:2000/UserService/AddUser
Request Method:POST
Status Code:400 Bad Request
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:windows-949,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:18
Content-Type:application/json; charset=UTF-8
Host:localhost:2000
Origin:http://localhost:3000
Referer:http://localhost:3000/views/useradd.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
Request Payload
LoginId=11&Name=22
Response Headersview source
Access-Control-Allow-Origin:*
Cache-Control:no-cache, no-store
Connection:Close
Content-Length:1760
Content-Type:text/html
Date:Tue, 14 Feb 2012 05:56:42 GMT
Expires:-1
Pragma:no-cache
Server:ASP.NET Development Server/10.0.0.0
X-AspNet-Version:4.0.30319

As you see it is 400 Bad Request, this is why I doubted that the problem is related with cross-domain issue. But I am not sure.

Can you guess the reason of this problem? Thanks in advance.

Ray
  • 4,038
  • 8
  • 36
  • 48
  • possible duplicate of [Problem sending JSON data from JQuery to WCF REST method](http://stackoverflow.com/questions/4875195/problem-sending-json-data-from-jquery-to-wcf-rest-method) – Ray Feb 14 '12 at 06:27

4 Answers4

0

1- make sure you set crossDomainScriptAccessEnabled="true" in webHttpBinding

Config file should be like following

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true"/>
  </system.web>

  <system.serviceModel>

    <bindings>
      <webHttpBinding>
        <binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>

    <behaviors>

      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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>
      </serviceBehaviors>

    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        <add name="Access-Control-Max-Age" value="1728000" />

      </customHeaders>
    </httpProtocol>
  </system.webServer>

</configuration>

2- your method should decorated like following

for get resquest :

[OperationContract]
[WebGet(UriTemplate = "/Dowork/{name}/{action}", ResponseFormat = WebMessageFormat.Json)]
CompositeType DoWork(string name, string action);

for post request :

[WebInvoke(UriTemplate = "/DoworkPOST/{name}", Method = "POST", ResponseFormat = WebMessageFormat.Json,RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
[OperationContract]
CompositeType DoWorkPost(string name, string action1, string action2);

3-in java script you can access like following

//for get
    function testGet() {
        $.ajax({
            url: 'http://www.yourhost.com/yourservicename.svc/DoWorkPost/azadeh1',
            success: function (data) {
                $("#result").html('Load was performed' + data);
            }
        });


    }

    //for post
    var testobj = { action1: "cook", action2: "dance" };
    function testPost() {
        $.ajax({
            type: "POST",
            url: 'http://www.yourhost.com/yourservicename.svc/DoWorkPost/azadeh',
            data: JSON.stringify(testobj),
            crossDomain:true,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            processdata: false,
            success: function (data) {
                $("#result").html('Load was performed' + data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                $("#result").text(textStatus);
            }
        });


    }

4- check your svc file

<%@ ServiceHost Language="C#" Debug="true" Service="namespace.servicename" CodeBehind="servicename.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
Azadeh Khojandi
  • 3,806
  • 1
  • 30
  • 32
0

I think the problem is that your should use another format of the message body, so you should use other value for the data parameter:

data: JSON.stringify({
    LoginId: $("#LoginId").val(),
    Name : $("#Name").val()

})

See the answer where included different formats of the data representation depend on the BodyStyle attribute which you use.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
0

I'm guessing, it still may be a cross domain issue, as the ports are different.

google chrome dev tool may give more information on that, you should see the response tab there, the response may have an error why is the request not satisfied, also the same tool's console may give more info on that.

Igarioshka
  • 677
  • 3
  • 14
0

Try hosting your service on port 80 because it solves the cross domain problem.

JJJ
  • 32,902
  • 20
  • 89
  • 102
dali
  • 164
  • 13