How to Call MVC web Controller from Xamarin Android App - android

string apiUrl1 = string.Format(#"http://xxx.xxx.x.xxx/test/Home/getdata?id=1");
public static string GetData(string url)
{
string Result = "";
try
{
using (WebClient client = new WebClient())
{
Result = client.DownloadString(string.Format(#"" + url + ""));
}
}
catch (Exception e)
{
string msg = e.Message;
Result = "";
}
return Result;
}
I am trying to get Data from my Published .Net MVC Web Project But i am getting Server Error "The remote server returned an error: (500) Internal Server Error."
My MVC Controller Code is Here
public JsonResult getdata(int? id)
{
List<Items> dbItems = Items.getItemsData(id);
return Json(dbItems, JsonRequestBehavior.AllowGet);
}

Besides the fact that you would probably be better suited using ASP.NET Web API (you wouldn't have to specifically convert your response to JSON on your controller), you can try something like below. As far as the server error, you would have to debug that server side.
public class RestClient
{
HttpClient client;
private string RestUrl = "http://192.168.1.103/test/Home/";
private static List<Items> _items = new List<Items>();
public RestClient()
{
client = new HttpClient();
client.MaxResponseContentBufferSize = 9999999;
}
public async Task<List<Item>> GetItems(int? id)
{
List<Item> items= new List<Item>();
var uri = new Uri(RestUrl + "getdata?id=" + id);
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
items= JsonConvert.DeserializeObject<List<Item>>(content);
_items.AddRange(items);
}
else
{
//do something
}
return _items;
}
}

Related

Xamarin WebService Localhost

I'm developing a project with Xamarin. I'm trying to bring data with Android Web Service. The WebService is running. The data comes to Local. But the androide doesn't come.
public partial class ListData : ContentPage
{
private HttpClient client;
URL url;
Connection cnn;
public ListData()
{
InitializeComponent();
client = new HttpClient();
cnn = new Connection();
}
async void btnEkle_Clicked(object sender, System.EventArgs e)
{
URL url = new URL("https://localhost:44364/api/values");
client.BaseAddress = new Uri(url.ToString());
var yanit = await client.GetAsync(url.ToString());
var jsondata = yanit.Content.ReadAsStringAsync().Result;
var root = JsonConvert.DeserializeObject<List<User>>(jsondata);
}
}

Is Newtonsoft.JSON supported for .net Framework 4.6 in Xamarin.Android?

I'm consuming WCF based web services for an android app. Previously the web application (for which webservices have been written) was using .NET framework 3.5, recently it was migrated to .net framework 4.6. The below pieces of code are throwing the exception :
"Error: NameResolutionFailure at
System.Net.HttpWebRequest.EndGetResponse"
url = https://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1
private async Task<JsonValue> FetchErrAsync(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
return jsonDoc;
}
}
}
The webservices are up and running. Json format data is being displayed in a normal web browser, however from the android app, we are getting the above exception.
Note: This code was working fine when the web application was running on .NET framework 3.5
Is Newtonsoft.JSON supported for .net Framework 4.6 in Xamarin.Android?
Yes it is supported for .net Framework 4.6 in Xamarin.Android.
You can convert your stream to string and then use Newtonsoft.JSON to convert the string to object.
"Error: NameResolutionFailure at System.Net.HttpWebRequest.EndGetResponse"
This error is not about the Newtonsoft.JSON, it is about the network environment. By testing your url . (https://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1), I find the secure issue with certificate, I think you can try bypass certificate validation with the ServerCertificateValidationCallback, and try again.
I have get your json string successfully by following codeļ¼š
public class MainActivity : Activity
{
Button bt1;
TextView tv1;
TextView tv2;
TextView tv3;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
bt1 = FindViewById<Button>(Resource.Id.button1);
tv1 = FindViewById<TextView>(Resource.Id.textView1);
tv2 = FindViewById<TextView>(Resource.Id.textView2);
tv3 = FindViewById<TextView>(Resource.Id.textView3);
bt1.Click += Bt1_Click;
}
private async void Bt1_Click(object sender, EventArgs e)
{
await FetchErrAsync("http://121.242.223.199/SEZOnlineWebService/SezOnlineWebService.svc/FetchNumberOfSEZandUnits/1");
}
public bool MyRemoteCertificateValidationCallback(System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors in the certificate chain, look at each error to determine the cause.
if (sslPolicyErrors != SslPolicyErrors.None)
{
for (int i = 0; i < chain.ChainStatus.Length; i++)
{
if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
{
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
bool chainIsValid = chain.Build((X509Certificate2)certificate);
if (!chainIsValid)
{
isOk = false;
}
}
}
}
return isOk;
}
private async Task FetchErrAsync(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
//JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
//return jsonDoc;
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
tv1.Text = text;
var myFetchNumberOfSEZandUnitsResultguage = JsonConvert.DeserializeObject<MyFetchNumberOfSEZandUnitsResultguage>(text);
tv2.Text = myFetchNumberOfSEZandUnitsResultguage.FetchNumberOfSEZandUnitsResult[0].Key;
tv3.Text = myFetchNumberOfSEZandUnitsResultguage.FetchNumberOfSEZandUnitsResult[0].Value;
}
}
}
}
public class MyFetchNumberOfSEZandUnitsResultguage
{
public List<MyKeyValue> FetchNumberOfSEZandUnitsResult { get; set; }
}
public class MyKeyValue
{
public string Key { get; set; }
public string Value { get; set; }
}
screen shot :
To deserialize your response to a specific object you could use:
NewtonSoft.Json.JsonConvert.DeserializeObject<MyClass>(webResponseInString);
Also a big note: WCF isn't fully supported in the Xamarin stack, so be careful when using WCF.

Server error 500 in Retrofit during POST request

I have rest api designed in Slim 3. which stores the customer details in MySQL db. I am using Retrofit 1.9 to connect to webservice. I am receiving server error 500 where as same request working fine in POSTMAN.
//using retrofit
RestAdapter adapter = new RestAdapter.Builder().setEndpoint(Config.CUSTOMER_URL).build();
RegisterCustomer api = adapter.create(RegisterCustomer.class);
api.registerCustomer(custName.toString(),
phoneNumber.toString(),
address.toString(),
Config.API_KEY, new Callback<retrofit.client.Response>() {
#Override
public void success(retrofit.client.Response result, retrofit.client.Response response) {
BufferedReader reader = null;
String output = "";
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("customer result",result.getBody()+"##"+result.getStatus() +"##" +response.getBody().toString());
}
#Override
public void failure(RetrofitError error) {
Log.d("customer save fail ",error.getMessage());
}
});
Interface:
public interface RegisterCustomer
{
#FormUrlEncoded
#POST("/customer")
public void registerCustomer(
#Field("cust_name") String cust_name,
#Field("phone") String phone,
#Field("address") String address,
#Field("apikey") String apikey,
Callback<Response> callback);
}
My php code.
// Adding customer
// pass cust_name,phone,address and apikey
$app->post('/customer', function ($request, $response, $args) {
$_message = $request->getParsedBody();
$customer = new Customer();
$customer->cust_name = $_message['cust_name'];
$customer->phone = $_message['phone'];
$customer->address = $_message['address'];
$customer->apikey = $_message['apikey'];
$payload=[];
$customer->save();
if ($customer->id) {
$payload = ['cust_id' => $customer->id,
'cust_uri' => '/customer/' . $customer->id
];
return $response->withStatus(201)->withJson($payload);
}else {
return $response->withStatus(400);
}
});

writing to WCF post json from Android client and saving data to sql server 2008

I am facing problem when posting data through WCF service. I have hosted wcf service and working fine with my .net website but it is not working with my android client, I am unable to understand what is happening, Can anyone help me to resolve this problem? Here is my android and wcf code:
WCF Service:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare,UriTemplate = "insert")]
string InsertUserDetails(UserDetails userInfo);
}
public class UserDetails
{
string username = string.Empty;
string fname = string.Empty;
string lname = string.Empty;
string loc = string.Empty;
[DataMember]
public string UserName
{
get { return username; }
set { username = value; }
}
[DataMember]
public string FirstName
{
get { return fname; }
set { fname = value; }
}
[DataMember]
public string LastName
{
get { return lname; }
set { lname = value; }
}
[DataMember]
public string Location
{
get { return loc; }
set { loc = value; }
}
}
namespace CRUDWCFService
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public string InsertUserDetails(UserDetails userInfo)
{
string Message;
SqlConnection con = new SqlConnection("Data Source=192.168.1.99;Initial Catalog=database;User ID=sa;Password=zaeveypws21");
con.Open();
SqlCommand cmd = new SqlCommand("insert into UserInformation(UserName,FirstName,LastName,Location) values(#UName,#FName,#LName,#Location)", con);
cmd.Parameters.AddWithValue("#UName", userInfo.UserName);
cmd.Parameters.AddWithValue("#FName", userInfo.FirstName);
cmd.Parameters.AddWithValue("#LName", userInfo.LastName);
cmd.Parameters.AddWithValue("#Location", userInfo.Location);
int result = cmd.ExecuteNonQuery();
if (result == 1)
{
Message = userInfo.UserName + " Details inserted successfully";
}
else
{
Message = userInfo.UserName + " Details not inserted successfully";
}
con.Close();
return Message;
}
}
}
Here is my Android code:
public void addListenerOnButton() {
Button btnCreateProduct = (Button) findViewById(R.id.btnInsert);
btnCreateProduct.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
Editable UserName = inputUName.getText();
Editable FirstName = inputFName.getText();
Editable LastName = inputLName.getText();
Editable Location = inputLoc.getText();
boolean isValid = true;
if (isValid) {
// POST request to <service>/insert
HttpPost request = new HttpPost("http://192.168.1.99/wcfinsert/Service1.svc/insert");
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
// Build JSON string
JSONStringer userInfo = new JSONStringer().object()
.key("userInfo").object().key("UserName")
.value(UserName).key("FirstName")
.value(FirstName).key("LastName")
.value(LastName).key("Location")
.value(Location).endObject().endObject();
StringEntity entity = new StringEntity(userInfo.toString());
request.setEntity(entity);
// Send request to WCF service
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
Log.d("WebInvoke", "Saving : "
+ response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
My logcat is:
03-22 12:23:55.397: D/dalvikvm(115): GC_EXTERNAL_ALLOC freed 424 objects / 21160 bytes in 233ms
03-22 12:24:01.748: D/WebInvoke(305): Saving : 415
03-22 12:26:43.081: D/SntpClient(59): request time failed: java.net.SocketException: Address family not supported by protocol
Thanks
Add the following into manifest
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
https://stackoverflow.com/a/8937348
https://stackoverflow.com/a/8307257/3366280

Android C2DM works with Web Service java-based, but 401 Error comes out if i try in a WS dotNet-based

i did a simple Web Service in Java and i deployed it in JBOSS 5.1.
This WS handles C2DM service for sending a notify message to an Android phone. I set all like i red in google c2dm api, and, first of all, i sign up for accessing to c2dm service. In this case, all works well.
Now i have to do the same in .NET on IIS7. Some clarification about the .Net code:
setRegId() and pushMessage() method are available by WebService.
handShakeRegId() is simply called by setRegId() after String "reg_id" and "device_id" are setted
all code commented are my try for solving problem, but all was useless
Thats the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Net;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace WebService1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
private String accountType = "HOSTED_OR_GOOGLE";
private String email = "example#gmail.com";
private String password = "password";
private String service = "ac2dm";
private String source = "com.cloudTest.app";
private String HTTPHeaderCT = "application/x-www-form-urlencoded";
private String auth;
private String reg_Id;
private String deviceId;
private String collapseKey = "CollapseKey";
public void handShakeRegId()
{
HttpWebRequest req;
Stream reqst;
try
{
req = (HttpWebRequest)WebRequest.Create(#"https://www.google.com/accounts/ClientLogin");
// string proxy = null;
// req.MaximumAutomaticRedirections = 4;
// req.MaximumResponseHeadersLength = 4;
// req.Credentials = CredentialCache.DefaultCredentials;
string data = String.Format("accountType={0}&Email={1}&Passwd={2}&service={3}&source={4}", accountType, email, password, service, source);
byte[] buffer = Encoding.UTF8.GetBytes(data);
// ASCIIEncoding encoding = new ASCIIEncoding();
// byte[] buffer = encoding.GetBytes(data);
req.Method = "POST";
req.ContentType = HTTPHeaderCT;
req.ContentLength = buffer.Length;
// req.Proxy = new WebProxy(proxy, true);
// req.CookieContainer = new CookieContainer();
reqst = req.GetRequestStream(); // add form data to request stream
reqst.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
Debug.WriteLine("--------------------");
Debug.Write("(handShakeRegId) Request Error:" + e);
Debug.WriteLine("--------------------");
throw;
}
HttpWebResponse res;
Stream resst;
try
{
res = (HttpWebResponse)req.GetResponse();
resst = res.GetResponseStream();
StreamReader sr = new StreamReader(resst, Encoding.UTF8);
string response = sr.ReadToEnd();
string SID = response.Substring((response.IndexOf("SID=") + 4),
(response.IndexOf("\n") - 4));//extracting SID
string Auth = response.Substring((response.IndexOf("Auth=") + 5),
(response.Length - (response.IndexOf("Auth=") + 5)) - 1);//extracting Auth
auth = Auth;
}
catch (Exception e)
{
Debug.Write("(handShakeRegId) Response Error:" + e);
throw;
}
resst.Flush();
resst.Close();
reqst.Flush();
reqst.Close();
}
[WebMethod]
public void setRegId(String reg_id, String device_id)
{
reg_Id = reg_id;
deviceId = device_id;
Debug.WriteLine("RegID=" + reg_Id);
Debug.WriteLine("--------------------");
Debug.WriteLine("DeviceID=" + deviceId);
handShakeRegId();
}
[WebMethod]
public void pushMessage(String msg)
{
// Needed! Without an SSL Exception comes out
System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate(object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; };
HttpWebRequest req;
Stream reqst;
try
{
req = (HttpWebRequest)WebRequest.Create("http://android.apis.google.com/c2dm/send");
//req.MaximumAutomaticRedirections = 4;
//req.MaximumResponseHeadersLength = 4;
//req.Credentials = CredentialCache.DefaultCredentials;
//req.Credentials = new NetworkCredential("example#gmail.com","password");
//req.KeepAlive = true;
//string proxy = null;
string data = String.Format("registration_id={0}&collapse_key={1}&data.message={2}", reg_Id, collapseKey, msg);
// ASCIIEncoding encoding = new ASCIIEncoding();
// byte[] buffer = encoding.GetBytes(data);
byte[] buffer = Encoding.UTF8.GetBytes(data);
req.Method = "POST";
req.ContentType = HTTPHeaderCT;
req.ContentLength = buffer.Length;
req.Headers.Add("Authorization", "GoogleLogin auth=" + auth);
// req.Proxy = new WebProxy(proxy, true);
// req.CookieContainer = new CookieContainer();
reqst = req.GetRequestStream(); // add form data to request stream
reqst.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
Debug.Write("(PushMessageMsgOUT)Error: " + e);
throw;
}
HttpWebResponse res;
Stream resst;
try
{
res = (HttpWebResponse)req.GetResponse();
HttpStatusCode responseCode = ((HttpWebResponse)res).StatusCode;
if (responseCode.Equals(HttpStatusCode.Unauthorized) || responseCode.Equals(HttpStatusCode.Forbidden))
{
Debug.WriteLine("Unauthorized - need new token");
}
else if (!responseCode.Equals(HttpStatusCode.OK))
{
Debug.WriteLine("Response from web service not OK :");
Debug.WriteLine(((HttpWebResponse)res).StatusDescription);
}
resst = res.GetResponseStream();
StreamReader sr = new StreamReader(resst);
string response = sr.ReadToEnd();
}
catch (Exception e)
{
Debug.WriteLine("(pushMessageMsgIN) Error: "+e);
throw;
}
resst.Flush();
resst.Close();
reqst.Flush();
reqst.Close();
}
}
}
Handshake method works well! I get auth token without problem.
setRegId method is called by Android device (in my case is the Android+GoogleApi 2.2 emulator)
Error which comes out is always the same in pushMessage getResponse() ( and its strange because i implement connection exactly like its in handshake method :-/ ):
A first chance exception of type 'System.Net.WebException' occurred in System.dll
(pushMessageMsgIN) Error: System.Net.WebException: remote server error (401) Unauthorized in System.Net.HttpWebRequest.GetResponse()
2 days for searching something useful but.... NOTHING!!
Its very stressful...
I hope someone can help me.
I red something about Authentication in IIS, so i enabled Anonymous User and other unknown things just for trying. Nothing!
Solved: MY STUPIDITY !!! i made a mistake in private String source !! I specified a wrong package name! -.-

Categories

Resources