我想為學校專案制作一個小而簡單的移動應用程式,我知道出于安全原因從手機連接到資料庫并不好,但基本上只有我會觸摸它。
因此,要將我的 Xamarin 應用程式連接到 Mysql,我下載了擴展程式 MysqlConnector ( https://www.nuget.org/packages/MySqlConnector/2.1.8?_src=template )
一開始似乎一切正常,但現在我認為他們的庫中存在與 Xamarin 不兼容的問題:
在 line reader = cmd.ExecuteReader(); 的第二個查詢中,我似乎總是得到一個空參考例外。我不知道為什么,沒有什么是空的,我已經列印了所有內容。(我已經在它發生的地方發表了評論)我嚴重懷疑這是他們圖書館的問題,因為他們總共有 3720 萬次下載。但也許這只是一個兼容性沖突,但這使得第一個查詢作業很奇怪。
這是我當前的所有代碼:
using PuppyChinoBestelling.Views;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
using MySqlConnector;
using System.Threading.Tasks;
namespace PuppyChinoBestelling.ViewModels
{
public class LoginViewModel : BaseViewModel
{
public Command LoginCommand { get; }
public string Mail { get; set; }
public string Pass { get; set; }
public LoginViewModel()
{
Pass = string.Empty;
Mail = string.Empty;
LoginCommand = new Command(OnLoginClicked);
}
private async void OnLoginClicked(object obj)
{
MySqlConnection conn = new MySqlConnection("private");
try
{
conn.Open();
Console.WriteLine("Conn opened!");
}
catch(Exception ex)
{
Console.WriteLine("Error " ex.Message);
}
string sql = @"SELECT * FROM users WHERE email = @email;";
var cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("@email", Mail);
var reader = cmd.ExecuteReader();
if (reader.HasRows)
{
sql = @"SELECT * FROM users WHERE email = @email;";
cmd = conn.CreateCommand();
cmd.Parameters.Clear();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("@email", Mail);
reader = cmd.ExecuteReader(); //null reference happening here idk why
string pwdHashed = reader.GetString(5);
bool validPwd = BCrypt.Net.BCrypt.Verify(Pass, pwdHashed);
conn.Close();
if (validPwd)
{
await Shell.Current.GoToAsync($"//{nameof(AboutPage)}");
}
else
{
Console.WriteLine("Foute logingegevens!");
}
}
else
{
Console.WriteLine("Je bestaat niet!");
}
}
}
}
提前致謝!
uj5u.com熱心網友回復:
很難確定,但問題可能是因為您沒有關閉閱讀器和命令,并且同一連接上不能有多個命令。
此外,您需要使用reader.Read.
在任何情況下,首先都不需要運行該命令兩次。您已經在第一次運行時獲得了所有資訊。
- 您還需要使用
using. 這會自動關閉連接。 - 不要
SELECT *,只需選擇您需要的列。 - 理想情況下,您將計算給定密碼的哈希值,并將其發送到資料庫服務器進行檢查,而不是從資料庫中提取真正的密碼哈希值(可能存在安全風險)。
- 不要將哈希存盤為字串。而是將它們存盤為具有
varbinary資料型別的二進制檔案,并byte[]在 C# 端進行轉換。 - 不清楚為什么您只為打開連接而不是執行命令來處理錯誤。
private async void OnLoginClicked(object obj) { const string sql = @" SELECT Pass FROM users WHERE email = @email; "; using (var conn = new MySqlConnection("private")) using (var cmd = new MySqlCommand(sql, conn)) { try { conn.Open(); Console.WriteLine("Conn opened!"); } catch(Exception ex) { Console.WriteLine("Error " ex.Message); return; // no point continuing } cmd.Parameters.AddWithValue("@email", Mail); using (var reader = cmd.ExecuteReader()) { if (!reader.Read()) { Console.WriteLine("Je bestaat niet!"); return; // no point continuing } string pwdHashed = (string)reader["Pass"]; conn.Close(); bool validPwd = BCrypt.Net.BCrypt.Verify(Pass, pwdHashed); if (validPwd) { await Shell.Current.GoToAsync($"//{nameof(AboutPage)}"); } else { Console.WriteLine("Foute logingegevens!"); } } } }
另一種方法是完全洗掉閱讀器并使用ExecuteScalar
private async void OnLoginClicked(object obj)
{
const string sql = @"
SELECT Pass
FROM users
WHERE email = @email;
";
using (var conn = new MySqlConnection("private"))
using (var cmd = new MySqlCommand(sql, conn))
{
try
{
conn.Open();
Console.WriteLine("Conn opened!");
}
catch(Exception ex)
{
Console.WriteLine("Error " ex.Message);
return; // no point continuing
}
cmd.Parameters.AddWithValue("@email", Mail);
string pwdHashed = cmd.ExecuteScalar() as string;
conn.Close();
if (pwdHashed is null)
{
Console.WriteLine("Je bestaat niet!");
return; // no point continuing
}
bool validPwd = BCrypt.Net.BCrypt.Verify(Pass, pwdHashed);
if (validPwd)
{
await Shell.Current.GoToAsync($"//{nameof(AboutPage)}");
}
else
{
Console.WriteLine("Foute logingegevens!");
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/480346.html
標籤:C# xamarin xamarin.forms xamarin.android
上一篇:如何在彈出視窗中隱藏外殼專案
下一篇:創建自定義滑塊
