Webservice in GAE, call from a C# client - c#

I have created a webapplication on Google App Engine that gets and sets data in datastore, using Python API and it's working fine.
Now I want to access to that data from a client application, written in C# so I was thinking of creating a webservice in GAE to provide access to the data to my app.
I have started to play a bit with ProtoRPC, and built a "hello" webservice as in the tutorial and now I want to call that webservice from my C# client application.
I have found Jayrock lib which seems to do the job; unfortunately I can't find how to make it work.
Here is my code, based on JayrockRPCClient sample :
JsonRpcClient client = new JsonRpcClient();
client.Url = "http://localhost:8081/hello";
JsonObject p = new JsonObject { { "my_name", "Joe" } };
Console.WriteLine(client.Invoke("hello.hello", p));
I always get Missing value error.
Can anybody point me to what do I do wrong ?
And as another question, what do you think of that architecture, as there a simplier way to build a webservice in GAE and call it from C#?

Note that while ProtoRPC communicates via JSON, it is not a JSON-RPC service. By using a JSON-RPC client, you are most likely sending messages in the wrong format.
You should be doing a POST to http://localhost:8081/hello.hello with a request body of {"my_name": "Joe"}. Check to make sure your client is sending requests in this format.

Using WebClient:
var uri = new Uri("http://localhost:8081/hello.hello");
var data = "{\"my_name\":\"Joe\"}";
var wc = new WebClient();
wc.Headers["Content-type"] = "application/json";
wc.Encoding = Encoding.UTF8;
var response = wc.UploadString(uri, data);
For serializing objects, you can use DataContractJsonSerializer.

Related

POST request implementation

I need to implement a post request in a c# winform application of my project. Earlier to that I just have implemented get requests. I have checked that the API URI is working well (I checked it using Postman). I never implemented POST requests in the past. The get requests I implement using the following code:
WebClient n = new WebClient();
string uri = "API_URI";
string json = n.DownloadString(uri);
Now my requirement is to download json string using post method with an "apikey" with its value which I need to provide while calling the URI.
When I am using the above code, it is searching the "API_URI" in my local application directory.
Any direction, sample code and or tutorial will be much appreciated. Please help me with that.
Since you have the call tested in Postman, as a starting point use the "Code" link in PostMan to generate your call using RestSharp so that you can test it and further refine it.
https://learning.getpostman.com/docs/postman/sending-api-requests/generate-code-snippets/
you can do something like this:
WebClient client = new WebClient();
string uri = "API_URI";
string json = "{some:\"json data\"}";
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
client.Headers.Add("Authorization", "apikey");
string response = client.UploadString(uri,json);
this is the documentation https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.uploadstring?view=netframework-4.8
You can use POST method in this way
WebClient client = new WebClient();
string uri = "API_URI";
var reqparm=new NameValueCollection(); // Used for passing request perameter
reqparm.Add("some","json data");
response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", reqparm));
I hope this will help you.

How to read data from WebClient.UploadData

First time posting! I've been breaking my head on this particular case. I've got a Web application that needs to upload a file towards a web-api and receive an SVG file (in a string) back.
The web-app uploads the file as follows:
using (var client = new WebClient())
{
var response = client.UploadFile(apiUrl, FileIGotEarlierInMyCode);
ViewBag.MessageTest = response.ToString();
}
Above works, but then we get to the API Part:
How do I access the uploaded file? Pseudocode:
public string Post([FromBody]File f)
{
File uploadedFile = f;
String svgString = ConvertDataToSVG(uploadedFile);
return s;
}
In other words: How do I upload/send an XML-file to my Web-api, use/manipulate it there and send other data back?
Thanks in advance!
Nick
PS: I tried this answer:
Accessing the exact data sent using WebClient.UploadData on the server
But my code did not compile on Request.InputStream.
The reason Request.InputStream didn't work for you is that the Request property can refer to different types of Request objects, depending on what kind of ASP.NET solution you are developing. There is:
HttpRequest, as available in Web Forms,
HttpRequestBase, as available in MVC Controllers
HttpRequestMessage, as available in Web API Controllers.
You are using Web API, so HttpRequestMessage it is. Here is how you read the raw request bytes using this class:
var data = Request.Content.ReadAsByteArrayAsync().Result;

Deserializing a local xml file using Rest Sharp

I have no problem deserializing an xml into my class while using the following code. I was wondering if it was possible to use the same code on a local file, as our source files are saved locally for archival purposes and are occasionally reprocessed.
This works for remote xml but not for local xml:
RestRequest request = new RestRequest();
var client = new RestClient();
//doesnt work
client.BaseUrl = directory;
request.Resource = file;
//works
client.BaseUrl = baseURL;
request.Resource = url2;
IRestResponse<T> response = client.Execute<T>(request);
return response.Data;
Is there a way to use RestSharp from a local file? I was going to try to use the same function regardless of whether the xml is local or remote and just pass it the location of the xml to read.
This is in fact possible using built in JsonDeserializer class as below. I have used this method to stub API response for testing.
// Read the file
string fileContents = string.Empty;
using (System.IO.StreamReader reader = new System.IO.StreamReader(#"C:\Path_to_File.txt"))
{
fileContents = rd.ReadToEnd();
}
// Deserialize
RestResponse<T> restResponse = new RestResponse<T>();
restResponse.Content = fileContents;
RestSharp.Deserializers.JsonDeserializer deserializer = new RestSharp.Deserializers.JsonDeserializer();
T deserializedObject = deserializer.Deserialize<T>(restResponse);
This is not possible with standard functionality. For example "file://" URLs do not work with RestSharp.
I would recommend using RestSharp do get the returned data from a Uri and having another function to deserialize this data into an object.
You can use the same funcion then to deserialize from file data.
RestSharp is a library to do REST calls, not to deserialize from arbitrary sources. Even if there is a possibility to make RestSharp believe it is talking to a website instead of a file, it would be a hack.
If you need it you could still use the XmlDeserializer from RestSharp. It expects a IRestResponse object, but it only uses the Content property from it, so it should be easy to create. It still feels like a hack though and there are more than enough other XmlSerializers out there that will do a great job

calling a Asp.net web API from c# with multiple of parameters

I have a web api that has parameters. I am trying to call the api from another application. This is not a problem on the client side using, but i cannot find a way to do it on the server side in c#. Thanks for any advice.
You can call Web API from any desktop or server side application using WebClient.
var webClient = new WebClient();
webClient.Headers["Content-Type"] = "application/json";
webClient.Headers["X-JavaScript-User-Agent"] = "Google APIs Explorer";
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { longUrl = url });
var data = webClient.UploadString("https://www.googleapis.com/urlshortener/v1/url?pp=1", json);
http://weblogs.asp.net/pglavich/archive/2012/02/18/mvc4-and-web-api-make-an-api-the-way-you-always-wanted-part-1.aspx
The link above worked perfectly for me.

Some help posting to ASP.NET Web API with C#

I have been playing with ASP.NET Web API. I am looking to see can I post to a method I have built which simply returns back the object I have POSTED:
On The Accounts Controller:
// POST /api/accounts
public Account Post(Account account)
{
return account;
}
Code Used To Post:
public void PostAccount()
{
// http://local_ip/api/accounts
var uri = string.Format("{0}", webServiceRoot);
var acc = new Account();
acc.AccountID = "8";
acc.AccountName = "Mitchel Cars";
acc.AccountNumber = "600123801";
acc.SubscriptionKey = "2535-8254-8568-1192";
acc.ValidUntil = DateTime.Now;
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/xml";
request.ContentLength = 800;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Account));
xmlSerializer.Serialize(request.GetRequestStream(), acc);
var response = (HttpWebResponse)request.GetResponse();
XmlSerializer serializer = new XmlSerializer(typeof(Account));
var newAcc = (Account)serializer.Deserialize(response.GetResponseStream());
}
I have removed any error checking or any boiler plate code to make it easier to read. This is strictly a spike just to under stand to to actually POST. My understanding is that you should write to the GetRequestStream(). All the reading and such seems to work ok but I never here back from the request.GetResponse();
If I do a simple get it works fine. I did see you can use a class called HTTPClient for doing this stuff but I can't use it as I need to get this working for WinForms, Silverlight and Windows Phone all based on .Net 3.5
Any help pushing POCO's to the server would be a great help, cheers!
ADDITIONAL INFO:
Currently I get no error, the test app just hangs.
If I turn off the WebAPI project I get a server not found response.
I have not changed any routes or any of that.
Gets to the same controller work.
You will need to close the response stream. Most examples I see also show setting the content length. You may be better to serialize to a memory stream and then use the length of that stream as the Content-Length. Unfortunately in .net 3.5 there is no CopyStream so you may have to write that yourself.
If you want to use the HttpClient, you can install the download the REST starter Kit. and use the DLLs as external DLLs
http://forums.asp.net/t/1680252.aspx/1

Categories

Resources