Post object to a WCF method - wcf

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

Related

is there a reason to serialize and then deserialize an object?

I have a SOAP web service that someone developed at my work place and i try to learn it and i came across a move in the code that i can't get my head around. can someone explain to me the logic behind it? why would someone want to serialize an object and a line after to deserialize it?
**this is the whole code: if someone has a way to improve the code it will be appreciated: **
using IRail.BLL.SAP;
using IRail.Entities.SAP.Report;
using IRail.WebAPI.Heplers;
using Logger;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web.Script.Serialization;
using System.Web.Services;
namespace IRail.WebAPI
{
public class EventInfo
{
public string QMNUM { get; set; }
public string QMART { get; set; }
public string STATUS { get; set; }
public string MAHUT_CODE { get; set; }
public string MAHUT_TXT { get; set; }
public string START_DATE { get; set; }
public string START_TIME { get; set; }
public string END_DATE { get; set; }
public string END_TIME { get; set; }
public string ZQMNUM { get; set; }
public string QMTXT { get; set; }
public string IKUN { get; set; }
public string ZLONG { get; set; }
public string LAT { get; set; }
public string TPLNR { get; set; }
public string ZZKM_NUM { get; set; }
public string ZZTOKM_NUM { get; set; }
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Events : System.Web.Services.WebService
{
public static readonly ILogger _logger = LogManager.GetLogger();
[WebMethod]
public string UpdateEvent(EventInfo eventInfo)
{
// create an instance of SapClient object an fill it with the input parameters,
// that passes by the url to the function using the eventInfo class.
SapClient SapArgs = new SapClient()
{
params_input = "",
QNUM = eventInfo.QMNUM,
QMART = eventInfo.QMART,
STATUS = eventInfo.STATUS,
MAHUT_CODE = eventInfo.MAHUT_CODE,
MAHUT_TXT = eventInfo.MAHUT_TXT,
START_DATE = eventInfo.START_DATE,
START_TIME = eventInfo.START_TIME,
END_DATE = eventInfo.END_DATE,
END_TIME = eventInfo.END_TIME,
ZQMNUM = eventInfo.ZQMNUM,
QMTXT = eventInfo.QMTXT,
IKUN = eventInfo.IKUN,
ZLONG = eventInfo.ZLONG,
LAT = eventInfo.LAT,
TPLNR = eventInfo.TPLNR,
ZZKM_NUM = eventInfo.ZZKM_NUM,
ZZTOKM_NUM = eventInfo.ZZTOKM_NUM,
ikunx = "",
ikuny = "",
operation_type = "",
returnZ = "",
returnM = "",
returnTrueCurves = "",
f = ""
};
string errorMsg = String.Empty;
string outputJson = String.Empty;
ApiHelper apiHelper = new ApiHelper();
try
{
// create an instance of JS Serializer.
var jss = new JavaScriptSerializer();
// serialize the object to convert it to json format.
JObject sapArgs = JObject.Parse(jss.Serialize(SapArgs));
// decerialize the object back from json format to pass the JSON string representation
// of the sapArgs object as the input to the callGPAsync method.
var dict = jss.Deserialize<Dictionary<string, string>>(sapArgs.ToString());
// create an instance of EventsEngine.
EventsEngine eventsEngine = new EventsEngine();
// assign the type of the event to the events object:
// check the event type.
SapArgs.operation_type = eventsEngine.CheckEventType(dict, ref errorMsg);
// assign the event type that has returned to the sapArgs object's operation_type parameter.
sapArgs["operation_type"] = SapArgs.operation_type; // "1";// set operation_type for test;
// if encountered an error return the content of it.
if (errorMsg != "") return "UpdateEvent ERROR: " + errorMsg;
_logger.Info($"Username: {Utils.GetUserName()}, UpdateEvent : {sapArgs.ToString()}, eventType :{SapArgs.operation_type}");
if (!string.IsNullOrWhiteSpace(apiHelper.getValueFromDict(dict, "IKUN")) && dict["IKUN"].ToString() == "Y")
{
var res = apiHelper.convertCoordiateWGSToITM(sapArgs).GetAwaiter().GetResult();
}
outputJson = apiHelper.callGPAsync(sapArgs).GetAwaiter().GetResult();
try
{
// if there is result from submitted job add operation_type
outputJson = outputJson.Replace("}", ", \"operation_type\" = \"" + SapArgs.operation_type + "\" }");
}
catch (Exception outputEx)
{
return "outputJson ERROR: " + outputEx;
}
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(outputJson, System.Text.Encoding.UTF8, "application/json");
return outputJson;
}
catch (Exception ex)
{
_logger.Error(" UpdateEvent ERROR : " + SapArgs.ToString() + ", eventType :" + SapArgs.operation_type + ", errorMsg :" + errorMsg);
_logger.Error(ex);
return "UpdateEvent ERROR: update failed on exception. please check logs.";
}
//0. check with documentation - what are the parameters - in sap document
//0. log -> input call
//1. properties input validation -
// A. all inputs are correct //2.4 in documents ---> function in BLL that does the validation
//2. if all ok - -- delete prev event
//3. call GP service to update new event
//4. return success + log reult
}
}
}
I did not try anything i just want to understand the logic.

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

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

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

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.