Unity: Use HTTP PUT in Unity3D - rest

I'm quite new to Unity and facing some problems about RESTFul in Unity.
I want to update some data on the server by using HTTP PUT, but as what I received when search the web, the WWWW class in Unity doesn't support HTTP PUT. I also tried some HttpWebRequest example related to HTTP PUT but always received error code 400: Bad Request.
How can I solve this problem?
Do I have to list out all the key-value pairs when updating or just need to list the pairs I want to change the value ?

If you're not looking for a 3rd party plugin and assuming your server supports it then one method you could look at using is the "X-HTTP-Method-Override" HTTP header. Your client sends the data to the server via POST, but the server handles this as the value in the X-HTTP-Method-Override header (such as PUT).
I've used this before to great effect where our server supported it. An example of using this in Unity3d would be along the lines of:
string url = "http://yourserver.com/endpoint";
byte[] body = Encoding.UTF8.GetBytes(json);
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add( "Content-Type", "application/json" );
headers.Add( "X-HTTP-Method-Override", "PUT" );
WWW www = new WWW(url, body, headers);

I recommend looking at BestHTTP package instead of default WWW class. It's cheap (almost all Unity3d assets are, compared to typical middleware prices in game industry) and it's pretty decent, judging by personal experience.
Alternatively, you can use standard .NET sockets.

I made it worked by the following codes using HttpWebRequest
void updatePlayer(){
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://yourAPIUrl");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "PUT";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{" +
"'ID': '100'," +
"'ClubName': 'DEF'," +
"'Number': 102," +
"'Name': 'AnNT'," +
"'Position': 'GK'," +
"'DateOfBirth': '2010-06-15T00:00:00'," +
"'PlaceOfBirth': 'Hanoi'," +
"'Weight': 55," +
"'Height': 1.55," +
"'Description': 'des'," +
"'ImageLink': 'annt.png'," +
"'Status': false," +
"'Age': '12'" +
"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
//Now you have your response.
//or false depending on information in the response
Debug.Log(responseText);
}
}

Related

Post with Accept Header .Net Core 3.1 - PagSeguro

I'm trying to integrate with a payment gateway (PagSeguro), according to the documentation, I must use the Accept Header "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1".
Trying with the code not work:
HttpClient.DefaultRequestHeaders.Clear();
HttpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1");
var content = new StringContent(json, Encoding.Default, "application/json");
var response = await HttpClient.PostAsync(enderecoPreApprovals, content);
var responsestr = await response.Content.ReadAsStringAsync();
I also tried using the same code from documentation:
var client = new RestClient(url) {Timeout = -1};
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1");
request.AddParameter("application/json", content, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
and using flurl:
var response = await addresPreApprovals
.WithHeader("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1")
.WithHeader("Content-Type", "application/json")
.PostJsonAsync(adesaoDto);
All the responses are Accept header field is mandatory.. It's like Accept Header is not recognized.
The problem is not in API why i tried using Postman and Insomnia and it's works perfectly.
The problem occurs because of the space between the semicolon (;) and the word charset. We were unable to make it work in .NET 3.1 and there is even an issue on github, indicating that it is not a problem, an implementation of the RFC 7231 specification. Whenever a string "var1 = val1; var2 = val2", o is indicated. NET converts to "var1 = val1; var2 = val2". However, in .NET 5.0, an implementation was released that allows entering a raw string. Another option, according to an old post, is to create something with .NET Framework 4.5
In .NET 5.0
var acceptValue = "application/vnd.pagseguro.com.br.v1+json;charset=ISO-8859-1";
var requestMessage = new HttpRequestMessage(HttpMethod.Post, urlApprovals);
requestMessage.Headers.TryAddWithoutValidation("accept", acceptValue);
GitHub ref: https://github.com/dotnet/runtime/issues/30171
User who solved the problem using .NET Framework 4.5: https://stackoverflow.com/a/40162071/2112736

Can any body share me java code to make a one Rest api call to IBM BPM Cloud

Can any body share a java client code which makes a Rest calls to IBM Cloud BPM. Basically I want to know how to authenticate IBM Cloud BPM.
I tried the following code but it is not working
String user_info_url="https://ustrial01.bpm.ibmcloud.com/bpm/dev/rest/bpm/wle/v1/user/current?includeInternalMemberships=true&parts=all";
logger.info("user_info_url :" + user_info_url);
HttpClient client = HttpClientBuilder.create().build();
HttpGet get = new HttpGet(user_info_url);
String authData = "rajesh.kohir123#gmail.com" + ":" + "password";
String encoded = new sun.misc.BASE64Encoder().encode(authData .getBytes());
get.setHeader("Content-Type", "application/json");
get.setHeader("Accept", "application/json");
get.setHeader("Authorization", "Basic " + encoded);
HttpResponse cgResponse = client.execute(get);
if(cgResponse.getStatusLine().getStatusCode() != 200) {
logger.info("IBM Rest call failed");
}
if(cgResponse.getStatusLine().getStatusCode() == 200) {
logger.info("IBM Rest call Succeded");
String content = EntityUtils.toString(cgResponse.getEntity());
logger.info(content);
}
Any help is greatly appreciated
I ran your code and just made the changes in URL. It worked. I hope this helps you.
Following is the URL I used to execute an exposed service :
https://vhost031.bpm.ibmcloud.com/bpm/dev/rest/bpm/wle/v1/service/OMS#Greetings
I used the following code to add the parameters :
String parameters = "{'name':'pramod'}";
URIBuilder builder = new URIBuilder("https://vhost031.bpm.ibmcloud.com/bpm/dev/rest/bpm/wle/v1/service/OMS#Greetings");
List nameValuePairs = new ArrayList();
nameValuePairs.add(new BasicNameValuePair("action", "start"));
nameValuePairs.add(new BasicNameValuePair("params", parameters));
nameValuePairs.add(new BasicNameValuePair("createTask", "false"));
nameValuePairs.add(new BasicNameValuePair("parts", "all"));
builder.setParameters(nameValuePairs);
HttpGet get = new HttpGet(builder.build());
Download the download.zip form the post.
Look at the SampleBPDProcessTests.java - Line no 103
JSONObject results = bpmClient.runBPD(BPD_ID, PROCESS_APP_ID, bpdArgs);
The actual Java Code for Rest call is available as part of "bpm-rest-client.jar"
Try this concept.
Sample Java code to start a process:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://ustrial03.bpm.ibmcloud.com:443/bpm/dev/rest/bpm/wle/v1/process?
processAppId=3u092jr02j-djaodaj.u092302c166c1&bpdId=25.jklaklaa-539a-4150-
b63e-9ef94e96e521&action=start")
.put(null)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Accept", "application/json")
.addHeader("Connection", "keep-alive")
.addHeader("Authorization", "Basic YXJrYX24223232hQGRlbG9pdHRlLmNvbTpkZWZjb240QA==")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "f46c1525-7a75-954c-9265-bb2b21a57f16")
.build();
Response response = client.newCall(request).execute();
A full explanation of REST integration with BPM Cloud can be found in my answer at:
How to run IBM BPM Rest api call from Post man client

How to consume REST api in Xamarin.iOS?

I have made a REST API and I want to use it using my Xamarin.iOS application.
Basically I want to call the API from my Xamarin application by sending some arguments to one of my API's function.
I tried the resources available at Xamarin's official website, but I a newbie so I cannot understand how it was done.
The REST API is hosted locally by the network I am using. It is not hosted at a static IP.
Kindly guide me.
You don't really need a fancy plugin if you just want to hit Web Endpoints. I simply use the basic WebRequest API.
var request = WebRequest.CreateHttp(YOUR_URL_HERE);
request.Method = "GET";
request.ContentType = "application/JSON";
request.BeginGetResponse(ResponseComplete, request);
... and then your response method can be something along the lines of...
protected void ResponseComplete(IAsyncResult result)
{
try
{
var request = result.AsyncState as HttpWebRequest;
if (request != null)
{
Debug.WriteLine("Completed query: " + request.RequestUri);
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Debug.WriteLine("Query Result: " + result);
}
}
}
}
... and if you need to post data you can add request.BeginGetRequestStream(PostData, request); before request.BeginGetResponse(ResponseComplete, request); and make your GetRequestStream handling method something along the lines of...
protected void PostData(IAsyncResult result)
{
var request = result.AsyncState as HttpWebRequest;
if (request != null)
{
using (var postStream = request.EndGetRequestStream(result))
{
var json = JsonConvert.SerializeObject(DATA_TO_POST);
Debug.WriteLine("Posting data: " + json);
var byteArray = Encoding.UTF8.GetBytes(json);
postStream.Write(byteArray, 0, byteArray.Length);
}
}
}
I would recommend Refit, you can install it as a NuGet package. Its pritty simple to use.
Refit allows us to define an interface that describes the API that we're calling, and the Refit framework handles making the call to the service and deserializing the return.
Have a look at this great blog post on how to set it up and other packages that might help you out. http://arteksoftware.com/resilient-network-services-with-xamarin/
I have used RestSharp before but Refit is alot easier to get running.

Sharepoint authentication without using sharepoint development environment or service references?

I am trying to access a local SharePoint site using a .net program and am having difficulties.
I don't want to use the SharePoint development environment (may have many developers work on this, and that is just one more thing to install).
I would also like to make this configurable so that I can change the site and list name without recompiling. I don't think I can do that with the Service References. If I can, how?
I also don't want the user to enter sharepoint validation information, I am ok with storing sharepoint login information in a .config file.
I believe I could do this with REST, but can't figure out how to create an AccessToken without using the Sharepoint development environment.
Any help would be appreciated.
The main problem I was having was not understanding that you could put other types of credentials in the request.Credentials property. Here is the code I created:
public bool CopyFileToSharePoint(string fileName, Stream fileStream)
{
var data = new byte[fileStream.Length];
fileStream.Read(data, 0, (int) fileStream.Length);
fileStream.Close();
var sharePointPath =
SharePointWebSiteUrl + "/_api/web/lists/getByTitle('" + SharePointListName + "')" +
"/RootFolder/Files/add(url='" + fileName + "',overwrite='true')";
var request = (HttpWebRequest) WebRequest.Create(sharePointPath);
request.Credentials = new NetworkCredential(SharePointUserName, SharePointPassword, SharePointLoginDomain);
request.Method = "POST";
request.Accept = "application/atom+xml";
request.Headers["X-RequestDigest"] = GetFormDigest(SharePointWebSiteUrl);
request.ContentType = "application/txt";
request.ContentLength = data.Length;
request.GetRequestStream().Write(data, 0, data.Length);
var response = (HttpWebResponse) request.GetResponse();
return response.StatusCode == HttpStatusCode.OK;
}
I'm sure it's not perfect, but it works.

Must/can I install MS ASP.NET Web API Client Libraries in order to post data to my Web API server?

Do I need to install ASP.NET Web API Client Libraries (as this article indicates) in order to post data to a Web API server? If so, can I do so in Visual Studio 2008 from a Windows CE project?
The reasons I wonder are:
0) The client is a Windows CE project, for which I'm using Visual Studio 2008, and I don't know if ASP.NET Web API Client Libraries are available for that version; I know I don't have the NuGet Package Manager in that environment.
1) I am successfully querying data from my RESTful Web API methods without installing ASP.NET Web API Client Libraries, using code like this:
while (true)
{
deptList.departments.Clear();
string uri = String.Format("http://platypi:28642/api/Duckbills/{0}/{1}", lastIdFetched, RECORDS_TO_FETCH);
var webRequest = (HttpWebRequest) WebRequest.Create(uri);
webRequest.Method = "GET";
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
var reader = new StreamReader(webResponse.GetResponseStream());
string jsonizedDuckbills = reader.ReadToEnd();
List<Duckbill> duckbills = JsonConvert.DeserializeObject<List<Duckbill>>(jsonizedDuckbills);
if (duckbills.Count <= 0) break;
foreach (Duckbill duckbill in duckbills)
{
duckbillList.duckbills.Add(duckbill);
lastIdFetched = duckbill.Id;
}
} // if ((webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse
int recordsAdded = LocalDBUtils.BulkInsertDuckbills(duckbillList.duckbills);
totalRecordsAdded += recordsAdded;
} // while (true);
I'm stuck on posting, though, and the cleanest example I've seen so far for doing so is at that link already shown above.
I got an answer to my question on how to post here, but that hasn't made me smart enough yet to actually accomplish it. It's a step in the right direction, perhaps, although I reckon, based on how my client query code looks, that the client posting code would be of similar "style" (like the previously referenced article here, and unlike the likewise previously referenced answer here).
UPDATE
If I'm already providing the data in the uri string itself, as I am, like this:
string uri = String.Format("http://shannon2:28642/api/Departments/{0}/{1}", onAccountOfWally, moniker);
...why would I need to also specify it in postData? Or could I set postData (if that's just a necessary step to get the length) to those values...something like:
postData = String.Format("{0}, {1}", onAccountOfWally, moniker);
?
To talk to ASP.NET Web API, you do not necessarily need the client library, although it makes the life easier. After all, one of the benefits of HTTP services is the platform reach. Literally you can use any library that gives you HTTP capabilities. So, using WebRequest, you can do something like this. I'm using JSON in the payload. You can use XML and application/www-form-urlencoded as well. Just that you need to format the request body accordingly. Also, for complex objects, you will be better off using JSON.NET unlike formatting the JSON manually.
var request = System.Net.WebRequest.Create("http://localhost:12345/api/values");
request.Method = "POST";
string postData = "{\"firstName\":\"Steven\"," + "\"lastName\":\"Waugh\"}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(byteArray, 0, byteArray.Length);
}
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var reader = new System.IO.StreamReader(responseStream))
{
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
}
}
}
EDIT
If you are specifying data in URI, you do not need to specify the same in the request body. To let web API bind the parameters for you from URI, you will need to specify the route accordingly so that the placeholders are set for onAccountOfWally and moniker. Then you will need to use a simple type like string as action method parameters for web API to bind. By default, simple types are bound from URI path and query string and complex types from request body.