Using Fiddler I post a JSON message to my WCF service. The service uses System.ServiceModel.Activation.WebServiceHostFactory
[OperationContract]
[WebInvoke
(UriTemplate = "/authenticate",
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
String Authorise(String usernamePasswordJson);
When the POST is made, I am able to break into the code, but the parameter usernamePasswordJson is null. Why is this?
Note: Strangly when I set the BodyStyle to Bare, the post doesn't even get to the code for me to debug.
Here's the Fiddler Screen:
You declared your parameter as type String, so it is expecting a JSON string - and you're passing a JSON object to it.
To receive that request, you need to have a contract similar to the one below:
[ServiceContract]
public interface IMyInterface
{
[OperationContract]
[WebInvoke(UriTemplate = "/authenticate",
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
String Authorise(UserNamePassword usernamePassword);
}
[DataContract]
public class UserNamePassword
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
}
Related
I am writing some REST service in WCF. This is my code.
[DataContract]
public class Result
{
[DataMember]
public String ErrorCode { get; set; }
[DataMember]
public Object Data { get; set; }
public Result(String msg, Object data)
{
this.ErrorCode = msg;
this.Data = data;
}
}
And I am calling this like this
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "login",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
Result Login(string emailAddress, string password);
In my Interface implementation class, I write this.
public Result Login(string emailAddress, string password)
{
return new Result("[0000]",null);
}
It gives me a JSON result like this
{"LoginResult":{"Data":null,"ErrorCode":"[0000]"}}
The weird thing is it has a LoginResult at the root,What I want is simply {"Data":null,"ErrorCode":"[0000]"} without this LoginResult header in JSON response. How can I fix this?
Thank you.
UPDATE
I just noticed that you have two parameters in your method
1. string emailAddress
2. string password
Please add these two parameters as properties in an object and use that object as the parameter.
Then apply the changes as given below. This will work for you.
Please change your the following line:-
BodyStyle = WebMessageBodyStyle.Wrapped
To
BodyStyle = WebMessageBodyStyle.Bare
I am trying to create a method with class as a parameter. But it's throwing error. After some search I found the implementation of QueryStringConverter.
I am trying to do it but I didn't have much knowledge in it.
In my service class, the method is :
[WebInvoke(UriTemplate="LogInForMobileWithDeviceNo", Method="POST", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.Wrapped)]
string LogInForMobileWithDeviceNo(clsUserDeviceInfo userDeviceInfo);
In the clsUserDeviceInfo class, i declared the properties as:
[DataContract]
public class clsUserDeviceInfo
{
[DataMember]
public string UserID{get;set;}
[DataMember]
public string DeviceName{get;set;}
[DataMember]
public string CordovaVersion{get;set;}
[DataMember]
public string DevicePlatformJs{get;set;}
[DataMember]
public string DeviceUID{get;set;}
[DataMember]
public string DeviceModel { get; set; }
[DataMember]
public string DeviceVersion { get; set; }
}
but it's not working.
using Jquery i did Ajax posting:
var DeviceName = "samsung";
var CordovaVersion = "2.1.1.1";
var DevicePlatformJs = "windows 8";
var DeviceUID = "23dswd-234dff-23-2334nhj";
var DeviceModel = "grand duos";
var DeviceVersion = "3.2";
var DataArr = {DeviceName:DeviceName,CordovaVersion:CordovaVersion, DevicePlatformJs:DevicePlatformJs,DeviceUID:DeviceUID,DeviceModel:DeviceModel,DeviceVersion:DeviceVersion};
$.ajax({
type: "GET",
url: serverurl,
data: JSON.stringify(DataArr),
success: function (result) {
alert(result);
},
accept: 'application/json'
});
Am I doing anything wrong?
Do you have a OperationContract, this should work!
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/LogInForMobileWithDeviceNo?userDeviceInfo={userDeviceInfo}")]
string LogInForMobileWithDeviceNo(clsUserDeviceInfo userDeviceInfo);
I am running a WCF service with these methods,
public string UploadInspections(Inspection[] inspections)
public string UploadInspection(Inspection inspection)
[DataContract]
public partial class Inspection
{
[DataMember]
public DateTime DateTime { get; set; }
[DataMember]
public int Id { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public int Rating { get; set; }
}
From javascript I tried to call a POST on these methods using JSON. The JSON I had for the UploadInspection method was this,
{"Id":10,"Comment":"New One","Rating":3}
The UploadInspection method was called, but the inspection object was set to null.
I wasn't sure how to specify the Date field using JSON, and I thought that perhaps the parser didn't like JSON with no Date field. I removed the Date field from the Inspection object, but the same thing happened.
Also what should the JSON look like for the UploadInspections method which is an array? I had some JSON that I tried,
"inspections": [{"Id":10,"Comment":"New One","Rating":3}]
And also this,
[{"Id":10,"Comment":"New One","Rating":3}, {"Id":11,"Comment":"New Two","Rating":2}]
But I was getting this error,
OperationFormatter encountered an invalid Message body. Expected to find an attribute with name 'type' and value 'object'. Found value 'string'.
The problem is not what I thought it was, in my service definition it initially looked like this,
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
string UploadInspections(Inspection[] inspections);
Once I removed this,
BodyStyle = WebMessageBodyStyle.WrappedRequest
It worked!
Let's say we have REST client with next declaration:
[ServiceContract]
interface ITestClient
{
[OperationContract]
[WebGet(UriTemplate = "SetData/?d1={d1}&d2={d2}")]
void SetData(string d1, string d2);
}
I would like tu use it with next signature (HTTP GET):
[ServiceContract]
interface ITestClient
{
[OperationContract]
[WebGet(UriTemplate = "SetData/?")]
void SetData(SetDataRequest setData);
}
[DataContract]
public class SetDataRequest
{
[DataMember(Name = "d1")]
private string Data1 { get; set; }
[DataMember(Name = "d2")]
private string Data2 { get; set; }
}
I wish that WCF serializes instance of the SetDataRequest to HTTP QueryString.
Is this possible (HTTP POST is not acceptable)?
You should not use WebGet for this you should instead do:-
[OperationContract]
[WebInvoke( UriTemplate="SetDate/" Method="POST")]
void SetData(SetDataRequest setData);
You should use a post when submitting data as you will run into security/caching issues if you don't.
I have a datacontract as defined below:
[DataContract(Namespace="",Name="community")]
public class Community {
[DataMember(Name="id")]
public int Id{get; set;}
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name="description")]
public string Description { get; set; }
}
and the service contract goes like this:
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "{id}"
)]
Community GetCommunity(string id);
When I make a rest call to the host, I get data but only Id and Name properties are populated. The Description property is null! I am creating the channel by inheriting from ClientBase.
Does anybody know why WCF serializes Id and Name but not Description? The Transfer Encoding is set to 'Chunked' on the response from the host and I would like to know if that has anything to do with it ?
I found out that some of the properties were not getting serialized because the response xml had the elements in a different order. The solution was to explicitly set serialization order on the datacontract. Here is the datacontract after I added order attribute:
[DataContract(Namespace="",Name="community")]
public class Community
{
[DataMember(Name = "name",Order=2)]
public string Name { get; set; }
[DataMember(Name="id",Order = 1)]
public int Id{get; set;}
[DataMember(Name="description",Order=3)]
public string Description { get; set; }
}