Send dynamic object throught HTTP POST request in c# - c#

I'm trying to send a dynamic object throught and HTTP POst request, but when I Receive that object, it is null.
I cannot USE JObject, cause I have a "virtual" api, and it does not accept JObjects.
I tried to send the type object and dynamic. Both of them do not work. Can some body help me ?
Here's my post request:
public static void Post(string uri, object parameter, string serviceName)
{
StringBuilder url = new StringBuilder();
url.Append(uri);
var client = GetClient(url.ToString(), 300, "application/json");
var urlParameters = GetUrlParameters(new List<KeyValuePair<string, object>>() { });
var response = client.PostAsync(
urlParameters,
new StringContent(
JsonConvert.SerializeObject(parameter).ToString(),
Encoding.UTF8,
"application/json")
).Result;
if (response.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"{serviceName}: {response.StatusCode}");
}
Here is where i Receive that post:
Interce for method:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "Teste")]
void Teste(object requestData);
Method implemented in class( this is acctually where i get the data):
public void Teste(object requestData)
{
var teste = requestData;
var t1 = JsonConvert.SerializeObject(requestData); // this returns {}; (empty)
}

Can you tweak your POST a bit to troubleshoot the issue a bit more? Something like the following? (not compiled)
var rawJson = await client.PostAsync(
urlParameters,
new StringContent(
JsonConvert.SerializeObject(parameter).ToString(),
Encoding.UTF8,
"application/json")
).Content.ReadAsStringAsync();
var mappedObj = JsonConvert.DeserializeObject<T>(rawJson,
new JsonSerializerSettings
{
Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
// convert this to your logger
LogHelper.Instance.Warning(2000, string.Format("Failed object mapping: {0}\n{1}",
args.ErrorContext.Error, rawJson));
args.ErrorContext.Handled = true;
},
// set culture to mitigate mapping issues related to dates/numbers
// https://stackoverflow.com/a/34529198
Culture = CultureInfo.InvariantCulture
});

Related

Passing parameters to WCF using RestSharp

I have the following WCF service:
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string UpdateReturnedPatients(string lst);
And I am calling it using RestSharp like this:
Ids id = new Ids();
id.id = "EMR0037933";
var client = new RestClient("https://myweb.com/services/Service1.svc");
var request = new RestRequest("UpdateReturnedPatients", Method.POST);
request.RequestFormat = DataFormat.Json;
string json = JsonConvert.SerializeObject(id);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("lst", json);
// execute the request
IRestResponse response = client.Execute(request);
var content = response.Content;
But when I run the code, I have this returned:
Request Error:
The server encountered an error processing the request. The
exception message is 'The incoming message has an unexpected message
format 'Raw'. The expected message formats for the operation are
'Xml', 'Json'. This can be because a WebContentTypeMapper has not been
configured on the binding.
What is the problem, and how I can pass the parameter (in my case named lst) to the web-service?
I can use methods other than RestSharp.
UPDATE
Changed web service to:
[WebInvoke(Method = "POST", UriTemplate = "UpdateReturnedPatients", RequestFormat =
WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle =WebMessageBodyStyle.Bare)]
string UpdateReturnedPatients(Ids lst);
and The implementation of it is
public string UpdateReturnedPatients(Ids lst)
{
try
{
string json = JsonConvert.SerializeObject(lst);
return json;
}
catch (Exception ex)
{
throw;
}
}
And I used
request.AddBody(new { lst = id});
instead of AddParameter()
but the response is :
"{\"id\":null}"
It is not returning the value of the id field, even though I did supply it.

RestClient returns universal response

I have some code:
public Task<IRestResponse> SendRequest(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest();
request.RequestFormat = DataFormat.Json;
request.Method = Method.POST;
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
client.ExecuteAsync(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
response contains all but not the answer from url (response doesnt' contain Data object). When I specify object for ExecuteAsync:
public Task<IRestResponse<MyClass>> SendRequest(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest();
request.RequestFormat = DataFormat.Json;
request.Method = Method.POST;
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse<MyClass>>();
client.ExecuteAsync<MyClass>(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
public class MyClass
{
public bool ResultCheck { get; set; }
public string Message { get; set; }
}
in response I can find object Data (response.Data) which contains fields with values from url.
For example I receive response with Data: { ResultCheck=true, Message="Result!" }
How can I receive filled Data from url with any object without specifiing type - MyClass. I wan't to receive response with any number of fields for different urls. I want to receive some anonymous object.
One way would be to use Generics and dynamic objects. This should allow you to specify any object type to be converted to a response.
You can therefore change the method to
public Task<IRestResponse<T>> SendRequest<T>(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest
{
RequestFormat = DataFormat.Json;
Method = Method.POST;
};
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse<T>>();
client.ExecuteAsync<T>(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
Then we can create temp object using dynamic. We can then fill this will all the information we need
// Create temp obj
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
finally at the call site we state the type is dynamic. Hopefully the rest api can forward this onto the client and they can retrieve the object as type dynamic.
SendRequest<dynamic>(url, JsonConvert.SerialiseObject(employee));
The client can then do something like
dynamic response = GetResponse(...);
var name = response.Name;

REST Service receive empty params

I'm trying to comunicate with my rest service but this one return always that my sended parameter is empty but in my client console he is filled.
Here is the Interface Class :
[ServiceContract]
public interface IMyTest
{
[OperationContract]
[WebInvoke(UriTemplate = "TestMe", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
string TestMe(string parameter);
}
My svc method :
public string TestMe(string parameter)
{
if (string.IsNullOrEmpty(parameter)
return "Empty";
return "OK";
}
My client :
string content = "{\"Param\" : \"TEST\"}";
var request = WebRequest.Create("http://localhost/MyTestURL/MyTest.svc/TestMe");
request.Method = "POST";
request.ContentType = "application/json";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(content);
}
var res = (WebResponse)request.GetResponse();
StreamReader reader =
new StreamReader(res.GetResponseStream(), Encoding.UTF8);
System.Console.WriteLine("Response");
System.Console.WriteLine(reader.ReadToEnd().ToString());
Is my client code not ok ? My conifiguration not ok ? ...
Thanks.
If you want to get request as string, use Stream instead of String parameter
public void TestMe(Stream dataStream)
but if not, use serializable to Json objects as parameters.
i founded a good tutorial that helped me to implement the method with the stream parameter. thanks.

How to pass parameter value using HttpPost and NameValuePair in android when accessing rest web service?

I made a rest web service with the service contract as shown below
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "postdataa?id={id}"
)]
string PostData(string id);
Implementation of the method PostData
public string PostData(string id)
{
return "You posted " + id;
}
Code in Android to post data in web service
HttpClient httpclient = new DefaultHttpClient();
HttpHost target = new HttpHost("192.168.1.4",4567);
HttpPost httppost = new HttpPost("/RestService.svc/postdataa?");
String result=null;
HttpEntity entity = null;
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("id", "1"));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePairs);
httppost.setEntity(ent);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(target, httppost);
entity = response.getEntity();
//get xml result in string
result = EntityUtils.toString(entity);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
The problem is that the xml result shows and the value of the parameter is missing:
<PostDataResponse xmlns="http://tempuri.org/"><PostDataResult>You posted </PostDataResult></PostDataResponse>
I do not know what went wrong.
Since you are using REST service, give this a try:
private static char[] GetData(String servicePath) throws Exception
{
InputStream stream = null;
String serviceURI = SERVICE_URI;//this is your URI to the service
char[] buffer = null;
try
{
if (servicePath != "")
serviceURI = serviceURI + servicePath;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(serviceURI);
request.setHeader("Accept", "application/xml");
request.setHeader("Content-type", "application/xml");
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null)
{
// Read response data into buffer
buffer = new char[(int)responseEntity.getContentLength()];
stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
reader.read(buffer);
stream.close();
}
}
catch (Exception e)
{
Log.i("Survey Application", e.getMessage());
throw e;
}
return buffer;
}
Invoke this method using
try
{
char[] buffer = GetData("postdataa/" + id);
if (buffer != null)
//Build your XML object
}
catch (Exception e)
{
}

When I pass xml string as a request i get an Bad Request exception in WCF REST?

Client:
string value = "<?xml version=1.0?><person><firstname>john</firstname><lastname>smith</lastname> <person/>";
using (HttpResponseMessage response = m_RestHttpClient.Post("new/customerxml/"+value2, frm.CreateHttpContent()))
{
}
Server:
[OperationContract]
[WebInvoke(UriTemplate = "new/customerxml/string={value}", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
public string NewCustomer(string value)
{
return value;
}
That's because WCF sniffs the content and decides you are uploading XML, not a string. Assuming you are using the HttpClient from the WCF REST Starter kit, try this:
string value = "<?xml version=1.0?><person><firstname>john</firstname><lastname>smith</lastname> <person/>";
var content = HttpContentExtentions.CreateDataContract(value, typeof(string));
using (HttpResponseMessage response = m_RestHttpClient.Post("new/customerxml/"+value2, content)
{
...
}

Categories