I believe the answer is simple but none of the code samples I've found worked...
Basically I'm trying to send a post request using System.Net.WebClient, with a string parameter; But the server gets the parameter as null.
It has to be written in dotnet 2, so I can't use HttpClient (which worked by the way).
client:
using(var client = new WebClient())
{
try
{
var res = client.UploadString(_uri, "POST", "test");
if (res != "test")
return false;
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
return false;
}
service:
public string Post([FromBody]string value)
{
return value;
}
Haven't tested this code, but try it out. You can add more headers, if it throws more errors it might require more specific headers.
using (WebClient client = new WebClient())
{
string yourURL = "http://example.com/example.php";
string PARM= "par1=value1&par=value2";
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string result= client.UploadString(yourURL, PARM);
if(result != "test"){
return false
}
}
Related
I have this function in my xamarin.ios app that posts an object to my api . The object contains strings and 1 member as a base64 string . I can't seem to get a timeout and get an exception in less than 5 minutes when there is no connection. However it seems to be timing out when there is no base 64 in the object. Any idea to get this to work? Here is my code :
public static string postData(object #params, string url)
{
MyWeWbClient webClient = new MyWeWbClient();
try
{
webClient.Headers["content-type"] = "application/json";
webClient.Headers.Add("Authorization", "Bearer " + Settings.GeneralSettings3);
var reqString = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(#params, Formatting.Indented));
byte[] resByte = webClient.UploadData(url, "post", reqString);
var resString1 = Encoding.Default.GetString(resByte);
webClient.Dispose();
return resString1;
}
catch (WebException ex)
{
string responseText = "";
var responseStream = ex.Response?.GetResponseStream();
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
responseText = reader.ReadToEnd();
}
}
throw new Exception(responseText.ToString());
}catch(Exception ex)
{
throw;
}
}
And my custom webclient class so I can do set timeout:
public class MyWeWbClient : WebClient
{
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest w = base.GetWebRequest(uri);
w.Timeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;//20 * 60 * 1000;
return w;
}
}
Thanks in advance. Any help is appreciated.
EDIT:
The same code is working perfectly fine on xamarin.android , and its timing out if there is no internet connection like intended.
I don't recommand using webClient, I would use an external depency like restsharp.
Alternatively, you can hardcode it using Task.Run() but since its in Xamarin I couldn't say.
I would like to make a simple Http request using the Webclient:
public string PostRequest(object json, string contentType, string server)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(server);
request.ContentType = contentType;
request.Method = "POST";
request.Timeout = 10000;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(json));
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
return streamReader.ReadToEnd();
}
}
catch (Exception e)
{
throw e;
}
}
The problem is that the request.GetRequestStream() part does never return and will always timeout (with the default 100s and the 10s as well). I am using a samsung xcover 4 with android 7 and later android 8.1. the server string works perfectly when copyed into my standard browser on the PC.On the device browser itself it does not work (timeout). The contentType is "application/json".
Is there something I can do to fix this problem or is there another method to send httprequests in xamarin that are not broken?
the server itself is working and I can ping it form my device:
public int PingHost(string nameOrAddress)
{
int pingCount = 0;
Ping pinger = null;
for (int i = 0; i < 4; i++)
{
try
{
pinger = new Ping();
PingReply reply = pinger.Send(nameOrAddress);
pingCount += reply.Status == IPStatus.Success ? 1:0;
}
catch (Exception){ pingCount = - 1; }
finally
{
pinger?.Dispose();
}
if (pingCount == -1) return -1;
}
return pingCount;
}
thanks for your time.
Well I have a working code in my application and it is something like this:
public HttpClient apiClient;
GetType API
public async Task<string> GetServiceData(string srvUrl)
{
try
{
apiClient = new HttpClient(new NativeMessageHandler(throwOnCaptiveNetwork: false, customSSLVerification: false)); // SSL true if you have custom SLL in your API
apiClient.BaseAddress = new Uri(_yourbaseUrl); // Url where the service is hosted
apiClient.DefaultRequestHeaders.Add("",""); //defualt req header key value in case any
var respon = await apiClient.GetAsync(srvUrl).Result.Content.ReadAsStringAsync(); // svrUrl is the name of the api that you want to consume
if (respon != string.Empty)
{
return respon;
}
}
catch (HttpRequestException reqEx)
{
return string.Empty;
}
catch (Exception ex)
{
return string.Empty;
}
}
PostType API
public async Task<string> PostServiceData(string srvUrl, object srvModel)
{
try
{
var myContent = JsonConvert.SerializeObject(srvModel);//your parameter to the API
var stringContent = new StringContent(myContent, Encoding.UTF8, "application/json");
apiClient = new HttpClient(new NativeMessageHandler(throwOnCaptiveNetwork: false, customSSLVerification: true));// SSL true if you have custom SLL in your API
apiClient.BaseAddress = new Uri(_yourbaseUrl); // Url where the service is hosted
apiClient.DefaultRequestHeaders.Add("",""); //defualt req header key value in case any
apiClient.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
var respon = await apiClient.PostAsync(srvUrl, stringContent);
var resReslt = respon.Content.ReadAsStringAsync().Result;
return resReslt;
}
else
return string.Empty;
}
catch (HttpRequestException reqEx)
{
return string.Empty;
}
catch (Exception ex)
{
return string.Empty;
}
Good luck In case of queries revert!
I have a web service where I Post to a URL Asynchronously
public Response uploadXMLData(string destinationUrl, string requestXml,Request req)
{
try
{
Response resp=new Response();
System.Uri uri = new System.Uri(destinationUrl);
using (WebClient client = new WebClient())
{
client.UploadStringCompleted
+= new UploadStringCompletedEventHandler(UploadStringCallback);
client.UploadStringAsync(uri, "POST",requestXml,req);
}
}
catch (Exception ex)
{}
return resp;
}
public void UploadStringCallback(object sender, UploadStringCompletedEventArgs e)
{
Response resp=new Response();
Request req = new Request();
try
{
if (e.Error != null)
{
object objException = e.Error.GetBaseException();
Type _type = typeof(WebException);
if (_type != null)
{
WebException objErr = (WebException)e.Error.GetBaseException();
WebResponse rsp = objErr.Response;
using (Stream respStream = rsp.GetResponseStream())
{
req= (Request)e.UserState;
resp=Utilities.ParseWithoutSoapEnv(respStream);
}
}
else
{
Exception objErr = (Exception)e.Error.GetBaseException();
throw objErr;
}
}
else
{
//Parse e.Result
}
}
catch (Exception ex)
{}
}
The Function Called Utilities.ParseWithoutSoapEnv(respStream); returns Type Response
what I want to do is get the Response from that function, and make it the return value for uploadXMLData
But I can't change the return type of a CallBack Function, so I have no idea what to do.
When someone calls my webservice function, they expect it to return a type of Response, and the Response class I need is being received to the CallBack function..
Hope I made my issue clear
Any help would be appreciated
Things get a little easier if you use the Task Asynchronous Pattern and HttpClient. You'll need to modify your method to return a Task<Response>:
public async Task<Response> UploadXmlDataAsync(
string destinationUrl,
string requestXml,
Request req)
{
try
{
Response resp=new Response();
System.Uri uri = new System.Uri(destinationUrl);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync(Uri, new StringContent(requestxml))
.ConfigureAwait(false);
var responeStream = response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return Utilities.ParseWithoutSoapEnv(responseStream);
}
}
And when you call it higher up the call-stack, you'll need to await that too:
public async Task FooAsync()
{
var parsedResponse = await UploadXmlDataAsync(url, xml, request);
// Do something with response.
}
If you want a synchronous alternative, you can also do:
public Response UploadXmlData(string destinationUrl, string requestXml,Request req)
{
Response resp=new Response();
System.Uri uri = new System.Uri(destinationUrl);
using (WebClient client = new WebClient())
{
var response = client.UploadString(uri, "POST", requestXml, req);
using (var responseStream = new MemoryStream(Encoding.UTF8.GetBytes(response))
{
return Utilities.ParseWithoutSoapEnv(responseStream);
}
}
}
Uri myuri = new Uri("https://buffalousercontent.blob.core.windows.net/371-static/profileimages/full/39398");
This is my uri, when u hit means it receives image based on user some user doesn't contains image at that time it receives error page.
How to check the received one is image or something in C# code?
If you're just looking to validate that the URL contains an image:
bool ValidateImage(string url)
{
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
r.Method = "GET";
try
{
HttpWebResponse resp = (HttpWebResponse)r.GetResponse();
if (resp.ContentType == "image/jpeg")
{
Console.WriteLine("Image retrieved successfully.");
// Process image
return true;
}
else
{
Console.WriteLine("Unable to retrieve image");
}
}
catch
{
Console.WriteLine("Unable to retrieve image.");
}
return false;
}
Obviously, change the ContentType check to whatever makes sense for your application. You could also use HEAD as the request method (as in #Chris' answer) if you're just looking to validate the content type and not download the entire image right then.
As mentioned in the other answers, you can look at the content type of the response, or you could try to create an image from the URI.
try {
var client = new WebClient();
var image = Image.FromStream(client.OpenRead(uri));
}
catch(ArguementException e) {
// this exception will be thrown if the URI doesn't point to a valid image.
}
To check if there is an error, you have to send a request and then receive an error or a good blob.
To send a request, you can use WebClient as described here :
public bool CheckUri(Uri uri){
using(var client = new WebClient()){
try{
client.DownloadFile(uri);
return true;
}catch{//error detected
return false;
}
}
}
Do a httprequest and check if the response contenttype equals "image/". This function should do the trick!
Boolean IsImageUrl(string URL)
{
var req = (HttpWebRequest)HttpWebRequest.Create(URL);
req.Method = "HEAD";
using (var resp = req.GetResponse())
{
return resp.ContentType.ToLower(CultureInfo.InvariantCulture)
.StartsWith("image/");
}
}
Well a Uri object itself doesn't know what will happen when you use it as the address of a GET request.
To check if a string is a valid Uri, you can use
Uri uri;
bool valid = Uri.TryCreate(stringInput, UriKind.Absolute, out uri);
To check what the file type of a request is
using (var client = new HttpClient())
{
var response = client.GetAsync(uri).Result;
var contentType = response.Content.Headers.ContentType;
}
You can use the Azure client API to do this. Add a reference to Microsoft.WindowsAzure.StorageClient:
bool IsBlobJpeg(string blobUri)
{
try
{
Microsoft.WindowsAzure.StorageClient.CloudBlob blob =
new CloudBlob(
blobUri);
blob.FetchAttributes();
return (blob.Properties.ContentType == "image/jpeg");
}
catch (StorageClientException ex)
{
Console.WriteLine(String.Format("{0} Does not exist", blobUri));
return false;
}
}
Is it possible to pass parameters with an HTTP get request? If so, how should I then do it? I have found an HTTP post requst (link). In that example the string postData is sent to a webserver. I would like to do the same using get instead. Google found this example on HTTP get here. However no parameters are sent to the web server.
My preferred way is this. It handles the escaping and parsing for you.
WebClient webClient = new WebClient();
webClient.QueryString.Add("param1", "value1");
webClient.QueryString.Add("param2", "value2");
string result = webClient.DownloadString("http://theurl.com");
First WebClient is easier to use; GET arguments are specified on the query-string - the only trick is to remember to escape any values:
string address = string.Format(
"http://foobar/somepage?arg1={0}&arg2={1}",
Uri.EscapeDataString("escape me"),
Uri.EscapeDataString("& me !!"));
string text;
using (WebClient client = new WebClient())
{
text = client.DownloadString(address);
}
In a GET request, you pass parameters as part of the query string.
string url = "http://somesite.com?var=12345";
The WebRequest object seems like too much work for me. I prefer to use the WebClient control.
To use this function you just need to create two NameValueCollections holding your parameters and request headers.
Consider the following function:
private static string DoGET(string URL,NameValueCollection QueryStringParameters = null, NameValueCollection RequestHeaders = null)
{
string ResponseText = null;
using (WebClient client = new WebClient())
{
try
{
if (RequestHeaders != null)
{
if (RequestHeaders.Count > 0)
{
foreach (string header in RequestHeaders.AllKeys)
client.Headers.Add(header, RequestHeaders[header]);
}
}
if (QueryStringParameters != null)
{
if (QueryStringParameters.Count > 0)
{
foreach (string parm in QueryStringParameters.AllKeys)
client.QueryString.Add(parm, QueryStringParameters[parm]);
}
}
byte[] ResponseBytes = client.DownloadData(URL);
ResponseText = Encoding.UTF8.GetString(ResponseBytes);
}
catch (WebException exception)
{
if (exception.Response != null)
{
var responseStream = exception.Response.GetResponseStream();
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
Response.Write(reader.ReadToEnd());
}
}
}
}
}
return ResponseText;
}
Add your querystring parameters (if required) as a NameValueCollection like so.
NameValueCollection QueryStringParameters = new NameValueCollection();
QueryStringParameters.Add("id", "123");
QueryStringParameters.Add("category", "A");
Add your http headers (if required) as a NameValueCollection like so.
NameValueCollection RequestHttpHeaders = new NameValueCollection();
RequestHttpHeaders.Add("Authorization", "Basic bGF3c2912XBANzg5ITppc2ltCzEF");
GET request with multiple params:
curl --request GET --url
http://localhost:8080/todos/?limit=10&offset=2 --header
'content-type:application/json'
You can also pass value directly via URL.
If you want to call method
public static void calling(string name){....}
then you should call usingHttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create("http://localhost:****/Report/calling?name=Priya);
webrequest.Method = "GET";
webrequest.ContentType = "application/text";
Just make sure you are using ?Object = value in URL