Model value not being set in Xamarin in iOS Only - ios

I am working on a Xamarin App where I am facing an issue.
Case 1:
Mode: Debug
Error: System.NullReferenceException: 'Object reference not set to an instance of an object'
Explanation:
No value is being set and passed to ViewModel, Controller.
Even I tried setting static values to variables and parameters.
LoginModel logtest = new LoginModel();
logtest.Username = "Test#user.com"; //uName;
logtest.Password = "2342534"; //pWord;
Tried solution:
In the beginning, I tried many different solutions nothing worked.
Then I create a new project and moved all the code to the new project, then it started working.
Case 2:
Mode: release
Now the same issue I am getting in release mode.
No value is being set and passed to ViewModels and Controller.
I have already tried moving code to a new project.
How can I resolve this? I am not sure is this a Visual studio issue or Xamarin issue or Apple.
I have tried updating Visual Studio enterprise 2019 and Xcode on Mac.
Deleted and recreated Provisioning Profiles and Signing Identities.
Code From LoginPage.xaml.cs
private async void LoginButtonClicked(object sender, EventArgs e)
{
await ((LoginViewModel)BindingContext).Login();
}
protected async override void OnAppearing()
{
//App.Current.MainPage = new Navigation(new DashboardPage());
//load the login page
Device.BeginInvokeOnMainThread(() =>
{
try
{
((LoginViewModel)BindingContext).IsLoading = false;
((LoginViewModel)BindingContext).RememberMe = DeviceStorage.RememberMe;
if (DeviceStorage.RememberMe == true)
{
((LoginViewModel)BindingContext).UserName = "Test#user.ca"; //Trying set static values here
((LoginViewModel)BindingContext).Password = "password"; //Trying set static values here
}
//RememberMeToggle.Toggled += switcher_Toggled;
((LoginViewModel)BindingContext).Load();
}
catch (Exception ex)
{
//logger.Error(App.LogPrefix() + "Error opening Navigation Page: " + ex.Message);
Console.WriteLine(App.LogPrefix() + "Error opening Load(): " + ex.Message);
}
});
}
Code from LoginViewModel.cs
public async Task Login()
{
IsLoading = true;
await TokenController.GetAuthorizationToken(UserName, Password);
}
Code from TokenController.cs
public static async Task GetAuthorizationToken(string uName, string pWord)
{
bool tokenReturned = false;
string tokenGetResponse = string.Empty;
// Have tried setting them static values as well
LoginModel logtest = new LoginModel();
logtest.Username = uName;
logtest.Password = pWord;
logtest.AppType = Constants.AppDetails.APP_CODE;
logtest.SystemCode = Constants.AppDetails.SYSTEM_CODE;
logtest.Push.PushSystem = PushAddressModel.PushSystemCode.FireBase;
logtest.Push.Address = ((App)App.Current).PushNotificationToken;
logtest.Push.AppCode = Constants.AppDetails.APP_CODE;
string uri = URI.message_Chat_Endpoint;
(tokenReturned, tokenGetResponse) = await ApiFunctions.Post(logtest, URI.token_Endpoint, false);
if (tokenReturned)
{
try
{
//deserialize the return object
TokenModel token = JsonConvert.DeserializeObject<TokenModel>(tokenGetResponse);
((App)App.Current).token = token;
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
//logger.Error(App.LogPrefix() + "Error: " + ex.Message);
}
Console.WriteLine("Profile Token loaded: " + ((App)App.Current).token.access_token);
}
else
{
Console.WriteLine("Error: Error loading profile token ");
//logger.Error(App.LogPrefix() + "Error loading profile token");
}
}

Related

How to update pin information on google map using xamarin

It is necessary to replace the direct connection to the database with API.
I use this code to directly connect to MySQL db and change pin information:
public async void DatabaseConnection(List<CustomPin> pins)
{
string ConnectionString = "server=192.168.0.1;uid=user;port=4444;pwd=pass;database=dbName;";
MySqlConnection Conn = new MySqlConnection(ConnectionString);
try
{
Conn.Open();
string query = "SELECT * FROM sel_alert_level s;";
MySqlCommand myCommand = new MySqlCommand(query, Conn);
MySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while (myReader.Read())
{
int codeNum = myReader.GetInt32(4);
int level = myReader.GetInt32(3);
int mapCode = myReader.GetInt32(0);
foreach (var item in pins)
{
if (item.CodeNum == codeNum)
{
item.AlertLevel = level;
item.CodeNum = codeNum;
item.MapCode = mapCode;
//await DisplayAlert("Alert", mapCode.ToString(), "ok");
}
}
//await DisplayAlert("Database Connection", "Connected .." + Environment.NewLine + myReader.GetInt32(0) + Environment.NewLine + myReader.GetString(1) + Environment.NewLine + myReader.GetString(2) + Environment.NewLine + myReader.GetInt32(3) + Environment.NewLine + myReader.GetInt32(4), "OK");
}
}
finally
{
myReader.Close();
Conn.Close();
}
}
catch (Exception ex)
{
await DisplayAlert("Database Connection", "Not Connected ..." + Environment.NewLine + ex.ToString(), "OK");
}
}
With this code I successfully update the pin information.
Now I create the same method with API Response and what to do the same like DatabaseConnection(); just try to update the information, but not work for me :(
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}
I not have any errors here. waterData come with the data, but data not changed in the pins.. I don't know why...
And Now my information are not changed ..
MapCode and other variables not changed.
I call this two methods in the constructor like that:
DatabaseConnection(customMap.CustomPins);
APIConnection(customMap.CustomPins);
So... When I start the project I receive message like this:
/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Microsoft.Common.CurrentVersion.targets(5,5): Warning MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. (MSB3276) (MaritsaTundzhaForecast.iOS)
And I check this link but I not have properties option, because I use mac. I have only options on the projects.
Is it possible that this does not change the content in the pins аnd what would be the reason it didn't work ?
I checked the if statement in the loop and she work:
Since it is an asynchronous method , I suggest you try to assign customMap.CustomPins in APIConnection method .
Something like that
//constructor
List<CustomPin> pins = xxxxx;
APIConnection(pins);
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
customMap.CustomPins = pins; //assign the value in this line
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}

Calling an ASP.Net web api from a ASP.Net MVC web app. MVC web client is not building the URL properly so getting not found

When I run my web api method using Postman passing in my URL, it works fine - it returns the value of '5' which I expect since the call returns just a single integer. Also at the very bottom I include another method of my web api that I run using Postman and it too works just fine.
http://localhost:56224/api/profileandblog/validatelogin/DemoUser1/DemoUser1Password/169.254.102.60/
However, in the client - an Asp.Net MVC method, when building the URL, it is DROPPING the "/api/profileandblog" part. Note: I'm using "attribute routing" in the web api.
Here is the Asp.Net MVC method to call the web api:
I stop it on this line so I can see the error details: if (result1.IsSuccessStatusCode)
It's INCORRECTLY building the URL as: http://localhost:56224/validatelogin/DemoUser1/DemoUser1Password/169.254.102.60/
It's dropping the: "/api/profileandblog" part that should follow 56224.
So it give's me the Not found.
Why does it drop it? It has the localhost:56224 correct.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SignIn(SignInViewModel signInViewModel)
{
int returnedApiValue = 0;
User returnedApiUser = new User();
DateTime currentDateTime = DateTime.Now;
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
try
{
if (!this.IsCaptchaValid("Captcha is not valid"))
{
ViewBag.errormessage = "Error: captcha entered is not valid.";
}
else
{
if (!string.IsNullOrEmpty(signInViewModel.Username) && !string.IsNullOrEmpty(signInViewModel.Password))
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224/api/profileandblog");
string restOfUrl = "/validatelogin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";
// Call the web api to validate the sign in.
// Sends back a -1(failure), -2(validation issue) or the UserId(success) via an OUTPUT parameter.
var responseTask1 = client.GetAsync(restOfUrl);
responseTask1.Wait();
var result1 = responseTask1.Result;
if (result1.IsSuccessStatusCode)
{
var readTask1 = result1.Content.ReadAsAsync<string>();
readTask1.Wait();
returnedApiValue = Convert.ToInt32(readTask1.Result);
if (returnedApiValue == -2)
{
ViewBag.errormessage = "You entered an invalid user name and/or password";
}
else
{
// I have the 'user id'.
// Continue processing...
}
}
else
{
ModelState.AddModelError(string.Empty, "Server error on signing in. 'validatelogin'. Please contact the administrator.");
}
}
}
}
return View(signInViewModel);
}
catch (Exception)
{
throw;
}
}
Per the suggestion about not having headers, I used another tutorial (https://www.c-sharpcorner.com/article/consuming-asp-net-web-api-rest-service-in-asp-net-mvc-using-http-client/) and it has the code for defining the headers. But it is coded slightly different - using async Task<> on the method definition. I was not using async in my prior version.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SignIn(SignInViewModel signInViewModel)
{
int returnedApiValue = 0;
User returnedApiUser = new User();
DateTime currentDateTime = DateTime.Now;
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
try
{
if (!this.IsCaptchaValid("Captcha is not valid"))
{
ViewBag.errormessage = "Error: captcha entered is not valid.";
}
else
{
if (!string.IsNullOrEmpty(signInViewModel.Username) && !string.IsNullOrEmpty(signInViewModel.Password))
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224/api/profileandblog");
string restOfUrl = "/validatelogin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Call the web api to validate the sign in.
// Sends back a -1(failure), -2(validation issue) or the UserId(success) via an OUTPUT parameter.
HttpResponseMessage result1 = await client.GetAsync(restOfUrl);
if (result1.IsSuccessStatusCode)
{
var readTask1 = result1.Content.ReadAsAsync<string>();
readTask1.Wait();
returnedApiValue = Convert.ToInt32(readTask1.Result);
if (returnedApiValue == -2)
{
ViewBag.errormessage = "You entered an invalid user name and/or password";
}
else
{
// I have the 'user id'.
// Do other processing....
}
}
else
{
ModelState.AddModelError(string.Empty, "Server error on signing in. 'validatelogin'. Please contact the administrator.");
}
}
}
}
return View(signInViewModel);
}
catch (Exception)
{
throw;
}
}
It now has a header but still NOT building the URL properly as it is not including the "/api/profileandblog" part.
Here is the web api and the method being called:
namespace GbngWebApi2.Controllers
{
[RoutePrefix("api/profileandblog")]
public class WebApi2Controller : ApiController
{
[HttpGet]
[Route("validatelogin/{userName}/{userPassword}/{ipAddress}/")]
public IHttpActionResult ValidateLogin(string userName, string userPassword, string ipAddress)
{
try
{
IHttpActionResult httpActionResult;
HttpResponseMessage httpResponseMessage;
int returnValue = 0;
// Will either be a valid 'user id" or a -2 indicating a validation issue.
returnValue = dataaccesslayer.ValidateLogin(userName, userPassword, ipAddress);
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, returnValue);
httpActionResult = ResponseMessage(httpResponseMessage);
return httpActionResult;
}
catch (Exception)
{
throw;
}
}
}
}
Here's the network tab of the client browser before I hit the button to fire of the Asp.Net MVC method.
The network tab of the client browser after I hit the button to fire of the Asp.Net MVC method and it fails.
Here's another example of Postman executing another method of my api just fine.
I got it to work by setting this as: client.BaseAddress = new Uri("localhost:56224"); and setting the string restOfUrl = "/api/profileandblog/validatesignin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";

Is it possible to switch wifi networks in Appium?

While executing my test suite I have to switch between different wifi networks available in Android Device.
In the middle of the execution I have to change my wifi connection from Wifi_Network_1 to Wifi_Network_2 provided ssid name and password of wifi network is known. How can it be done?
I am using:
Appium server -->1.8.1
java-client --> 6.1.0
selenium-java --> 3.13.0
Since NetworkConnectionSetting has been deprciated, I am not able to find alternate for it.
I can toggle wifi on/off using
driver.toggleWifi();
But it is not suitable for my case as i need to toggle between different wifi network available using SSID name and its password.
Thanks in advance.
Hi I'am using this method due Appium deprecated their switch for wifi, and I've created my own override via console via commands from adb. It is working for me so give it a try:
public synchronized boolean wifiSetup(String udid, boolean flg) {
synchronized (this) {
String flgEnabled = (flg) ? "enable" : "disable";
List<String> output = Console.runProcess(false, "adb -s " + udid + " shell am broadcast -a io.appium.settings.wifi --es setstatus " + flgEnabled);
for (String line : output) {
System.err.println(line);
if (line.equalsIgnoreCase("Broadcast completed: result=-1"))
return true;
}
return false;
}
}
usage to switch off:
wifiSetup("xxxUDIDfromAndroid", false);
usage to switch on:
wifiSetup("xxxUDIDfromAndroid", true);
And here is part for calling console:
public class Console {
private static final String[] WIN_RUNTIME = { "cmd.exe", "/C" };
private static final String[] OS_LINUX_RUNTIME = { "/bin/bash", "-l", "-c" };
private Console() {
}
private static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
#SuppressWarnings({ "hiding"})
private static <String> String[] concatStr(String[] first, String[] second) {
String[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
public static List<String> runProcess(boolean isWin, String... command) {
String[] allCommand = null;
try {
if (isWin) {
allCommand = concat(WIN_RUNTIME, command);
} else {
allCommand = concat(OS_LINUX_RUNTIME, command);
}
ProcessBuilder pb = new ProcessBuilder(allCommand);
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String _temp = null;
List<String> line = new ArrayList<String>();
while ((_temp = in.readLine()) != null) {
// system.out.println("temp line: " + _temp);
line.add(_temp);
}
// system.out.println("result after command: " + line);
return line;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Hope this helps,

How can i get HttpClient to work with NTLM in a pcl with android

have the following which works on Win10 phone in a pcl.
But i cannot get the same code to return OK on samsung s7 with android 7.0
project is xamarin forms.
nuget for system.net.http is 2.2.29.
I've include the same nuget in my UWP for the win10 phone and android projects.
i've also changed the user to include be "domain\user", "domain#user", "user#domain"
var httpClientHandler = new System.Net.Http.HttpClientHandler()
{
Credentials = credentials.GetCredential(new Uri(location), "NTLM")
};
I've tried and alternative to setting the httpClientHandler.Credentials.
var credentials = new NetworkCredentials("user", "pass", "domain");
var location = "http://apps.mysite.com/api#/doit";
var httpClientHandler = new HttpClientHandler{
Credentials = credentials
}
using (var httpClient = new HttpClient(httpClientHandler, true))
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
try
{
var httpResponseMessage = await httpClient.GetAsync(location);
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
{
//handle error
}
else
{
//do something
}
}
catch (Exception)
{}
finally
{}
}
another strange thing. when i run this on android, the code hits the await httpclient.getasync(location);
and the immediately jumps to the finally.
I hava a simple form with username & password Entry Fields, plus an OK button.
all three controls are bound to a viewmodel. the OK button via an ICommand.
this code and the view live in the PCL. which has a reference to Microsoft.Net.Http.
I have Android and Universal Windows Xamarin forms builds that consume the PCL.
Android Properties. Default httpClient, SSL/TLS Default. supported arch armeabi, armeabi-v7a;x86
Android Manifest: Camera, flashlight and internet
private bool calcEnabled = false;
private ICommand okCommand;
private string message = string.Empty;
private string validatingMessage = "Validating!";
private string unauthorizedMessage = "Invalid Credentials!";
private string authenticatedMessage = "Validated";
private bool validating = false;
public ICommand OkCommand => okCommand ?? (okCommand = new Command<object>((o) => clicked(o), (o) => CalcEnabled));
protected async void clicked(object state)
{
try
{
Validating = true;
Message = validatingMessage;
var credentials = new
System.Net.NetworkCredential(Helpers.Settings.UserName, Helpers.Settings.Password, "www.domain.com");
var location = "http://apps.wwwoodproducts.com/wwlocator#/information";
var httpClientHandler = new System.Net.Http.HttpClientHandler()
{
Credentials = credentials.GetCredential(new Uri(location), "NTLM") };
using (var httpClient = new System.Net.Http.HttpClient(httpClientHandler))
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
try
{
var httpResponseMessage = await
httpClient.GetAsync(location);
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
{
Message = unauthorizedMessage;
}
else
{
Message = authenticatedMessage;
Messenger.Default.Send<bool>(true);
}
}
catch (Exception)
{
Message = unauthorizedMessage;
}
finally
{
Validating = false;
}
}
}
catch (Exception)
{
throw;
}
}

Getting NameResolutionFailure error

Unable to fetch data in Xamarin.Forms project. I have tried with the following code and is getting NameResolutionFailure error.
private const string BaseUrl = "http://intilaqemployees.azurewebsites.net/api/employeesapi";
public async Task<List<Employee>> GetEmployeesAsync()
{
var httpClient = new HttpClient();
try
{
var jsonResponse = await httpClient.GetStringAsync(BaseUrl).ConfigureAwait(false);
//The following line never gets executed
var employeesList = JsonConvert.DeserializeObject<List<Employee>>(jsonResponse);
return employeesList;
}
catch (AggregateException exception) { }
catch (Exception ex)
{
}
return null;
}
This is what I have tried so far
Have enable INTERNET in android manifest
Translating the host name to ip
Tried to set host directly by setting client.DefaultRequestHeaders.Host = "intilaqemployees.azurewebsites.net";
Putting the wifi off in emulator
Please note: Android emulator does not have any internet connectivity.
My problem solved by this code:
var client = new HttpClient {
BaseAddress = new Uri("http://1.2.3.4"),
DefaultRequestHeaders = { Host = "example.com" }
};

Resources