0

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

5 Answers 5

2

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" }
Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

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.
0

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.

1 Comment

are json and xml the only formats supported? I thought that they are for complex objects.
0

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.

Comments

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.