How to set a method with class as a parameter in WCF service? - wcf

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);

Related

WCF REST Format Output

I have a WCF service using REST protocol.
Code:
[ServiceContract]
public interface IHybridService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/hybridservice/compositedata/{value}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
CompositeType GetDataUsingDataContract(string value);
}
[DataContract]
public class CompositeType
{
List<Data> data = new List<Data>();
public CompositeType()
{
data.Add(new Data() { Id= 1, Value = "test1" });
}
[DataMember]
public List<Data> DataList
{
get { return data; }
set { data = value; }
}
}
public class Data
{
[DataMember(Name = "DataID")]
public int Id { get; set; }
public string Value { get; set; }
}
Currently it returns the following output:
{
"DataList": [
{
"Id": 1,
"Value": "test1"
}
]
}
How can I change the Id within DataList to DataID? I tried [DataMember(Name = "DataID")] but it doesn't work. I do not want to change the c# property to DataID to make it work.
Found the reason, I had to declare Data class as [DataContract].

WCF JSON format

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

WCF RESTful Console-hosted, return 400 Bad Request

Studying WCF RESTful, host in a Console,
my steps:
create sample models
create contract of service
create service
host this service in a console.
run this host, looks ok.
create a winform, use service address via json post to service host.
i hope it would work, but return http 400.
I tried on WCF(not REST) Console-hosted, WebAPI, steps all ok.
finally, stackoverflow.com
please help
Models
[Serializable]
public abstract class Building
{
public Manufacturer Manufacturer { get; set; }
}
[Serializable]
public class Manufacturer
{
public string Name { get; set; }
public string Telephone { get; set; }
}
[Serializable]
public class Furniture : Building
{
public string Name { get; set; }
}
[Serializable]
public class Reception
{
public int Floor { get; set; }
public int Number { get; set; }
}
[Serializable]
public class Room : Building
{
public string Number { get; set; }
public List<Furniture> Furnitures { get; set; }
}
[Serializable]
public class Hotel : Building
{
public Guid Guid { get; set; }
public List<Reception> Receptions { get; set; }
public List<Room> Rooms { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Contract
[ServiceContract]
public interface IHotel
{
// Create objct Hotel
[OperationContract]
[WebInvoke(UriTemplate = "", Method = "POST", RequestFormat= WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)]
bool Create(Hotel hotel);
}
Service
public class HotelService : I Hotel
{
public bool Build(Models.Hotel hotel)
{
if (hotel == null)
return false;
// codes here is object hotel(EF) creation, test OK
return true;
}
}
Host(Console)
WebServiceHost serviceHost = new WebServiceHost(typeof(Demo.Services.HotelService), new Uri("http://192.168.1.101/HotelService"));
ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(Demo.Contracts.IHotel), new WebHttpBinding(), "");
ServiceDebugBehavior sdb = serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = false;
Console.WriteLine("Starting Service...");
// start service
serviceHost.Open();
Console.WriteLine("Started, press RETURN to exit.");
Console.ReadLine();
serviceHost.Close();
Client(Winform)
Caller
public bool BuildHotel(string json)
{
WebRequest request = HttpWebRequest.Create("http://192.168.1.101/HotelService");
request.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(json);
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
WebResponse response = request.GetResponse(); // 400 throwed here
Stream responseStream = response.GetResponseStream();
StreamReader responseStreamReader = new StreamReader(responseStream);
string result = responseStreamReader.ReadToEnd();
return true;
}
Json String for 'bool BuildHotel(string)' upon
{
"Guid":"ea59c011-d656-4870-b29b-30a44e668560",
"Receptions":[
{"Floor":1,"Number":1},
{"Floor":2,"Number":2}
],
"Rooms":[
{
"Number":"c",
"Furnitures":[
{"Name":"1","Manufacturer":{"Name":"1","Telephone":"1"}},
{"Name":"2","Manufacturer":{"Name":"2","Telephone":"2"}}
],
"Manufacturer":{"Name":"c","Telephone":"c"}
}
],
"Name":"x",
"Address":"x",
"Manufacturer":{"Name":"x","Telephone":"x"}
}
it expects such kind of JSON:
{"k_BackingField":{"k_BackingField":"4","k_BackingField":"4"},"k_BackingField":"x","k_BackingField":"ea59c011-d656-4870-b29b-30a44e668560","k_BackingField":"x","k_BackingField":[{"k_BackingField":1,"k_BackingField":1},{"k_BackingField":2,"k_BackingField":2}],"k_BackingField":[{"k_BackingField":{"k_BackingField":"3","k_BackingField":"3"},"k_BackingField":[{"k_BackingField":{"k_BackingField":"1","k_BackingField":"1"},"k_BackingField":"1"},{"k_BackingField":{"k_BackingField":"2","k_BackingField":"2"},"k_BackingField":"2"}],"k__BackingField":null}]}
To change it you can mark all your data contracts with DataContract and DataMember attribute:
[DataContract]
public abstract class Building
{
[DataMember]
public Manufacturer Manufacturer { get; set; }
}
In this case it will understand json as you have given us in the question and will process it successfully.

Error while parsing JSON response in Windows 8

The following code throws error at statement :
Result res = (Result)stdserialize.ReadObject(ms);
And the error is : There was an error deserializing the object of type TrackLocation.MainPage+Result. End element 'types' from namespace '' expected. Found element 'item' from namespace ''.
HttpClient gClientRequest = new HttpClient();
System.Uri gURI = new Uri("http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true");
HttpResponseMessage gResponse = await gClientRequest.GetAsync(gURI);
string strStream = await gResponse.Content.ReadAsStringAsync();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(strStream));
DataContractJsonSerializer stdserialize = new DataContractJsonSerializer(typeof(Result));
Result res = (Result)stdserialize.ReadObject(ms);
//################################################################################################
[DataContract]
public class Address
{
[DataMember(Name = "long_name")]
public string address1;
[DataMember(Name = "short_name")]
public string shortaddress;
[DataMember(Name = "formatted_address")]
public string formattedtaddress;
[DataMember(Name = "lat")]
public string latitude;
[DataMember(Name = "long")]
public string latitude;
}
//###############################################################################################
[DataContract]
public class Result
{
[DataMember(Name = "results")]
public Address[] Results { get; set; }
[DataMember(Name = "status")]
public string Status { get; set; }
}
[DataContract]
public class Address
{
[DataMember(Name = "formatted_address")]
public string FormattedAddress;
[DataMember(Name = "address_components")]
public AddressComponent[] AddressComponents;
}
[DataContract]
public class AddressComponent
{
[DataMember(Name = "long_name")]
public string LongName;
[DataMember(Name = "short_name")]
public string ShortName;
[DataMember(Name = "types")]
public string Types;
}
any idea how to fix this issue.Any help would be greatly appreciated.
I just converted the JSON to XMl and found the types to be repeated(check screen shot below) but in your datacontract its
[DataMember(Name = "types")]
public string Types;
Just put this as
[DataMember(Name = "types")]
public string[] Types;
and it should work
Take a closer look at the JSON, your Type field of the AddressComponent should be string[] not string.
{
"results" : [
{
"address_components" : [
{
"long_name" : "285",
"short_name" : "285",
"types" : [ "street_number" ]
},
Also, you seem to have two Address classes and a result (lowercase) and Result (uppercase) class; I'm assuming those were cut-and-paste issues since they don't seem to match the JSON that's returned.

Post object to a WCF method

I am a newbie to both RestSharp and WCF and I am trying to write a working sample that has a post method which takes a string and an object as parameters. I have looked at another post here where someone asked the same question and I still couldn't get it to work. Can someone please point me in the right direction. I debugged the code and I am getting a null in the object. It seems like its pretty straight forward but I am not sure what I am missing. This is what I have so far.
Server side:
[OperationContract]
[Description("addUser")]
[WebInvoke(Method = "POST", UriTemplate = "/addUser?id={id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
TSCRUResponse addUser(string id, User usr);
public TSCRUResponse addUser(string id, User usr)
{
TSCRUResponse r = new TSCRUResponse();
r.status = id + usr.name + usr.age + usr.gender;
return r;
}
The first parameter for the above method comes through OK but not the object.
These are the objects:
[DataContract]
public class TSCRUResponse
{
[DataMember(Name = "status")]
public string status { get; set; }
}
[DataContract]
public class User
{
[DataMember(Name = "name")]
public string name { get; set; }
[DataMember(Name = "age")]
public string age { get; set; }
[DataMember(Name = "gender")]
public string gender { get; set; }
}
Client side :
public void postmethod(string uri)
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
RestClient client = new RestClient();
client.BaseUrl = "http://localhost:1119/TestService.svc/";
client.Authenticator = new HttpBasicAuthenticator("username", "password");
RestRequest request = new RestRequest("addUser?id={id}", Method.POST);
request.AddHeader("Accept", "application/json");
request.JsonSerializer = new RestSharp.Serializers.JsonSerializer();
request.RequestFormat = DataFormat.Json;
request.AddParameter("id", "12839", ParameterType.UrlSegment);
User itm = new User { age = "40", name = "user1", gender = "M" };
request.AddBody(itm);
var response = client.Execute<TSCRUResponse>(request);
TSCRUResponse addres = response.Data;
Console.WriteLine(addres.status);
}