tags:

views:

914

answers:

5

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

A: 

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.

David
Thanks for the suggestion. I calculated the content-length by hand and came up with 46 also. I had let fiddler calculate this on its own. Unfortunately, this didn't resolve the issue.
Thanks David. I got this working.
A: 

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.

Adam Sills
are json and xml the only formats supported? I thought that they are for complex objects.
Thanks Adam. I got this working.
A: 

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.

W. Kevin Hazzard
+1  A: 

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"&gt;
<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" }
sbeardsley
A: 
User-Agent: Fiddler
Host: localhost:8889
Content-Length: 113
**Content-Type: text/xml**

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

Angshuman