I have created the following restfull web service:
Interface
[ServiceContract]
public interface ISIGService
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "GetTicket/")]
Ticket GetTicket(string user, string pwd);
}
Implementation
public class SIGService : ISIGService
{
public Ticket GetTicket(string user, string pwd)
{
return new Ticket()
{
Usuario = "xx",
UsuarioNombre = "xxx",
UsuarioId = "xxx"
};
}
Contract
[DataContract]
public class Ticket
{
[DataMember]
public int UsuarioId { get; set; }
[DataMember]
public string UsuarioNombre { get; set; }
[DataMember]
public string Usuario { get; set; }
}
I need to consume this service, from a web application, and get the typed object Ticket, I have included a service reference for this.
Server side code:
string urlService =
String.Format("http://localhost:22343/SIGService.svc/GetTicket/?user='{0}'&pwd='{1}'",
usuario, password);
var request = (HttpWebRequest)WebRequest.Create(urlService);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
I put a text variable just to get something, sort of lost here.
I don't seem to get this object, could you give some pointers on this?
Most likely, you just need to change your URL from
http://localhost:22343/SIGService.svc/GetTicket/?user='{0}'&pwd='{1}'
to using the proper REST syntax (since you're using a REST service):
http://localhost:22343/SIGService.svc/GetTicket/{user}/{pwd}
Sample:
http://localhost:22343/SIGService.svc/GetTicket/daniel/topsecret
No ? or user= or single quotes necessary ....
With this, the value from {0} will be passed into the user parameter, and the value from {1} to the pwd parameter.
For consuming the service, I would recommend you check out the excellent RestSharp library which makes using your REST service a breeze.
Your code would look something like this:
// set up the REST Client
string baseServiceUrl = "http://localhost:22343/SIGService.svc";
RestClient client = new RestClient(baseServiceUrl);
// define the request
RestRequest request = new RestRequest();
request.Method = Method.GET;
request.RequestFormat = DataFormat.Xml;
request.Resource = "GetTicket/{user}/{pwd}";
request.AddParameter("user", "daniel", ParameterType.UrlSegment);
request.AddParameter("pwd", "top$ecret", ParameterType.UrlSegment);
// make the call and have it deserialize the XML result into a Ticket object
var result = client.Execute<Ticket>(request);
if (result.StatusCode == HttpStatusCode.OK)
{
Ticket ticket = result.Data;
}
Related
I am writing a mobile application in Xamarin.Forms, and have a very simple PHP file for my back end. The mobile application sends a post request to the PHP file, and the PHP file is meant to var_dump the post contents.
<?php
echo "Your post response is...";
var_dump($_POST);
?>
My Xamarin application uses the HttpClient class to create a simple post request using the PostAsync() method.
public class RestService
{
HttpClient client;
private const string URL = "https://braz.io/mobile.php";
public RestService()
{
client = new HttpClient();
client.MaxResponseContentBufferSize = 256000;
}
public async Task<string> getUserInformation()
{
User u = new User("Barns", "password1234", "email#email.com");
string json = JsonConvert.SerializeObject(u);
var uri = new Uri(string.Format(URL, string.Empty));
try
{
client.DefaultRequestHeaders.Add("Accept", "application/json");
StringContent s = new StringContent(json);
var response = await client.PostAsync(uri, s);
string body = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{Console.WriteLine(ex);}
return null;
}
}
For some reason, my post request is only getting the response Your post resonse is... followed by an empty array. It is strange, because when I use PostMan on google chrome, it returns the correct information.
I have checked that my json variable has valid JSON in it as well, so I am unsure why the PostAsync function is returning/sending an empty array from/to my PHP file.
UPDATE as per comment request
The JSON I am sending is as follows:
"{\"username\":\"Barney\",\"password\":\"1234\",\"email\":\"email#email.com\"}"
My user class is:
public class User
{
public User(){ }
public string username { get; set; }
public string password { get; set; }
public string email { get; set; }
public User(string username, string password, string email)
{
this.username = username;
this.password = password;
this.email = email;
}
}
The issue has nothing to do with the Xamarin side of things. Your issue lies in the PHP code you provided and the fact that when you tried sending something with POSTman, you didn't send it as the body of the request.
In order to read the request body, you need to read the input stream:
$json = file_get_contents('php://input');
Then you can output that with
var_dump($json);
As for your RestService code, I would advise you to provide the content type for your string content:
var s = new StringContent(json, Encoding.UTF8, "application/json");
I'm quite new to MVC and Web API.
I'm trying to post a MailMessage(System.Net.Mail) object to the web api that I've created but the object is received as empty at API. I'm using ReshSharp to call the api below is my code:
MailMessage myMail = new System.Net.Mail.MailMessage("from#example.com", "to#example.com");
myMail.Subject = "Test message from client";
myMail.SubjectEncoding = System.Text.Encoding.UTF8;
myMail.Body = "<b>Test Mail</b><br>using <b>HTML from client</b>.";
myMail.BodyEncoding = System.Text.Encoding.UTF8;
myMail.IsBodyHtml = true;
RestClient client = new RestClient("http://localhost:53014/api/email");
var request = new RestRequest("SendMailMessage", Method.POST);
var json = request.JsonSerializer.Serialize(myMail);
request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
var res = client.Execute(request);
This is my API method:
[HttpPost]
public void SendMailMessage([FromBody]MailMessage myEmail)
{
//Code to send email
}
This is what I receive at the API end:
I have also tried this way but same output:
request = new RestRequest("SendMailMessage", Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddBody(myMail);
res = client.Execute(request);
I have also tried the Newtonsoft.Json serializer to serialize object but no success
var json = JsonConvert.SerializeObject(myMail);
Can anyone suggest what am I missing here?
Trying to send a MailMessage is problematic.
You should create a custom object to hold the information you want sent to the web API...
public class Email {
public string Body { get; set; }
public bool IsBodyHtml { get; set; }
public string Subject { get; set; }
public string[] To { get; set; }
//...Any other properties you deem relevant
//eg: public string From { get; set; }
}
Keep it simple.
So now you would send the custom object to the web api
var myMail = new Email() {
To = new [] { "to#example.com" },
Subject = "Test message from client",
Body = "<b>Test Mail</b><br>using <b>HTML from client</b>.",
IsBodyHtml = true
};
var client = new RestClient("http://localhost:53014/api/email");
var request = new RestRequest("SendMailMessage", Method.POST);
var json = request.JsonSerializer.Serialize(myMail);
request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
var res = client.Execute(request);
Then construct the mail message in the action using the properties provided to the action.
public class EmailController : ApiController {
[HttpPost]
public async Task<IHttpActionResult> SendMailMessage([FromBody]Email message) {
if (ModelState.IsValid) {
var myMail = new System.Net.Mail.MailMessage();
myMail.Subject = message.Subject;
myMail.SubjectEncoding = System.Text.Encoding.UTF8;
myMail.Body = message.Body;
myMail.BodyEncoding = System.Text.Encoding.UTF8;
myMail.IsBodyHtml = message.IsBodyHtml;
myMail.From = new MailAddress("from#example.com");
foreach (var to in message.To) {
myMail.To.Add(to);
}
//...Code to send email
}
return BadRequest(ModelState);
}
}
I have a web service which receives a json string and also returns the json string. But on receiving the response in the form of httpwebresponse I get
{"age":"29","name":"Alex"}.
How can I get just {"age":"29","name":"Alex"} because the above response is not getting deserialized.
Details class:
public class Details
{
public String name { get; set; }
public String age { get; set; }
}
Web service code:
[WebMethod]
[ScriptMethod(UseHttpGet=true, ResponseFormat = ResponseFormat.Json)]
public String getDetails(String details)
{
Details d;
Details retval=(Details)new JavaScriptSerializer().Deserialize(details, typeof(Details));
retval.age = 29.ToString();
String result = new JavaScriptSerializer().Serialize(retval);
return result;
}
Client code:
class Program
{
static void Main(string[] args)
{
Details details = new Details();
details.name = "John";
details.age = "24";
String jsonString = new JavaScriptSerializer().Serialize(details);
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost/JsonService/service1.asmx/getDetails");
httpWebRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
jsonString="details="+jsonString;
streamWriter.Write(jsonString);
}
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
}
The value of **result** comes as <?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">{"age":"29","name":"Alex"}</string>
but I need only {"age":"29","name":"Alex"}
As you are sending data and expect data back in the response formatted in JSON, try to change the content header to application/json instead:
httpWebRequest.ContentType = "application/json; charset=utf-8";
You may also set the accept header:
httpWebRequest.Accept = "application/json;";
I am trying to post the following JSON with RestSharp:
{"UserName":"UAT1206252627",
"SecurityQuestion":{
"Id":"Q03",
"Answer":"Business",
"Hint":"The answer is Business"
},
}
I think that I am close, but I seem to be struggling with the SecurityQuestion (the API is throwing an error saying a parameter is missing, but it doesn't say which one)
This is the code I have so far:
var request = new RestRequest("api/register", Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddParameter("UserName", "UAT1206252627");
SecurityQuestion securityQuestion = new SecurityQuestion("Q03");
request.AddParameter("SecurityQuestion", request.JsonSerializer.Serialize(securityQuestion));
IRestResponse response = client.Execute(request);
And my Security Question class looks like this:
public class SecurityQuestion
{
public string id {get; set;}
public string answer {get; set;}
public string hint {get; set;}
public SecurityQuestion(string id)
{
this.id = id;
answer = "Business";
hint = "The answer is Business";
}
}
Can anyone tell me what I am doing wrong? Is there any other way to post the Security Question object ?
Many thanks.
You need to specify the content-type in the header:
request.AddHeader("Content-type", "application/json");
Also AddParameter adds to POST or URL querystring based on Method
I think you need to add it to the body like this:
request.AddJsonBody(
new
{
UserName = "UAT1206252627",
SecurityQuestion = securityQuestion
}); // AddJsonBody serializes the object automatically
Thanks again for your help. To get this working I had to submit everything as a single parameter. This is the code I used in the end.
First I made a couple of classes called Request Object and Security Question:
public class SecurityQuestion
{
public string Id { get; set; }
public string Answer { get; set; }
public string Hint { get; set; }
}
public class RequestObject
{
public string UserName { get; set; }
public SecurityQuestion SecurityQuestion { get; set; }
}
Then I just added it as a single parameter, and serialized it to JSON before posting it, like so:
var yourobject = new RequestObject
{
UserName = "UAT1206252627",
SecurityQuestion = new SecurityQuestion
{
Id = "Q03",
Answer = "Business",
Hint = "The answer is Business"
},
};
var json = request.JsonSerializer.Serialize(yourobject);
request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
and it worked !
To post raw json body string, AddBody(), or AddJsonBody() methods will not work. Use the following instead
request.AddParameter(
"application/json",
"{ \"username\": \"johndoe\", \"password\": \"secretpassword\" }", // <- your JSON string
ParameterType.RequestBody);
It looks like the easiest way to do this is to let RestSharp handle all of the serialization. You just need to specify the RequestFormat like so. Here's what I came up with for what I'm working on. .
public List<YourReturnType> Get(RestRequest request)
{
var request = new RestRequest
{
Resource = "YourResource",
RequestFormat = DataFormat.Json,
Method = Method.POST
};
request.AddBody(new YourRequestType());
var response = Execute<List<YourReturnType>>(request);
return response.Data;
}
public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient(_baseUrl);
var response = client.Execute<T>(request);
return response.Data;
}
RestSharp supported from object by AddObject method
request.AddObject(securityQuestion);
I am having a real difficult time figuring out why I am getting a 400 bad request from my POST method on my client side. My other POST methods work fine for this service and client. Yet this one isnt working? I was hoping a fresh pair of eyes might find the problem?
My Service looks like this:
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/Message")]
void AddMessage(Message message);
//Post Method for Message
[DataContract(Name = "Message")]
public class Message
{
[DataMember(Name = "MessageID")]
public string MessageID { get; set; }
[DataMember(Name = "GroupMessage")]
public string GroupMessage { get; set; }
//DataContracts for Message
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class RawDataService : IReceiveData
{
List<Message> messages = new List<Message>();
int eCount = 0;
public void AddMessage(Message message)
{
message.MessageID = (++eCount).ToString();
messages.Add(message);
}
// add message method, increment MessageID
Client Code to Post which gives the 400 bad request on marked line:
private void button15_Click(object sender, EventArgs e)
{
string uriMessage = "http://localhost:8000/Service/Message";
StringBuilder sb1 = new StringBuilder();
sb1.AppendLine("</Message>");
sb1.AppendLine("<GroupMessage>" + this.textBox22.Text + "</GroupMessage>");
sb1.AppendLine("</Message>");
string GroupMessage = sb1.ToString();
byte[] arr1 = Encoding.UTF8.GetBytes(GroupMessage);
HttpWebRequest req1 = (HttpWebRequest)WebRequest.Create(uriMessage);
req1.Method = "POST";
req1.ContentType = "application/xml";
req1.ContentLength = arr1.Length;
Stream reqStrm1 = req1.GetRequestStream();
reqStrm1.Write(arr1, 0, arr1.Length);
reqStrm1.Close();
HttpWebResponse resp1 = (HttpWebResponse)req1.GetResponse(); //400 bad request?
MessageBox.Show(resp1.StatusDescription);
reqStrm1.Close();
resp1.Close();
}
This might be it.
sb1.AppendLine("</Message>");
sb1.AppendLine("<GroupMessage>" + this.textBox22.Text + "</GroupMessage>");
sb1.AppendLine("</Message>");
The opening Message element is actually a closing element.