glitch.com project can't be called with c# - c#

I am writing this question in context of glitch.com projects.
so, i made a test project(asp.net .net6 webapi) in glitch.com which returns your ip address. The link to the webpage is https://ror-test.glitch.me/getip . It runs perfectly fine and returns response accurately when called from a browser. Now, I want to access this project from c# client (to be precise unity3d) however i am unable to access it.
My first try was to use httpclient.getstringasync-
Code-
HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
System.Console.WriteLine(response);
Output-
Unhandled exception. System.Net.Http.HttpRequestException: Response status code does not indicate success: 403 (Forbidden).
In my second try i used httpclient.getasync
Code-
HttpClient client = new HttpClient();
var response = await client.GetAsync(url);
Output-
Response - https://jpst.it/348Ik
Response.Content - https://jpst.it/348LS
Also just to say that my app is working perfectly fine when i call the project from nodejs it works perfectly-
Code -
var url = "https://ror-test.glitch.me/getip";
var XMLHttpRequest = require("xhr2");
var xhr = new XMLHttpRequest();
console.log("starting");
xhr.open("GET", url);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}};
xhr.send();
Output -
starting
200
your ip: xx.xx.xxx.xx
In place of xx.xx.xxx.xx my real ip which i have cross checked with https://whatismyipaddress.com/ is coming. so i am sure problem is with c# client.
Plz help me or any other way i can call it from c# client(precisely unity3d).

You need to pass User-Agent request header.
HttpClient client = new HttpClient();
//add user agent
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "fake");
var response = await client.GetAsync(url);

Related

C# application hangs during POST request to python http server

I have a C# app that makes a post request to a simple http server created in Python but my request never "finishes" and doesn't progress past the point of making an asynchronous POST request. This is the call I'm making from my client (C# app):
private void sendPost(HttpClientAdaptor client, MyDataObject myDataObject) {
var payload = JsonConvert.SerializeObject(myDataObject);
var content = new StringContent(payload, Encoding.UTF8, "application/json");
try {
if (client.isDisposed) {
return;
}
var response = client?.PostAsync(ApiEndpoint, content); // this hangs forever
And my http server written in python:
#!/usr/bin/env python3
"""
Very simple HTTP server in python for logging requests
Usage::
./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
from io import BytesIO
class S(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
self.send_response(200)
self.end_headers()
response = BytesIO()
response.write(b'This is POST request. ')
response.write(b'Received: ')
response.write(body)
self.wfile.write(response.getvalue())
def run(server_class=HTTPServer, handler_class=S, port=5000):
logging.basicConfig(level=logging.INFO)
server_address = ('', port)
httpd = server_class(server_address, handler_class)
logging.info('Starting httpd...\n')
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
logging.info('Stopping httpd...\n')
if __name__ == '__main__':
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
I know the request is making it to my server since I used some print statements to print the payload but my client seemingly never acknowledges the 200 response from my server. I've verified the server is running, I'm not mixing up the port, and a GET request works via a browser.
I suspect something's wrong with my python server such that it's not 'finishing' the transaction and therefore my client doesn't get a response.
As an aside: Is there a more simple approach to spin up an http server for my client (windows app written in C#)? I just need a way to return a 200 status.
You are using an async function and are not awaiting it.
Instead of
var response = client?.PostAsync(ApiEndpoint, content);
try
var response = await client?.PostAsync(ApiEndpoint, content);
And change your method signature from
private void sendPost
To
private async Task sendPost

GET Request return 400 bad response

It's a generic question, but I need help with my specific case.
I have a simple GET endpoint (see image) which I've tested with Postman and it works
It takes two id tokens in the header and thats it.
I've put breakpoints in the code and copied the exact instance of the ids into Postman and the request works, but executing from code, I get a 400 response
using (HttpClient client = new HttpClient())
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://*******.execute-api.ap-southeast-2.amazonaws.com/dev/uploads/image.jpg"),
Method = HttpMethod.Get,
};
var idToken = Application.Current.Properties["id_token"].ToString();
var accessToken = Application.Current.Properties["access_token"].ToString();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Add("Id-Token", idToken);
request.Headers.Add("Access-Token", accessToken);
var response = await client.SendAsync(request);
}
I've tried with and without the content-type header and makes no difference. Also doesn't matter if it's present in Postman
This is a Xamarin project which is where Application.Current.Properties comes from. I'm utilising other endpoints in the application are there are no issues with accessing the tokens like this.

PostAsync in UWP App not working (no content sent)

I'm a bit stuck, I am trying to create a UWP App that will post XML content to a web service. I can get this to work in a regular .net console app without an issue. Trying to re-create this using UWP is proving to be tricky. Using fiddler I've narrowed down that the web service end point isn't receiving my content. It looks like the headers are setup properly the content length is sent correctly but the actual content isn't sent. Here is the heart of the code, it crashes/throws an exception after:
HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent2).ContinueWith(
(postTask) => postTask.Result.EnsureSuccessStatusCode());
When I try to execute the PostASync, looking at fiddler, I'm getting:
HTTP/1.1 408 Request body incomplete
Date: Mon, 14 Nov 2016 15:38:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Cache-Control: no-cache, must-revalidate
Timestamp: 10:38:53.430
The request body did not contain the specified number of bytes. Got 0, expected 617
I'm positive that I am getting content to post correct (I read it from a file, I send it to debug window to verify and it's correct). I think it might have to do with HttpContent httpContent2 - In regular .NET I've never needed to use this but with PostAsync I need to use it.
Any thoughts would be appreciated, thank you!
public async void PostWebService()
{
string filePath = "Data\\postbody.txt";
string url = "https://outlook.office365.com/EWS/Exchange.asmx";
Uri requestUri = new Uri(url); //replace your Url
var myClientHandler = new HttpClientHandler();
myClientHandler.Credentials = new NetworkCredential("user#acme.com", "password");
HttpClient request = new HttpClient(myClientHandler);
string contents = await ReadFileContentsAsync(filePath);
Debug.WriteLine(contents);
HttpContent httpContent2 = new StringContent(contents, Encoding.UTF8, "text/xml");
string s = await httpContent2.ReadAsStringAsync();
Debug.WriteLine(s); //just checking to see if httpContent has the correct data
//HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent);
request.MaxResponseContentBufferSize = 65000;
HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent2).ContinueWith(
(postTask) => postTask.Result.EnsureSuccessStatusCode());
Debug.WriteLine(ResponseMessage.ToString());
}
Well it seems like I found the root cause to my problem. This is appears to be a known bug with System.Net.Http.HttpClient when using network authentication. See this article here
My initial mistake was that I wasn't catching an exceptions thrown by PostAsync. once I wrapped that inside a try/catch block I got the following exception thrown:
“This IRandomAccessStream does not support the GetInputStreamAt method because it requires cloning and this stream does not support cloning.”
The first paragraph of the article I linked to above states:
When you use the System.Net.Http.HttpClient class from a .NET
framework based Universal Windows Platform (UWP) app and send a
HTTP(s) PUT or POST request to a URI which requires Integrated Windows
Authentication – such as Negotiate/NTLM, an exception will be thrown.
The thrown exception will have an InnerException property set to the
message:
“This IRandomAccessStream does not support the GetInputStreamAt method
because it requires cloning and this stream does not support cloning.”
The problem happens because the request as well as the entity body of
the POST/PUT request needs to be resubmitted during the authentication
challenge. The above problem does not happen for HTTP verbs such as
GET which do not require an entity body.
This is a known issue in the RTM release of the Windows 10 SDK and we
are tracking a fix for this issue for a subsequent release.
The recommendation and work around that worked for me was to use the Windows.Web.Http.HttpClient instead of System.Net.Http.HttpClient
Using that recommendation, the following code worked for me:
string filePath = "Data\\postbody.txt";
string url = "https://outlook.office365.com/EWS/Exchange.asmx";
Uri requestUri = new Uri(url); //replace your Url
string contents = await ReadFileContentsAsync(filePath);
string search_str = txtSearch.Text;
Debug.WriteLine("Search query:" + search_str);
contents = contents.Replace("%SEARCH%", search_str);
Windows.Web.Http.Filters.HttpBaseProtocolFilter hbpf = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
Windows.Security.Credentials.PasswordCredential pcred = new Windows.Security.Credentials.PasswordCredential(url, "username#acme.com", "password");
hbpf.ServerCredential = pcred;
HttpClient request = new HttpClient(hbpf);
Windows.Web.Http.HttpRequestMessage hreqm = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, new Uri(url));
Windows.Web.Http.HttpStringContent hstr = new Windows.Web.Http.HttpStringContent(contents, Windows.Storage.Streams.UnicodeEncoding.Utf8, "text/xml");
hreqm.Content = hstr;
// consume the HttpResponseMessage and the remainder of your code logic from here.
try
{
Windows.Web.Http.HttpResponseMessage hrespm = await request.SendRequestAsync(hreqm);
Debug.WriteLine(hrespm.Content);
String respcontent = await hrespm.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
string e = ex.Message;
Debug.WriteLine(e);
}
Hopefully this is helpful to someone else hitting this issue.

How to clear json api response from windows phone 8.1

I am developig a windows app 8.1. Where I am calling an json api in a page say "Page1". My issue is that when I navigate to another page say "Page2" and come back to "Page1", I recive the same data from the api. I found that when I come back to the Page1 again, my web api is called but the result is come from I guess from cache.So, json data is not updated. How can I overcome with this issue. Any suggestion is most welcome.
My Rest API Call Code Is
var client = new HttpClient(); // Add: using System.Net.Http;
var response = await client.GetAsync(new Uri(url));
response.Headers.Add("Cache-Control", "no-cache");
var result = await response.Content.ReadAsStringAsync();
response.Dispose();
client.Dispose();
return ressult.
In the calling url just add a random parameters like
string uri = string.format(http://www.myservice.com?time={0}",DateTime.Now);
var response = await client.GetAsync(new Uri(uri));

Why can my WebApi client make only a single GET request?

I wrote a simple client for my web service with Web Api as explained in this tutorial:
http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
The first request (GET a table) is executed successfully. That is, table data is fetched from the web service and bound to TableContent object.
But the program is totally blocked before executing the second request (GET table list); nothing happens, not even an error message!
If I comment out the code section related with the first request (GET a table) the second request (GET table list) is executed successfully.
What happens here? Why can this client execute only a single GET request?
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56510/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
// GET a table from web service
response = await client.GetAsync("api/table/GetMatrixTable");
if (response.IsSuccessStatusCode)
{
var tblcont = await response.Content.ReadAsAsync<TableContent>();
// do things ...
}
// GET a table list from web service
response = await client.GetAsync("api/table/GetTableList");
if (response.IsSuccessStatusCode)
{
var TblContList = await response.Content.ReadAsAsync<IList<TableContent>>();
// do things ...
}
}
Looking at the following SO question and its accepted answer (maybe not directly relevant but still useful in its own right):
HttpClient.GetAsync(...) never returns when using await/async
it might help if you replace your calls to GetAsync() as follows:
response = await client.GetAsync("api/table/GetMatrixTable",
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
. . .
response = await client.GetAsync("api/table/GetTableList",
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
I'm not able to test that so I can't take all the credit if that works.

Categories