Reputation:

Getting an http 400 error on calling a restful wcf service using http post

I have setup a wcf service. Unfortunately, when I call the service over fiddler, the web, or whereever, I get an http 400 error. I am really perplexed at where to start to solve this problem. Any suggestions are appreciated. WSDL is not an option at this time. REST is a requirement. I was able to make calls previously using GET, however, get is not secure as I need to pass the userid and password to validate and that would be easily viewable.

The wcf service has the following interface:

    [WebInvoke(UriTemplate = "/Login", Method="POST", 
        ResponseFormat = WebMessageFormat.Xml, 
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    [OperationContract]
    bool Login(string UserName, string PassWord, string AppKey);

The service has the following code. yes, this code is incomplete and I know that AppKey really doesn't do anything, its there as a place holder at this point.

    public bool Login(string UserName, string PassWord, string AppKey)
    {
        bool bl = false;
        if (String.IsNullOrEmpty(AppKey))
        {
            throw (new ApplicationException(AppKeyNull));
        }
        if (Membership.ValidateUser(UserName, PassWord))
        {
            bl = true;
        }
        return (bl);
    }

I am trying to call the service over fiddler. I have the following url:

http://127.0.0.1:82/WebServices/RemoteAPI.svc/Login

I have the following header setup:

User-Agent: Fiddler
Host: 127.0.0.1:82
Content-Length: 46
Content-Type: application/x-www-form-urlencoded

I have the following body setup:

UserName=xxxxxx&PassWord=yyyyyy&AppKey=blah

Upvotes: 0

Views: 7559

Answers (5)

Angshuman
Angshuman

Reputation: 1

User-Agent: Fiddler
Host: localhost:8889
Content-Length: 113
**Content-Type: text/xml**

Check if "Content-Type" is missing in the Request Header ?

Upvotes: 0

sbeardsley
sbeardsley

Reputation: 146

Give this a try:

Change your method signature and attributes to this

[WebInvoke(UriTemplate = "/Login", Method = "POST", ResponseFormat = WebMessageFormat.Xml, RequestFormat= WebMessageFormat.Xml)]
[OperationContract]
bool Login(LoginContract loginInfo);

Then add a new data contract LoginContract

[DataContract]
public class LoginContract
{
    [DataMember]
    public string UserName { get; set; }

    [DataMember]
    public string PassWord { get; set; }

    [DataMember]
    public string AppKey { get; set; }

}

Then when you post with Fiddler specify Content-Type: text/xml

and use this as your request body

<LoginContract xmlns="http://schemas.datacontract.org/2004/07/YourAppName" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AppKey>blah</AppKey>
<PassWord>testpwd</PassWord>
<UserName>test</UserName></LoginContract>

Alternatively, if you wanted to use JSON as your request body change the RequestFormat = WebMessageFormat.JSON and pass this in as your Request Body

{ "AppKey": "blah", "PassWord": "testpwd", "UserName": "test" }

Upvotes: 2

W. Kevin Hazzard
W. Kevin Hazzard

Reputation: 868

Check out WCF REST Contrib for help with this. Or you could accept a Stream parameter in your implementing method and use the HttpUtility.ParseQueryString utility to parse out the query string values from the POSTed body.

Upvotes: 0

Adam Sills
Adam Sills

Reputation: 17062

Is that a valid data format to pass to the REST service?

I can only assume you're using this: http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webinvokeattribute.aspx

And you're not specifying a RequestFormat, which supports XML and JSON. Your body is neither JSON nor XML.

Upvotes: 0

David
David

Reputation: 2174

A 400 error could happen if Content-Length is off a bit, if you're calculating it yourself for some reason. Might need more information, like the full text of the http request.

Upvotes: 0

Related Questions