Receiving POST data in WCF Service

11,596

Your problem is that you're passing a JSON object to the operation, but the operation is expecting a JSON string. If I understand correctly the Java code, this is what you're sending:

{
    "userInfo" : {
        "Email" : "mail",
        "Password" : "pass",
        "Cauntry" : "country",
        "UserName" : "username"
    }
}

Which is not a JSON string.

There are a couple of things you can do. The first alternative is to modify the operation not to take a string, but to take a data contract which is equivalent to that object.

The code would look something like the one below. Notice that you should also change the body format to Bare (instead of Wrapped).

public class RequestData
{
    public UserInfo userInfo { get; set; }
}

public class UserInfo
{
    public string Email { get; set; }
    public string Password { get; set; }
    public string Cauntry { get; set; } // typo to match the OP
    public string UserName { get; set; }
}

[ServiceContract]
public interface IRestServiceImpl
{
    [OperationContract]
    [WebInvoke(Method = "POST",
        UriTemplate = "registerUser",
        BodyStyle = WebMessageBodyStyle.Bare,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    void receiveData(RequestData data);
}

Another alternative, if the "schema" of the data changes every time, would be to take the input as a Stream (not a String). That way you should be able to accept basically any input. You may also need a content type mapper. You can find more information about this scenario at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx.

Share:
11,596
Amer A.
Author by

Amer A.

Updated on June 04, 2022

Comments

  • Amer A.
    Amer A. almost 2 years

    I read many tutorials but I could not get this running for my project. I made few GET services which send data and they work great, but I have problems receiving the data. I would really appreciate it if someone could tell me where I fail, instead of posting some links. :) When I try to call the service in my browser I get the error: Method not allowed. But I Think this is just the first error.

    Here is my code. First the code in Android where I call the service:

    public class MainActivity extends Activity {
    
    String SERVICE_URI = "http://10.0.2.2:51602/RestServiceImpl.svc";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        HttpPost request = new HttpPost(SERVICE_URI + "/registerUser");
        request.setHeader("Accept", "application/json");
        request.setHeader("Content-type", "application/json");
    
        try {
            JSONStringer user = new JSONStringer()
                    .object()
                    .key("userInfo")
                    .object()
                        .key("Email").value("mail")
                        .key("Password").value("pass")
                        .key("Cauntry").value("country")
                        .key("UserName").value("username")
                    .endObject()
            .endObject();
    
            StringEntity entity = new StringEntity(user.toString());
            request.setEntity(entity);
    
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(request);
    
    
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    IRestServiceImpl.cs:

    [ServiceContract]
    public interface IRestServiceImpl
    {
        [OperationContract]
        [WebInvoke(Method = "POST",
            UriTemplate = "registerUser",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json)]
        void receiveData(String data);
    }
    

    RestServiceImpl.cs:

    public class RestServiceImpl : IRestServiceImpl
    {
        public void receiveData(String data)
        {
            //some code
        }
    }
    

    Web.config:

    <?xml version="1.0"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
    
            <endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
    
            </endpoint>
          </service>
        </services>
    
        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehaviour">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="web">
              <webHttp/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    
    </configuration>
    
  • Amer A.
    Amer A. over 11 years
    OK, I changed it to bare and wrote a data contract. But when I send the JSON object in my android emulator, nothing happens. I added a breakpoint inside the receiveData method.
  • carlosfigueira
    carlosfigueira over 11 years
    What do you mean "nothing happens"? What do you get on the HttpResponse instance you received when making the call?
  • Amer A.
    Amer A. over 11 years
    Nothing because before I can get a response, I get ConnectTimeoutException.
  • carlosfigueira
    carlosfigueira over 11 years
    One thing you can try to do is to enable tracing at the server to see if there is any exception which could explain the problem.