Restful WCF service POST methods returns HTTP400 error in fiddler2 - wcf

have created simple Restful service for log in verification. Following are my interface and class definitions.
Interface IDemo:
public interface IDemo
{
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/ValidateUser?Username={UserName}&Password={Password}",
Method = "POST")]
string ValidateUser(string Username, string Password);
}
Class Demo :
public class Demo:IDemo
{
public string ValidateUser(string Username, string Password)
{
Users objUser = new Users();
objUser.UserID = Username;
objUser.Password = Password;
string Msg = LoginDataService.ValidateUser(Username, Password);
return Msg;
}
}
localhost:49922/Demo.svc/ValidateUser?Username=demo&Password=demo (with http:\)
When I try to parse the above URL under the Post Method in Fiddler2 I got Bad Request HTTP400 error.
Can anyone help me what is wrong in my code.
Thanks & Regards,
Vijay

Your URI template looks like you are sending the parameters in the URL. But when you use POST the parameters are sent in the http body.
Note you should not send the username and passord in the url as it can be logged.

For the above REST method the POST from Fiddler needs to be as shown below:
POST http://localhost/Sample/Sample.svc/ValidateUser?Username=demo&Password=demo HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: rajeshwin7
Content-Length: 0
Doing so i get back a 200 OK HTTP Status as shown below:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 44
Content-Type: application/json; charset=utf-8
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 14 Jun 2012 15:35:28 GMT
"Server returns username demo with password demo"

Related

Rest WCF Post Json body parameter is always null while using Fiddler

I have been struggling with this the past few days. I have researched the issue and tried the solutions posted. However it has not worked. I have REST WCF Post method that has
[OperationContract(Name = "ImportRawJson")]
WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json,
UriTemplate = "ImportRawJson/username/{username}/password/{password}/fileName/{fileName}")]
string ImportRawJson(string username, string password, string fileName, string jsonStream);
I am able to consume this through web client. However when I try calling through Fiddler like below the body parameter always results in null and I get an exception.
Fiddler :
Post http://localhost/TimesheetService/Timesheet.svc/ImportRawJson/username/user/password/pwd/fileName/testfiddler
Request Headers:
User-Agent: Fiddler
Host: localhost
Content-Length: 32
Content-Type: application/json; charset=utf-8
Request Body:
{ "jsonStream":{ "ImportRaw": {"TestXml": {"xml": "test" } }}}
Error:
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Length: 127
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Set-Cookie: ASP.NET_SessionId=wh4qxcu1x0vmiv45mmzuuaup; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Tue, 07 May 2013 14:00:58 GMT
{"ErrorCode":"Error","Message":"Procedure or function expects parameter 'jsonStream', which was not supplied."}
Any help as to how I can pass the body parameter. I truly appreciate. I am stuck at this point. Please help!! Thanks in advance
There are a couple of issues in your code. First, if by "JSON stream" you mean any JSON document, you won't be able to use the type string for your code. Instead, you'll need to take it as a Stream (which can basically accept any arbitrary input). If you take the input as a string, you should pass a JSON string to it. And since you set the body type to WrappedRequest, you need to wrap the JSON string in an object, with the parameter name being the member name, and the value you want to pass to your function the value. For example, to pass the string hello world to your operation, you'd need to pass this request body:
{"jsonStream":"hello world"}
But if I guessed correctly, and you want to take any arbitrary JSON, you need to go with the Stream parameter. The blog post at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx has more information about how to implement it.

WCF POST service with WebInvokeBodyStyle as wrapped not working as expected

I have created a WCF POST service with below mentioned signature. This is hosted successfully in IIS and I can see it in the service's help page as:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
Method = "POST",
UriTemplate = "TestMethod/{lang}/{str}/{selectedstring}/")]
string TestMethod(string lang, string str, string selectedstring, string mylist, int testval);
On the service's help page the method shows correctly as
TestMethod/{lang}/{str}/{selectedstring}/ || POST || Service at http://localhost:86/MyRestService.svc/TestMethod/{LANG}/{STR}/{SELECTEDSTRING}/
I am trying to call this service using fiddler with below mentioned options (Based on a few look up on blogs):
Method: Post
URL - 'http://servername:86/MyRestService.svc/TestMethod/en-us/str1/qad11/'
Req. Headers:
User-Agent: Fiddler
Host: servername:86
Content-Type: application/xml
Request Body:
<TestMethod xmlns="http://tempuri.org/"><mylist>string val</mylist><testval>3</testval></TestMethod>
However it always gives me an HTTP result code 411 (Length Required), the same error when I try to call the service from my .net test stub.
Fiddler should calculate the HTTP header named Content-Length for you (at least it does for v2.3.9.3) Check in the raw tab of the request for something like: Content-Length: nnn where nnn is the string length of the request body. If not, then you'll need to add it yourself. Also, you could try a browser plug-in like the POSTMan chrome plug to create your requests.

Metro client hangs when calling WCF webserver with wsHttpBinding

I have generated a webservice client with a local wsdl using Metro 1.2 this way:
./wsimport.sh -extension -verbose -wsdllocation service.wsdl -s src -d target service.wsdl -Xendorsed
The wsdl uses SOAP 1.2 and wsHttpBinding. It's supposed to connect to a WCF server that's using NTLM as authentication method.
I have created an Authenticator to handle the NTLM authentication:
public class NtlmAuthenticator extends Authenticator
{
private String username = "";
private String password = "";
public NtlmAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
}
Which I set before each webservice method is called:
#WebEndpoint(name = "WSHttpBinding_ICustomerService")
public ICustomerService getWSHttpBindingICustomerService() {
ICustomerService service =
super.getPort(new QName("http://xmlns.example.com/services/Customer",
"WSHttpBinding_ICustomerService"), ICustomerService.class);
NtlmAuthenticator auth = new NtlmAuthenticator(username, password);
Authenticator.setDefault(auth);
return service;
}
If I use the wrong username/password, I get a 401 Unauthorized back, which is well and all, but when I use the correct username/password, the call hangs and I never get a response!
The request looks like this (captured it with netcat, so host is different, and no https):
POST / HTTP/1.1
Content-type: application/soap+xml;charset="utf-8";action="http://xmlns.example.com/services/ICustomerService/GetCustomer"
Password: [password]
Authorization: Basic [auth]
Username: [username]
Accept: application/soap+xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.7-b01-
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:5500
Connection: keep-alive
Content-Length: 603
[xml follows]
I have also tried with wget 1.12 (heard that 1.11 had problem with NTLM), but it too never yields a response, just waits.
[...]
---request end---
[writing POST file customerRequest.xml ... done]
HTTP request sent, awaiting response...
I've seen that others have gotten this behaviour before, but I have not been able to find out why. Can anyone shed some light on this? JDK 1.6 on linux.
I found that I missed a line in my generated client code that enabled Addressing and pass it to the getPort super method:
WebServiceFeature wsAddressing = new AddressingFeature(true);
ICustomerService service =
super.getPort(new QName("http://xmlns.example.com/services/Customer",
"WSHttpBinding_ICustomerService"), ICustomerService.class,
wsAddressing);
Why metro didn't generate this is beyond me. The method looked like this in the end:
#WebEndpoint(name = "WSHttpBinding_ICustomerService")
public ICustomerService getWSHttpBindingICustomerService() {
WebServiceFeature wsAddressing = new AddressingFeature(true);
ICustomerService service =
super.getPort(new QName("http://xmlns.example.com/services/Customer",
"WSHttpBinding_ICustomerService"), ICustomerService.class,
wsAddressing);
NtlmAuthenticator auth = new NtlmAuthenticator(username, password);
Authenticator.setDefault(auth);
return service;
}
This in turn added a SOAP header to the message:
<S:Header>
<To xmlns="http://www.w3.org/2005/08/addressing">https://services.example.com/CustomerService.svc</To>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://xmlns.example.com/services/ICustomerService/GetCustomer</Action>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:d33c2888-abfa-474d-8729-95d2bcd17a96</MessageID>
</S:Header>

WCF REST: specify content-type on WebGet Attribute doesn't seem to be working

probably something i doing wrong, but i am returning XML from my WCF Rest service which is built with VS 2010. In fiddler you can see here that it returns test/html as the content-type
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 222
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 16 Aug 2010 20:49:55 GMT
So i went ahead and added the following on the webget attribute on my method but it still returns text/html ... I presume that i should return the content type of text/xml because i am in fact returning XML?
Heres my method, i added the ResponseFormat to the attribute... I wasn't sure if i needed bodystyle (i have no idea what it does but saw it in an example :-) )
[WebGet(UriTemplate = "", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml)]
public List<SampleItem> GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
}
anyway after the change and rebuilding of the project it still returns the wrong content type ... am i missign somthing?
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 222
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 16 Aug 2010 20:54:15 GMT
EDIT
Ok i got a working solution but the attribute method has NO EFFECT, very strange...but if i put this
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
Now i check fiddler and the content-type is actually text/xml.
But i need to put this in every method and the attribute method seems to have no effect.
Anybody know why?
According to this the Firefox request headers has a higher priority for text/html than text/xml, resulting in WCF service methods decorated with xml or json returning with the "wrong" response, although I can imagine it is the correct behavior.
You can force a response content type by explicitly setting
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
or equivalent. I guess this is the only alternative if you truly want to force a specific content type response for all browsers/clients.
See e.g.
WCF ResponseFormat For WebGet
I think you want e.g.
OutgoingWebResponseContext context =
WebOperationContext.Current.OutgoingResponse;
context.ContentType = "image/jpeg";
ResponseFormat controls something else.
Old post, but here is what I found on MSDN's Blog Getting Started with WCF WebHttp Services in .NET 4:
Your project has to use the Full .NET 4 Framework, not the Client Profile.
Once I did that, and restarted the project, I was able to add System.ServiceModel.Web from the list of References.
I hope this helps someone.

Passing primitive type to WCF RESTful service

I've been banging my head against the wall for the past couple of hours, here's what we're trying to do: a method expects a primitive/simple type as the request body. Originally we tried with a boolean, but that didn't work so we tried with string and object. Same thing.
Here's the server-side code
[OperationContract]
[WebInvoke(UriTemplate = "/foo/{foo_id}/bar", Method = "POST", ResponseFormat=WebMessageFormat.JSON)]
string G(string foo_id, string content);
And here's the request in Fiddler:
Header:
User-Agent: Fiddler
Host: localhost
Content-Type: 'application/json',
Content-Length: 19
Body:
"hello_world"
We tried to wrap "hello_world" in a json object, like {"content":"hello_world"} but no luck.
Any thoughts?
Works fine for me, here's my code:
[OperationContract]
[WebInvoke(UriTemplate = "/foo/{foo_id}/bar", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public string G(string foo_id, string content)
{
return content + foo_id;
}
You didn't set the request format (a pain I know :))
Here's my Fiddler request:
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:54287
Content-Length: 7
"Hello"