How to implement HttpGet for android client? - c#

I am developing client-server application. The server side is asp.net web api. I did simple web api application and simple android client. When I set up web api it works. And I get json. But how I can get data from my clietn application? I conncted my Android-device and trying to get data via WI-FI from my web api. For web api I create a seld hosting.
protected Boolean doInBackground(String... urls) {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://124.18.240.169:3890/api/values/1/");
HttpResponse response = client.execute(request);
in = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
It is my web api
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://124.18.240.169:3890");
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
where
124.18.240.160 is my IP whcih i found in ipconfig. What I should to do (I tried to do like
http://localhost) but it not wrok for Android app

You should consider using a library to help handle async callbacks. It can be super helpful for this.
This is the one I usually use:
LoopJ's Async HTTP Callback Library
This will handle GET and POST requests with a lot of cool features such as custom timeouts, JSON format, onSuccess() and onFailure() methods, etc. There's a lot of working examples of this library too. I've used it in all my apps and haven't had any problems yet!
Hopefully this helps.

Related

Problem Using user32.dll in C# (Error 1008 An attempt was made to reference a token that does not exist.)

Hello legendary coders.
Flowing by my previous question I tried to use user32.dll in windows universal application (UWP) in C# language but I encountered an error while trying to use the method I imported from that .dll
here is my code:
[DllImport("user32.dll")]
public static extern bool LockWorkStation();
private async void btnLock_Click(object sender, RoutedEventArgs e)
{
string path;
if (Images.TryGetValue(selectedRadioButton.Name, out path))
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
await LockScreen.SetImageFileAsync(file);
if (!LockWorkStation())
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
}
as you can see I imported LockWorkStation() mthod from user32.dll and I used it in the event listener of a button. the Images is a Dictionary<string,string> and every thing is Fine unless the call to method LockWorkStation() it always return false and so the thrown error is 1008 I mentioned it in the Title The question is Why? and how can I assign a token?
Note: any way,any way to lock the screen is admirable.
So after searching a lot and being hopeless from directly lock the screen from the universal windows application platform I send a web request to a local web server and I made that web server to use the user32.dll and lock the screen.
here is the code in the UWP app:
try
{
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("http://localhost:8080/lock/");
HttpStringContent content = new HttpStringContent(
"{ \"pass\": \"theMorteza#1378App\" }",
UnicodeEncoding.Utf8,
"application/json");
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
uri,
content);
httpResponseMessage.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw ex;
}
and there is the code in the web server:
[DllImport("user32.dll")]
public static extern bool LockWorkStation();
private static string LockTheScreen(HttpListenerRequest request)
{
var inputStream = request.InputStream;
try
{
using (StreamReader sr = new StreamReader(inputStream))
{
JToken pass = JToken.Parse(sr.ReadToEnd());
if (pass.Value<string>("pass") == "theMorteza#1378App")
{
LockWorkStation();
}
}
}
catch (Exception)
{
return "fail";
}
return "fail";
}
Note: you can find how to make a simple web server here
But: you must install the web server and grant it's access for users.

Lambda Function using c# cannot invoke external HTTPS APIs

I am trying to invoke External APIs from AWS lambda function written in c#. The Lamda function is deployed in No VPC mode. I am calling this function from Alexa skill. The code works fine for an http request, but its not working for https.
The below code works when I use http://www.google.com.
But, if I replace http with https, then I get the error in the cloud watch saying:
"Process exited before completing request."
Even the log written in catch is not getting logged in cloud watch.
public class Function
{
public const string INVOCATION_NAME = "bingo";
public async Task<SkillResponse> FunctionHandler(SkillRequest input, ILambdaContext context)
{
var requestType = input.GetRequestType();
if (requestType == typeof(IntentRequest))
{
string response = "";
IntentRequest request = input.Request as IntentRequest;
response += $"About {request.Intent.Slots["carmodel"].Value}";
try
{
using (var httpClient = new HttpClient())
{
Console.WriteLine("Trying to access internet");
//var resp=httpClient.GetAsync("http://www.google.com").Result // this works perfect!
var resp = httpClient.GetAsync("https://www.google.com").Result; // this throws error
Console.WriteLine("Call was successful");
}
}
catch (Exception ex)
{
Console.WriteLine("Exception from main function " + ex.Message);
Console.WriteLine(ex.InnerException.Message);
Console.WriteLine(ex.StackTrace);
}
return MakeSkillResponse(response, true);
}
else
{
return MakeSkillResponse(
$"I don't know how to handle this intent. Please say something like Alexa, ask {INVOCATION_NAME} about Tesla.",
true);
}
}
private SkillResponse MakeSkillResponse(string outputSpeech, bool shouldEndSession,
string repromptText = "Just say, tell me about car models to learn more. To exit, say, exit.")
{
var response = new ResponseBody
{
ShouldEndSession = shouldEndSession,
OutputSpeech = new PlainTextOutputSpeech { Text = outputSpeech }
};
if (repromptText != null)
{
response.Reprompt = new Reprompt() { OutputSpeech = new PlainTextOutputSpeech() { Text = repromptText } };
}
var skillResponse = new SkillResponse
{
Response = response,
Version = "1.0"
};
return skillResponse;
}
}
The issue was resolved by updating the library version.
System.Net.Http v4.3.4 was not completely compatible with dotnet core v1.
So outbound http calls were working but not https calls. Changing the version of System.net.http resolved the issue.

uploading of files

I am working on uploading files with a WCF web service,
here's my code for uploading:
public string UploadTransactionsFile(string uploadPath)
{
string uploadTransactionsFile;
if (String.IsNullOrEmpty(uploadPath))
return string.Empty;
if (!ValidateTransactionsFile(uploadPath))
return string.Empty;
try
{
var dir = #"C:\Upload\";
string myUploadPath = dir;
var myFileName = Path.GetFileName(uploadPath);
CheckDirectory(myUploadPath);
var client = new WebClient { Credentials = CredentialCache.DefaultCredentials };
client.UploadFile(myUploadPath + myFileName, "PUT", uploadPath);
client.Dispose();
uploadTransactionsFile = "ok";
}
catch (Exception ex)
{
uploadTransactionsFile = ex.Message;
}
return uploadTransactionsFile;
}
I created a Windows Forms test client and added the service reference, but
my code in calling the method and hardcoded the file i want to upload:
private testServiceClient testService;
private void Button_Click(object sender, RoutedEventArgs e)
{
var File = "C:\\file.csv";
testService = new testServiceClient();
testService.UploadTransactionFile(File);
}
I can upload files using one computer, but when I put my test client to another computer, then I can't, because the file is just passing the stringpath, which cannot be found on server computer.
Am I missing something?
Do I have to send my file as byte[]? If so, then how do I do this?
To stream files over HTTP to WCF service:
http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP
However, WebClient class is designed to be used on the client side too. So you could bypass the WCF service altogether.
From MSDN:
Provides common methods for sending data to and receiving data from a
resource identified by a URI.

Post request didn't pass parameter android to asp.net in IIS server

I am trying to trigger a create action in my ASP.NET web application from android.
The code seems to be working fine with no errors. I am using IIS 6 in Windows 7. I suspect a missing configuration in IIS?
I didn't get value in the web app.
Android Code:
List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("supplier_name",
"Thein Htike Aung"));
HttpClient client1 = new DefaultHttpClient();
HttpPost request =
new HttpPost("http://192.168.1.104/LogicUniversity/SupplierHandler.ashx");
try {
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
request.addHeader("Content-type", "application/x-www-form-urlencoded");
HttpResponse response = client1.execute(request);
BufferedReader in = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()));
String line;
String page="";
line = in.readLine();
while(line!=null)
{
page=page+line;
line=in.readLine();
}
Log.i("Page",page);
in.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
In Web Handler
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ApplicationLayer.Controllers;
using ApplicationLayer;
namespace PresentationLayer
{
/// <summary>
/// Summary description for SupplierHandler
/// </summary>
public class SupplierHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string name = context.Request.QueryString["supplier_name"];
if (name != null)
{
Supplier s = new Supplier();
s.supplier_name = name;
s.code = "TEST";
new SupplierController().actionCreateSupplier(s);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
You say that you're using a HTTP POST to push your value(s) to the server yet in your HTTP Handler you're reading from the query string:
string name = context.Request.QueryString["supplier_name"];
This should be:
string name = context.Request.Form["supplier_name"];
192.168.1.104 is specific to your local network. Your HTTPPost request, from the Andriod code, assumes that the Andriod device is on the same local network, is this your intention? This could be one of many causes on why your code work in development, and not production environment. You would need a Static IP configured on your web server to access the web service outside the local network.

Pre authenticate web service request in C#

I'm having a problem with calling a web service request in C#.
The service and request are working fine in Soap UI with the option 'Authenticate Preemptively' enabled (File, Preferences, HTTP Settings). Without this setting enabled the service returns a 'Java.Lang.NullPointerException'.
The problem I'm having is that I do not know how to enable this setting in a C# context.
I have a .NET 3.5 class library which holds a so called service reference to the specific service. This is a simple code snippet;
try
{
CatalogService.CatalogChangeClient service = new CatalogService.CatalogChangeClient();
service.ClientCredentials.UserName.UserName = "fancydress";
service.ClientCredentials.UserName.Password = "47fda9cb4b51a9e";
service.ClientCredentials.SupportInteractive = true;
ProductUpdate[] products = new ProductUpdate[1];
products[0] = new ProductUpdate();
products[0].ProductCode = "00001";
products[0].ProductDescription = "TestProduct";
string result = service.UpdateProducts(products);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
Update after first reply.
The CatalogService.CatalogChangeClient class seems to implement the WCF abstract class
System.ServiceModel.ClientBase<TChannel>
End Update
Could anyone help me set this property?
You could try and override the GetWebRequest method from your generated client stub. I have used this once and that solved my problem.
Look at the following URL:
http://www.eggheadcafe.com/community/wcf/18/10056093/consuming-webservices-and-http-basic-authentication.aspx
Scroll a bit down.
Here's the code from the link:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials =
Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(
networkCredentials.UserName + ":" +
networkCredentials.Password);
request.Headers["Authorization"] =
"Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}

Categories

Resources