I am completely new to windows phone app development. I just installed the Visual Studio 2015 and started working on a new app. Was going all smooth until the time arrived to call a web service of my back-office. First I was unable to debug why and where the code threw exception. Then I realized and tried writing the exception's message to a text block.
Note I have tried using the same code what I got from working examples found by Googling.
Error: "HRESULT E_FAIL has been returned from a call to a COM component"
Code:
public async Task<dynamic> getHomeCategories()
{
string url = string.Format("my working api url");
var uri = new Uri(url);
var client = new HttpClient();
dynamic resultObj = "";
//using (HttpResponseMessage response = await client.GetAsync(url))
try
{
var response = await client.GetStringAsync(uri);
resultObj = Newtonsoft.Json.Linq.JObject.Parse(response);
wsresult.Text = "okay";
return resultObj;
}
catch(Exception Ex) {
wsresult.Text = Ex.Message.ToString(); return resultObj;
}
}
Try this
HttpResponseMessage response;
public async Task<string> webserviceResponse(string HttpMethod)
{
// check internet connection is available or not
if (NetworkInterface.GetIsNetworkAvailable() == true)
{
// CancellationTokenSource cts = new CancellationTokenSource(2000); // 2 seconds
HttpClient client = new HttpClient();
MultipartFormDataContent mfdc = new MultipartFormDataContent();
mfdc.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
string GenrateUrl = "your url";
if (HttpMethod == "POST")
{
response = await client.PostAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "PUT")
{
response = await client.PutAsync(GenrateUrl, mfdc);
}
else if (HttpMethod == "GET")
{
response = await client.GetAsync(GenrateUrl);
}
var respon = await response.Content.ReadAsStringAsync();
string convert_response = respon.ToString();
return convert_response;
}
else
{
return "0";
}
}
It is your use of dynamic types giving you the expection
dynamic resultObj = "";
This makes resultObj a string
resultObj = Newtonsoft.Json.Linq.JObject.Parse(response);
The you try and stick a class in it. I would recommend you parse the response in to a type.
Related
I have this code for recovering Http code and description, but Visual Studio says that WebRequest is obsolete and that I have to use HttpClient. I'm not familiar with HttpClient can you help me?
IConfigurationRoot config;
myRequest = WebRequest.CreateHttp($"{config["BASE_URL"]}{link}");
myResponse = (HttpWebResponse)myRequest.GetResponse();
Check_load($"{config["BASE_URL"]}{link}");
var code = ((int)myResponse.StatusCode);
var desc = myResponse.StatusDescription;
var client = new HttpClient();
var response = await client.GetAsync(url);
var statusCode = response.StatusCode;
var content = response.Content;
if(statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.Created){
//return something, error, description
}
Update
From comment #Charlieface pointed out where I haven't declared HttpClient as static field. To avoid creating instances of HttpClient every time it is called, the complete workground as below.
public class HttpHelper{
private static HttpClent client = new HttpClient();
public static async Task<string> GetAsync(string url)
{
var response = await client.GetAsync(url);
var statusCode = response.StatusCode;
var content = response.Content;
if(statusCode != HttpStatusCode.OK && statusCode != HttpStatusCode.Created)
{
//return something, error, description
//return $"error with status code: {statusCode}";
}
else
{
//return "success";
}
}
}
The use of HttpClient is very simple. See the code below
try
{
using (HttpClient client = new HttpClient())
{
var res = await client.GetAsync(url);
var response = await res.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<MyObject>(response);
// use the new data retreived...
}
}
catch (Exception)
{
responseMessage = new BadRequestObjectResult("error retreiving data");
}
This suppose your data are sent in JSON format
I'm trying to get API response by passing service url and json parameter. Url and Parameter passing properly to the requestAPI function, but doesn't give response from PostAsync method. Url is the API location, parameter is the Category Id. When I'm running same API in the browser, it gives correct response. But not in app.
This is requestAPI function.
public async Task<ResponseObject> requestAPI(string urlString, string jsonParameters)
{
await Task.Delay(2000); // NOTE: just to simulate a HTTP request over the wire
try
{
var json = JsonConvert.SerializeObject(jsonParameters);
HttpContent httpContent = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
if (true) // no issue here.
{
response = await client.PostAsync(urlString, httpContent);
}
else
{
response = await client.PutAsync(urlString, httpContent);
}
if (response.IsSuccessStatusCode)
{
Debug.WriteLine(#" TodoItem successfully saved.");
var returnVal = await response.Content.ReadAsStringAsync();
return new ResponseObject{
jsonString = returnVal,
isSuccess = true,
error = null
};
}
else
{
return new ResponseObject
{
jsonString = null,
isSuccess = false,
error = null
};
}
}
catch (Exception ex)
{
Debug.WriteLine(#" ERROR {0}", ex.Message);
return new ResponseObject
{
jsonString = null,
isSuccess = false,
error = null
};
}
}
Category Id comes from this method.
private async void loadBookList(string categoryId)
{
IsBusy = true;
if (CrossConnectivity.Current.IsConnected)
{
ResponseObject responseObject = await _apiService.requestAPI("http://192.168.0.35/kiyawamu-api/index.php/rest/V1/mobileappintegration/getbookdetailsbycategory", Convert.ToString(categoryId));
if (responseObject.isSuccess)
{
var jsonObject = JsonConvert.DeserializeObject<BookListJsonObject>(responseObject.jsonString);
CategoryBooks = new ObservableCollection<Book>(jsonObject.booksByCategory);
}
else
{
giveAlertForCommonError();
}
}
}
I tried following solutions, but doesn't work.
Url used as a uri var uri = new Uri(urlString);
jsonParameter also used as a string
GetAsync also used
Any assistance on this will be greatly appreciated.
If you're running it on Android and the code is in a PCL, try to add ModernHttpClient so you can use the native HttpClientHandler.
https://github.com/paulcbetts/ModernHttpClient
But I also recommend all to upgrade from PCL to .NET standard. If you do so you don't have to install a NuGet package to use HttpCliennt. And then you can select implementation of HttpClientHandler in project settings.
I am trying to connect a Xamarin.Forms portable app using REST service. I am using Visual Studio 2015 Enterprise Edition.
Rest Service is published locally which is running fine by url.
When I am trying to call my Rest service in application. It is throwing an exception:
{System.Threading.Tasks.TaskCanceledException} with "One or more errors occurred."
C# Code at ServiceWrapper.cs:
public async Task<string> GetData()
{
try
{
var client = new HttpClient(new NativeMessageHandler());
client.BaseAddress = new Uri("http://ipaddress/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("IRESTApi.svc/xml/12").Result;
string content = await response.Content.ReadAsStringAsync();
return content;
//using (var client = new HttpClient())
//{
// var result = await client.GetAsync("http://ipaddress/IRESTApi.svc/xml/12");
// return await result.Content.ReadAsStringAsync();
//}
}
catch (Exception ex)
{
var t = ex.Message;
return t;
}
}
I am trying above method using this reference in android device. Please help.
Try this one :D
public interface IGetData
{
Task<string> GetApiData();
}
public class GetData : IGetData
{
public async Task<string> GetApiData()
{
var client = new HttpClient();
var response = await client.GetAsync(string.Format("http://mysite/api/Data"));
var responseString = await response.Content.ReadAsStringAsync();
return responseString;
}
}
I'm currently using Pushbullet API and need to upload a file.
I can successfully get an upload url as specified in the docs using this method:
public static async Task<Uploads> GetUploadUrl(string file_name, string file_type)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Access-Token", AccessToken);
var json = new JObject
{
["file_name"] = file_name,
["file_type"] = file_type
};
var result = await client.PostAsync(new Uri(_uploadUrl, UriKind.RelativeOrAbsolute), new HttpStringContent(json.ToString(), UnicodeEncoding.Utf8, "application/json"));
if (result.IsSuccessStatusCode)
{
var textresult = await result.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Uploads>(textresult);
}
}
return null;
}
The problem is when I try to upload the file. I'm currently using this method:
public static async Task<bool> UploadFile(StorageFile file, string upload_url)
{
try
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
var content = new MultipartFormDataContent();
if (file != null)
{
var streamData = await file.OpenReadAsync();
var bytes = new byte[streamData.Size];
using (var dataReader = new DataReader(streamData))
{
await dataReader.LoadAsync((uint)streamData.Size);
dataReader.ReadBytes(bytes);
}
var streamContent = new ByteArrayContent(bytes);
content.Add(streamContent);
}
client.DefaultRequestHeaders.Add("Access-Token", AccessToken);
var response = await client.PostAsync(new Uri(upload_url, UriKind.Absolute), content);
if (response.IsSuccessStatusCode)
return true;
}
catch { return false; }
return false;
}
but I get a Http 400 error. What's the right way to upload a file using multipart/form-data in a UWP app?
HTTP 400 error indicates Bad Request, it means the request could not be understood by the server due to malformed syntax. In the other word, the request sent by the client doesn't follow server's rules.
Let's look at the document, and we can find in the example request it uses following parameter:
-F file=#cat.jpg
So in the request, we need to set the name for the uploaded file and the name should be "file". Besides, in this request, there is no need to use access token. So you can change your code like following:
public static async Task<bool> UploadFile(StorageFile file, string upload_url)
{
try
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
var content = new MultipartFormDataContent();
if (file != null)
{
var streamData = await file.OpenReadAsync();
var bytes = new byte[streamData.Size];
using (var dataReader = new DataReader(streamData))
{
await dataReader.LoadAsync((uint)streamData.Size);
dataReader.ReadBytes(bytes);
}
var streamContent = new ByteArrayContent(bytes);
content.Add(streamContent, "file");
}
//client.DefaultRequestHeaders.Add("Access-Token", AccessToken);
var response = await client.PostAsync(new Uri(upload_url, UriKind.Absolute), content);
if (response.IsSuccessStatusCode)
return true;
}
catch { return false; }
return false;
}
Then your code should be able to work. You will get a 204 No Content response and UploadFile method will return true.
I have a web request that is working properly, but it is just returning the status OK, but I need the object I am asking for it to return. I am not sure how to get the json value I am requesting. I am new to using the object HttpClient, is there a property I am missing out on? I really need the returning object. Thanks for any help
Making the call - runs fine returns the status OK.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var responseMsg = client.GetAsync(string.Format("http://localhost:5057/api/Photo")).Result;
The api get method
//Cut out alot of code but you get the idea
public string Get()
{
return JsonConvert.SerializeObject(returnedPhoto);
}
If you are referring to the System.Net.HttpClient in .NET 4.5, you can get the content returned by GetAsync using the HttpResponseMessage.Content property as an HttpContent-derived object. You can then read the contents to a string using the HttpContent.ReadAsStringAsync method or as a stream using the ReadAsStreamAsync method.
The HttpClient class documentation includes this example:
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Building on #Panagiotis Kanavos' answer, here's a working method as example which will also return the response as an object instead of a string:
using System.Text;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json; // Nuget Package
public static async Task<object> PostCallAPI(string url, object jsonObject)
{
try
{
using (HttpClient client = new HttpClient())
{
var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
if (response != null)
{
var jsonString = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<object>(jsonString);
}
}
}
catch (Exception ex)
{
myCustomLogger.LogException(ex);
}
return null;
}
Keep in mind that this is only an example and that you'd probably would like to use HttpClient as a shared instance instead of using it in a using-clause.
Install this nuget package from Microsoft System.Net.Http.Json. It contains extension methods.
Then add using System.Net.Http.Json
Now, you'll be able to see these methods:
So you can now do this:
await httpClient.GetFromJsonAsync<IList<WeatherForecast>>("weatherforecast");
Source: https://www.stevejgordon.co.uk/sending-and-receiving-json-using-httpclient-with-system-net-http-json
I think the shortest way is:
var client = new HttpClient();
string reqUrl = $"http://myhost.mydomain.com/api/products/{ProdId}";
var prodResp = await client.GetAsync(reqUrl);
if (!prodResp.IsSuccessStatusCode){
FailRequirement();
}
var prods = await prodResp.Content.ReadAsAsync<Products>();
What I normally do, similar to answer one:
var response = await httpClient.GetAsync(completeURL); // http://192.168.0.1:915/api/Controller/Object
if (response.IsSuccessStatusCode == true)
{
string res = await response.Content.ReadAsStringAsync();
var content = Json.Deserialize<Model>(res);
// do whatever you need with the JSON which is in 'content'
// ex: int id = content.Id;
Navigate();
return true;
}
else
{
await JSRuntime.Current.InvokeAsync<string>("alert", "Warning, the credentials you have entered are incorrect.");
return false;
}
Where 'model' is your C# model class.
It's working fine for me by the following way -
public async Task<object> TestMethod(TestModel model)
{
try
{
var apicallObject = new
{
Id= model.Id,
name= model.Name
};
if (apicallObject != null)
{
var bodyContent = JsonConvert.SerializeObject(apicallObject);
using (HttpClient client = new HttpClient())
{
var content = new StringContent(bodyContent.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
client.DefaultRequestHeaders.Add("access-token", _token); // _token = access token
var response = await client.PostAsync(_url, content); // _url =api endpoint url
if (response != null)
{
var jsonString = await response.Content.ReadAsStringAsync();
try
{
var result = JsonConvert.DeserializeObject<TestModel2>(jsonString); // TestModel2 = deserialize object
}
catch (Exception e){
//msg
throw e;
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return null;
}
The code below is to access your HttpResponseMessage and extract your response from HttpContent.
string result = ret.Result.Content.ReadAsStringAsync().Result;
Convert your json in a structure according with your business
In my case BatchPDF is a complex object that it is being populated by result variable.
BatchPDF batchJson = JsonConvert.DeserializeObject<BatchPDF>(result);
return batchJson;