C
C#9mo ago
Mekasu0124

✅ Index Outside Of Bounds System.Data.SQLite

UserModel: https://pastebin.com/wJBdA30Y LoginModel: https://pastebin.com/QYMHxMbT LoginViewModel: https://pastebin.com/XdS6P11W DatabaseEngine function in question: https://pastebin.com/ipgtkTLd I keep getting the error in the screen shot from the funciton in question on the line where I execute
while (reader2.Read())
{
// do some stuff
}
while (reader2.Read())
{
// do some stuff
}
and I don't know why. I have tried moving them to two separate while loops, and two separate model variables like
UserModel newUser = new();
LoginModel userLogin = new();

while (reader.Read()) { // do something }
while (reader2.Read()) { // do something }

UserModel foundUser = newUser;
foundUser.UserLogin = userLogin;
UserModel newUser = new();
LoginModel userLogin = new();

while (reader.Read()) { // do something }
while (reader2.Read()) { // do something }

UserModel foundUser = newUser;
foundUser.UserLogin = userLogin;
and I still got the error. Thanks in advance
No description
154 Replies
Jimmacle
Jimmacle9mo ago
it probably refers to the column names you're trying to read from the reader unrelated, but you shouldn't be doing this
catch (SQLiteException ex)
{
if (ex.ErrorCode == 12)
{
return new UserModel();
}
else
{
throw new SQLiteException(ex.Message);
}
}
catch (SQLiteException ex)
{
if (ex.ErrorCode == 12)
{
return new UserModel();
}
else
{
throw new SQLiteException(ex.Message);
}
}
just use throw; to rethrow the exception you already have there are also a lot of disposable objects you aren't disposing well, not a lot but the data readers
Buddy
Buddy9mo ago
Use GetFoo(), not indexer Foo being the datatype
Jimmacle
Jimmacle9mo ago
it also seems like you should be using a join instead of 2 queries
Mekasu0124
Mekasu0124OP9mo ago
that specifically was from where I was trying to error code value and return specific messages based on it. I'll just throw the exception. In response to
It probably refers to the column names you're trying to read from the reader
cmd2.CommandText = @"CREATE TABLE IF NOT EXISTS
[login] (
[Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Username] VARCHAR(2048),
[Password] VARCHAR(2048),
UNIQUE(Username)
)
";
cmd2.CommandText = @"CREATE TABLE IF NOT EXISTS
[login] (
[Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Username] VARCHAR(2048),
[Password] VARCHAR(2048),
UNIQUE(Username)
)
";
In my create database function, I create a table called login with columns Username and Password and in my code,
cmd2.CommandText = "SELECT Password FROM login WHERE Username=$un";
cmd2.Parameters.AddWithValue("$un", user.Username);
cmd2.CommandText = "SELECT Password FROM login WHERE Username=$un";
cmd2.Parameters.AddWithValue("$un", user.Username);
I read from login by Username for Password and in the screenshot, you'll see the information is there.
No description
Mekasu0124
Mekasu0124OP9mo ago
I have a basic understanding of using relative databases and that's about as far as it goes
Jimmacle
Jimmacle9mo ago
so you're selecting Password but trying to get a Username too
Mekasu0124
Mekasu0124OP9mo ago
I'm here to learn how to do better
Jimmacle
Jimmacle9mo ago
there is no Username column in the result set for that query
Mekasu0124
Mekasu0124OP9mo ago
no selecting Password where Username = userLogin.Username
Buddy
Buddy9mo ago
I hope password isnt in plain text - unrelated but important.
Jimmacle
Jimmacle9mo ago
that doesn't affect what i said you're only getting the passwords, not the usernames and passwords so reader2["Username"] doesn't make sense
Mekasu0124
Mekasu0124OP9mo ago
it should only be getting 1 password if the username is a match to the usernames in the table
Jimmacle
Jimmacle9mo ago
the error isn't about the number of records it's about trying to access a column that doesn't exist
Buddy
Buddy9mo ago
Check your query
Mekasu0124
Mekasu0124OP9mo ago
I do apologize. I'm really confused on how when in the screenshot of the database, you can see the table and columns and that I'm calling them correctly
Jimmacle
Jimmacle9mo ago
you're not you are doing SELECT Password... then expecting the results to contain both Username and Password if you want the username too, you need to SELECT Username, Password...
Mekasu0124
Mekasu0124OP9mo ago
ok so it should only be selecting the password given a username match, so how do I need to write it?
Jimmacle
Jimmacle9mo ago
really this should be one query:
select u.FirstName, u.LastName, u.EmailAddress, l.Password
from users u
left join login l on u.Username = l.Username
where u.Username = $un
select u.FirstName, u.LastName, u.EmailAddress, l.Password
from users u
left join login l on u.Username = l.Username
where u.Username = $un
you have no reason to read the username back from the database because that's what you're using as your filter in the where
Mekasu0124
Mekasu0124OP9mo ago
As per this, I've been trying to learn about salting passwords in C# in a playground and so far I've gotten to
using System;
using System.Security.Cryptography;
using System.Text;

class Program
{
static void Main()
{
string password = "your_password_here";

// Generate a 32-byte salt
byte[] salt = new byte[32];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetNonZeroBytes(salt);
}

// Convert salt to base64 string
string base64Salt = Convert.ToBase64String(salt);

// Concatenate salt with password
string saltedPassword = base64Salt + password;

// Compute hash
byte[] hash;
using (var sha256 = SHA256.Create())
{
hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(saltedPassword));
}

// Convert hash to base64 string
string base64Hash = Convert.ToBase64String(hash);

Console.WriteLine($"Base64 salt: {base64Salt}");
Console.WriteLine($"Base64 hash: {base64Hash}");
}
}
using System;
using System.Security.Cryptography;
using System.Text;

class Program
{
static void Main()
{
string password = "your_password_here";

// Generate a 32-byte salt
byte[] salt = new byte[32];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetNonZeroBytes(salt);
}

// Convert salt to base64 string
string base64Salt = Convert.ToBase64String(salt);

// Concatenate salt with password
string saltedPassword = base64Salt + password;

// Compute hash
byte[] hash;
using (var sha256 = SHA256.Create())
{
hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(saltedPassword));
}

// Convert hash to base64 string
string base64Hash = Convert.ToBase64String(hash);

Console.WriteLine($"Base64 salt: {base64Salt}");
Console.WriteLine($"Base64 hash: {base64Hash}");
}
}
but I wanted to get the login screen working first before hashing the password and dehashing the password as the functions to encrypt and decrypt the password will be going into an EncryptionGenerator class this just absolutely blew my mind. Would you mind to show me what this looks like in my code with like some comments explaining it? If not, then would you mind linking a tutorial I can look at?
Jimmacle
Jimmacle9mo ago
you put it in like any other query, then the result set you get back will have those 4 columns in it it makes the database engine do the work of matching up your users and logins and gives you just the data you need in a single go
Mekasu0124
Mekasu0124OP9mo ago
so like
cmd2.CommandText = @"select u.FirstName, u.LastName, u.EmailAddress, l.Password from users u left join login l on u.Username = l.Username where u.Username = $un";
cmd2.Parameters.AddWithValue("$un", userLogin.Username);
cmd2.CommandText = @"select u.FirstName, u.LastName, u.EmailAddress, l.Password from users u left join login l on u.Username = l.Username where u.Username = $un";
cmd2.Parameters.AddWithValue("$un", userLogin.Username);
Jimmacle
Jimmacle9mo ago
i wouldn't squish it into one line, but yeah
Mekasu0124
Mekasu0124OP9mo ago
ok I don't know how I would separate it
Jimmacle
Jimmacle9mo ago
use triple quotes
cmd2.CommandText = """
all
the
lines
""";
cmd2.CommandText = """
all
the
lines
""";
Mekasu0124
Mekasu0124OP9mo ago
yep lmao figured
Jimmacle
Jimmacle9mo ago
also in general you should avoid SELECT * specifying an explicit set/order of columns to get back will avoid bugs and receiving more data than you care about
Mekasu0124
Mekasu0124OP9mo ago
https://pastebin.com/8sQqRSZw how about this ok, sounds good to me, any examples?
Jimmacle
Jimmacle9mo ago
the query i just shared is one 😛
Mekasu0124
Mekasu0124OP9mo ago
but you said to avoid Select and that one uses select or am I missing the point
Jimmacle
Jimmacle9mo ago
no avoid SELECT * specifically
Mekasu0124
Mekasu0124OP9mo ago
ohhhh got you ^ ?
Jimmacle
Jimmacle9mo ago
it looks like you dropped my query in when you have to rewrite the whole method you should only have one query and read the data just from that using either the names in the SELECT list or by index
Mekasu0124
Mekasu0124OP9mo ago
I wasn't aware I had to change the function. sorry oh ok. let me see if i can do that. one sec
Jimmacle
Jimmacle9mo ago
when in doubt, $tias
Jimmacle
Jimmacle9mo ago
the compiler and runtime will be better at telling you it's wrong than me reading raw text on pastebin
Mekasu0124
Mekasu0124OP9mo ago
what about this https://pastebin.com/McrbAAvp Index was outside the bounds of the array on newUser.FirstName = reader["u.FirstName"].ToString(). So I did something wrong with the column names?
Jimmacle
Jimmacle9mo ago
i personally wouldn't use the column names at all, it's redundant you can get them with a 0 based index i'd get rid of the loop too since you're only expecting one result
Mekasu0124
Mekasu0124OP9mo ago
I need to get all the information since if the passwords match, I'm returning all the information otherwise I'm returning an emtpy model
Jimmacle
Jimmacle9mo ago
what does that have to do with the loop
Mekasu0124
Mekasu0124OP9mo ago
newUser.FirstName = reader[0];
newUser.FirstName = reader[0];
is this how you meant?
Jimmacle
Jimmacle9mo ago
No description
Jimmacle
Jimmacle9mo ago
https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlite.sqlitedatareader?view=msdata-sqlite-7.0.0 the loop is about number of rows, you only have one row so there's no reason to loop
Mekasu0124
Mekasu0124OP9mo ago
ok so how do I need to write it? Something like
var returnedData = cmd.ExecuteReader();

userName.FirstName = returneData[0];
var returnedData = cmd.ExecuteReader();

userName.FirstName = returneData[0];
?
Jimmacle
Jimmacle9mo ago
you renamed the reader for some reason? that's not what i'm suggesting look at the docs, specifically the part i screenshotted
Mekasu0124
Mekasu0124OP9mo ago
I'm trying ok I see the part that you specified but I don't know how to use it
Jimmacle
Jimmacle9mo ago
it's a method on SqliteDataReader
Mekasu0124
Mekasu0124OP9mo ago
ok so reader.GetString("u.FirstName"); ?
Jimmacle
Jimmacle9mo ago
you tell me, what do the docs say it accepts as an argument?
Mekasu0124
Mekasu0124OP9mo ago
integer so I'd assume then reader.GetString(0);
Jimmacle
Jimmacle9mo ago
right that index refers to the order the columns are in in your SELECT
Mekasu0124
Mekasu0124OP9mo ago
so it would be ordered like ["u.FirstName", "u.LastName", "u.EmailAddress", "l.Password"] or replace each one for its database value
Jimmacle
Jimmacle9mo ago
if you were to treat the columns as an actual array then yes, that's the order they'd be in
Mekasu0124
Mekasu0124OP9mo ago
ok so what step did I miss?
Jimmacle
Jimmacle9mo ago
where? reader.GetString(0); is right if you want to get the first name for the row
Mekasu0124
Mekasu0124OP9mo ago
ok so then how would I get the last name? reader.GetString(1);?
Jimmacle
Jimmacle9mo ago
yes, you'd index them just like you'd index an array
Mekasu0124
Mekasu0124OP9mo ago
oh ok. bet
Mekasu0124
Mekasu0124OP9mo ago
current code: https://pastebin.com/vSZnT29z I'm not sure what I am doing wrong at this point. I thought I understood everything you said
No description
Jimmacle
Jimmacle9mo ago
you still have to call Read() to advance the reader to the row even if it's not in a loop the reader starts "before" the first row if that makes sense
Mekasu0124
Mekasu0124OP9mo ago
do I do that on the GetString()?
Jimmacle
Jimmacle9mo ago
no, you do it like you were doing before
Mekasu0124
Mekasu0124OP9mo ago
oh ok
Jimmacle
Jimmacle9mo ago
just not in the loop
Mekasu0124
Mekasu0124OP9mo ago
reader.Read(); then read
Jimmacle
Jimmacle9mo ago
yeah
Mekasu0124
Mekasu0124OP9mo ago
reader = cmd.ExecuteReader();

try
{
reader.Read();

UserModel newUser = new()
{
FirstName = reader.GetString(0),
LastName = reader.GetString(1),
EmailAddress = reader.GetString(2),
UserLogin = new()
{
Username = user.Username,
Password = reader.GetString(3)
}
};

if (newUser != null)
{
return newUser;
}
else
{
return new UserModel();
}
}
reader = cmd.ExecuteReader();

try
{
reader.Read();

UserModel newUser = new()
{
FirstName = reader.GetString(0),
LastName = reader.GetString(1),
EmailAddress = reader.GetString(2),
UserLogin = new()
{
Username = user.Username,
Password = reader.GetString(3)
}
};

if (newUser != null)
{
return newUser;
}
else
{
return new UserModel();
}
}
ok so I did reader.Read() before the model but this time instead of an error being thrown or anything like that, it just did nothing
Jimmacle
Jimmacle9mo ago
what does "nothing" mean? did you put a breakpoint and see if it set the properties of newUser like you expected?
Mekasu0124
Mekasu0124OP9mo ago
so using breakpoints in the database file and the login view model, It obtained my login inputs and passed them to the database function just fine. It queried the database and obtained the wanted results just fine. I ran the program, it got, passed, obtained the wanted data to/from the database, but then returned a null object. Then I remembered that the models used Id's as well so I go back and add in the Id fields to both models, and now instead of it breaking at point 1/4 it just breaks at spot 4/4 and has a null user model returned. current code: https://pastebin.com/B1xgTx07
Mekasu0124
Mekasu0124OP9mo ago
ok so now I'm getting this issue
No description
Mekasu0124
Mekasu0124OP9mo ago
ok so upon further inspection, reader.Read(); get all the correct wanted values, however, when I attempt to obtain those values inside the models, it's now a null object. like when it breaks on reader.Read() the hasRows boolean is true, but then when I step over to the next breakpoint on the newUser user model, the hasRows property of reader.Read() is now false. Past this, I'm lost
leowest
leowest9mo ago
dont use getstring for everything if the type is a number say int reader have other methods i.e.: reader.GetInt32(index) its the same process of using GetString but u just choose the right method for the right type in the database does that make sense? https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlite.sqlitedatareader?view=msdata-sqlite-7.0.0#methods there is a list with all the options u have to use with the reader
Mekasu0124
Mekasu0124OP9mo ago
right. I saw that on the docs after posting my question. I changed it to doing so with the Id's on both models, however, I still have the same issue. The reader.Read() is getting the wanted values just fine, but when I try and put them into the models, they become null and I don't know why. I'm fixing to try and set each item from the database equal to <type> <variable> setup and then use the variables in the models
Mekasu0124
Mekasu0124OP9mo ago
see here, in screen shot #1, it has the wanted values, but in screenshot #2 no sooner than I say int userId = reader.GetInt32(0); it's now null.
No description
No description
Pobiega
Pobiega9mo ago
that makes sense if you ask me. Your result only contains one single row so when you call reader.Read() that row is read, and the result set contains no further rows
Mekasu0124
Mekasu0124OP9mo ago
so then how am I supposed to write it? I'm honestly confused lmao I thought I was doing it right by indexing the reader....
Pobiega
Pobiega9mo ago
lemme set up a test project real quick. Have not worked with raw ADO in many years
Mekasu0124
Mekasu0124OP9mo ago
haha ok. I just want to become a lot better at databases than I currently am. I'm only good enough to write to/pull information from a relative database, and you see how well that's going 😂
Pobiega
Pobiega9mo ago
we all gotta start somewhere 🙂 and learnign how to write SQL queries is good
Mekasu0124
Mekasu0124OP9mo ago
completely 100% side question. If I was to put advertisements into my application that only I ever used, and I let that application just run and run and run and it's loading ads every so few minutes or whatever and playing them, would I still get paid from the ads, or would that be illegal? lmao
Pobiega
Pobiega9mo ago
Sounds illegal but I'm not sure
Mekasu0124
Mekasu0124OP9mo ago
absolutely. I've been listening to this Talk Python to me podcast, and the most that I hear of what people are looking for (mind you this was back in 2015) is those who are excellent with linux servers, database queries and other workings, and basically all backend stuff
Pobiega
Pobiega9mo ago
using var connection = new SqliteConnection(connectionString);
connection.Open();

var command = connection.CreateCommand();
command.CommandText = "SELECT Id, Username, Password FROM Users WHERE Username = 'Pobiega'";

using var reader = command.ExecuteReader();
reader.Read();

var id = reader.GetInt32(0);
var username = reader.GetString(1);
var password = reader.GetString(2);

Console.WriteLine($"Id: {id}, Username: {username}, Password: {password}");
using var connection = new SqliteConnection(connectionString);
connection.Open();

var command = connection.CreateCommand();
command.CommandText = "SELECT Id, Username, Password FROM Users WHERE Username = 'Pobiega'";

using var reader = command.ExecuteReader();
reader.Read();

var id = reader.GetInt32(0);
var username = reader.GetString(1);
var password = reader.GetString(2);

Console.WriteLine($"Id: {id}, Username: {username}, Password: {password}");
this works just fine for me can you show the most recent command/reader code you have?
Mekasu0124
Mekasu0124OP9mo ago
https://pastebin.com/bRc0c5fr this is my entire database file.
Pobiega
Pobiega9mo ago
and what method are we looking at?
Mekasu0124
Mekasu0124OP9mo ago
I had nearly this exact thing before I moved onto the complicated query statement GetUser method.
Pobiega
Pobiega9mo ago
GetUser? k hm, that seems fine at a glance I'll emulate that database structure
Mekasu0124
Mekasu0124OP9mo ago
before I had the compound statement, I had
using SQLiteConnection conn = new(_dbFile);
using SQLiteCommand cmd = conn.CreateCommand();
using SQLiteCommand cmd2 = conn.CreateCommand();

SQLiteDataReader reader;

conn.open();

cmd.CommandText = @"SELECT * FROM users WHERE Username=$un";
cmd.Parameters.AddWithValue("$un", user.Username);

cmd2.CommandText = @"SELECT Password FROM login WHERE Username=$un";
cmd2.Parameters.AddWithValue("$un", user.Username);

try
{
reader = cmd.ExecuteReader();
reader2 = cmd.ExecuteReader();

UserModel newUser = new();
LoginModel userLogin = new();

while (reader.Read())
{
newUser.FirstName = reader["FirstName"].ToString(),
//rinse repeat for LastName and EmailAddress
}

while (reader2.Read())
{
userLogin.Password = reader2["Password"].ToString();
}

if (newUser != null && userLogin != null)
{
UserModel foundUser = newUser;
foundUser.UserLogin = userLogin;
return foundUser;
}
else
{
return new UserModel();
}
}
using SQLiteConnection conn = new(_dbFile);
using SQLiteCommand cmd = conn.CreateCommand();
using SQLiteCommand cmd2 = conn.CreateCommand();

SQLiteDataReader reader;

conn.open();

cmd.CommandText = @"SELECT * FROM users WHERE Username=$un";
cmd.Parameters.AddWithValue("$un", user.Username);

cmd2.CommandText = @"SELECT Password FROM login WHERE Username=$un";
cmd2.Parameters.AddWithValue("$un", user.Username);

try
{
reader = cmd.ExecuteReader();
reader2 = cmd.ExecuteReader();

UserModel newUser = new();
LoginModel userLogin = new();

while (reader.Read())
{
newUser.FirstName = reader["FirstName"].ToString(),
//rinse repeat for LastName and EmailAddress
}

while (reader2.Read())
{
userLogin.Password = reader2["Password"].ToString();
}

if (newUser != null && userLogin != null)
{
UserModel foundUser = newUser;
foundUser.UserLogin = userLogin;
return foundUser;
}
else
{
return new UserModel();
}
}
I had this before the complicated select statement that I have now and I was getting an out of bounds error on run-time when I would attempt to login to my app, however, after re-writing to what it is now in the GetUser function, I have the problems in the screenshots I provided before this conversation today and I can't figure out why the values go from being there in the reader.Read() to them suddenly being null on the next step which we've identified is an issue on how I'm reading the information from reader
Pobiega
Pobiega9mo ago
works absolutely fine here
var connectionString = "DataSource=sqlite.db";

using var connection = new SqliteConnection(connectionString);
connection.Open();

var command = connection.CreateCommand();
command.CommandText = """
SELECT u.Id, u.FirstName, u.LastName, u.EmailAddress, l.Id, l.Password
FROM Users u
LEFT JOIN Logins l
ON u.Username == l.Username
WHERE u.Username = $un
""";
command.Parameters.AddWithValue("$un", "Pobiega");

using var reader = command.ExecuteReader();
reader.Read();

var id = reader.GetInt32(0);
var firstName = reader.GetString(1);
var lastName = reader.GetString(2);
var email = reader.GetString(3);
var loginId = reader.GetInt32(4);
var password = reader.GetString(5);

Console.WriteLine($"Id: {id}, First Name: {firstName}, Last Name: {lastName}, Email: {email}, Login Id: {loginId}, Password: {password}");
var connectionString = "DataSource=sqlite.db";

using var connection = new SqliteConnection(connectionString);
connection.Open();

var command = connection.CreateCommand();
command.CommandText = """
SELECT u.Id, u.FirstName, u.LastName, u.EmailAddress, l.Id, l.Password
FROM Users u
LEFT JOIN Logins l
ON u.Username == l.Username
WHERE u.Username = $un
""";
command.Parameters.AddWithValue("$un", "Pobiega");

using var reader = command.ExecuteReader();
reader.Read();

var id = reader.GetInt32(0);
var firstName = reader.GetString(1);
var lastName = reader.GetString(2);
var email = reader.GetString(3);
var loginId = reader.GetInt32(4);
var password = reader.GetString(5);

Console.WriteLine($"Id: {id}, First Name: {firstName}, Last Name: {lastName}, Email: {email}, Login Id: {loginId}, Password: {password}");
only thing I changed was the table names wanna hop to #vc-2 and screenshare?
Mekasu0124
Mekasu0124OP9mo ago
yea we can this
Jimmacle
Jimmacle9mo ago
private const int SaltSize = 128 / 8;
private const int HashSize = 256 / 8;
private const KeyDerivationPrf Prf = KeyDerivationPrf.HMACSHA512;
private const int Iterations = 100000;

private static byte[] HashToken(string token)
{
var salt = RandomNumberGenerator.GetBytes(SaltSize);
var subkey = KeyDerivation.Pbkdf2(token, salt, Prf, Iterations, HashSize);
byte[] outputBytes = [..salt, ..subkey];
return outputBytes;
}

private static bool VerifyToken(string token, byte[] tokenHash)
{
var salt = tokenHash[..SaltSize];
var subkey = tokenHash[SaltSize..];
var testSubkey = KeyDerivation.Pbkdf2(token, salt, Prf, Iterations, HashSize);
return CryptographicOperations.FixedTimeEquals(subkey, testSubkey);
}
private const int SaltSize = 128 / 8;
private const int HashSize = 256 / 8;
private const KeyDerivationPrf Prf = KeyDerivationPrf.HMACSHA512;
private const int Iterations = 100000;

private static byte[] HashToken(string token)
{
var salt = RandomNumberGenerator.GetBytes(SaltSize);
var subkey = KeyDerivation.Pbkdf2(token, salt, Prf, Iterations, HashSize);
byte[] outputBytes = [..salt, ..subkey];
return outputBytes;
}

private static bool VerifyToken(string token, byte[] tokenHash)
{
var salt = tokenHash[..SaltSize];
var subkey = tokenHash[SaltSize..];
var testSubkey = KeyDerivation.Pbkdf2(token, salt, Prf, Iterations, HashSize);
return CryptographicOperations.FixedTimeEquals(subkey, testSubkey);
}
MODiX
MODiX9mo ago
arion
REPL Result: Success
Encoding.UTF8.GetBytes("hello")
Encoding.UTF8.GetBytes("hello")
Result: byte[]
aGVsbG8=
aGVsbG8=
Compile: 309.642ms | Execution: 19.890ms | React with ❌ to remove this embed.
arion
arion9mo ago
The client shouldn't have access to the database when the server is hosted somewhere Usually its like this (+ some more complicated steps for bigger projects) Client -> Web API -> Database
Jimmacle
Jimmacle9mo ago
https://github.com/Remora/Remora.Results
public record Result
{
public bool IsSuccess { get; init; } = true;

public bool IsFailure => !IsSuccess;
public string Message { get; init; } = string.Empty;
public static Result Ok() => new() { IsSuccess = true, Message = string.Empty };
public static Result Fail(string message) => new() { IsSuccess = false, Message = message };

public static bool operator true(Result result) => result.IsSuccess;
public static bool operator false(Result result) => result.IsFailure;

public Result<T> As<T>() => IsFailure ? Result<T>.Fail(Message) : throw new InvalidOperationException("Result has no value to convert.");
}

public record Result<T> : Result
{
private T _value = default!;

public T Value => IsSuccess ? _value : throw new InvalidOperationException("A failed result has no value.");

public static Result<T> Ok(T value) => new() { IsSuccess = true, Message = string.Empty, _value = value };
public new static Result<T> Fail(string message) => new() { IsSuccess = false, Message = message, _value = default! };

public static implicit operator Result<T>(T okValue) => Ok(okValue);
}
public record Result
{
public bool IsSuccess { get; init; } = true;

public bool IsFailure => !IsSuccess;
public string Message { get; init; } = string.Empty;
public static Result Ok() => new() { IsSuccess = true, Message = string.Empty };
public static Result Fail(string message) => new() { IsSuccess = false, Message = message };

public static bool operator true(Result result) => result.IsSuccess;
public static bool operator false(Result result) => result.IsFailure;

public Result<T> As<T>() => IsFailure ? Result<T>.Fail(Message) : throw new InvalidOperationException("Result has no value to convert.");
}

public record Result<T> : Result
{
private T _value = default!;

public T Value => IsSuccess ? _value : throw new InvalidOperationException("A failed result has no value.");

public static Result<T> Ok(T value) => new() { IsSuccess = true, Message = string.Empty, _value = value };
public new static Result<T> Fail(string message) => new() { IsSuccess = false, Message = message, _value = default! };

public static implicit operator Result<T>(T okValue) => Ok(okValue);
}
Mekasu0124
Mekasu0124OP9mo ago
so how would I apply that return style to this function?
internal static bool InsertNewLogin(LoginModel userLogin)
{
if (!File.Exists("main.db"))
{
CreateDatabase();
}

using SqliteConnection conn = new(_dbFile);
using SqliteCommand cmd = conn.CreateCommand();

conn.Open();

cmd.CommandText = @"INSERT INTO login(Username, Password) VALUES ($un, $pw)";
cmd.Parameters.AddWithValue("$un", userLogin.Username);
cmd.Parameters.AddWithValue("$pw", userLogin.Password);

try
{
cmd.ExecuteNonQuery();
return true;
}
catch (SqliteException)
{
throw;
}
}
internal static bool InsertNewLogin(LoginModel userLogin)
{
if (!File.Exists("main.db"))
{
CreateDatabase();
}

using SqliteConnection conn = new(_dbFile);
using SqliteCommand cmd = conn.CreateCommand();

conn.Open();

cmd.CommandText = @"INSERT INTO login(Username, Password) VALUES ($un, $pw)";
cmd.Parameters.AddWithValue("$un", userLogin.Username);
cmd.Parameters.AddWithValue("$pw", userLogin.Password);

try
{
cmd.ExecuteNonQuery();
return true;
}
catch (SqliteException)
{
throw;
}
}
Jimmacle
Jimmacle9mo ago
you can use the non-generic Result
Mekasu0124
Mekasu0124OP9mo ago
so just
...
cmd.Parameters.AddWithValue(..., ...);

cmd.ExecuteNonQuery();
return Result;
...
cmd.Parameters.AddWithValue(..., ...);

cmd.ExecuteNonQuery();
return Result;
? It's an insert function so it doesn't return anything but a t/f value or is a ternary thing. return Result.IsSuccess ? cmd.ExecuteNonQuery() : Result.Failure;
Jimmacle
Jimmacle9mo ago
look at the methods defined on it
Mekasu0124
Mekasu0124OP9mo ago
oh ok so
internal static Result InsertNewLogin(...)
{
...
try
{
cmd.ExecuteNonQuery();
return Result.IsSuccess("Successfully Wrote User To Database");
}
catch (SqliteException)
{
return Result.Fail("Error Writing Information To Database");
}
internal static Result InsertNewLogin(...)
{
...
try
{
cmd.ExecuteNonQuery();
return Result.IsSuccess("Successfully Wrote User To Database");
}
catch (SqliteException)
{
return Result.Fail("Error Writing Information To Database");
}
Pobiega
Pobiega9mo ago
return Result.Ok(); for the happy flow
Mekasu0124
Mekasu0124OP9mo ago
bet tyvm in my app.axaml.cs, how would I go about setting the application to the max_width and max_height of the screen it's being viewed on? Like a mainWindow.ShowMaximized() or something
arion
arion9mo ago
I don't this you can do this in the app.axaml.cs but you can do it for the individual windows eg.
arion
arion9mo ago
In the window axaml.cs you can also call WindowState = from code you could inherit the Window class to have it apply some logic beforehand, eg.
public abstract class MaximizedWindow : Window
{
protected MaximizedWindow()
{
WindowState = WindowState.Maximized;
}
}
public abstract class MaximizedWindow : Window
{
protected MaximizedWindow()
{
WindowState = WindowState.Maximized;
}
}
then your Windows inherit that instead of just : Window
Mekasu0124
Mekasu0124OP9mo ago
oh ok bet
Jimmacle
Jimmacle9mo ago
or just put that line in the constructor of the windows you want to start maximized that's really not what you should use inheritance for
Mekasu0124
Mekasu0124OP9mo ago
so I'd just put it in the code behind for the screen that I want to be maximized? That's every screen except for literally 1 😂 #copyAndPastFTW
Jimmacle
Jimmacle9mo ago
as someone who uses programs, i would be pretty annoyed if something kept opening fullscreen windows how many windows do you have? is there a reason you're not just replacing the content in a single window?
Mekasu0124
Mekasu0124OP9mo ago
as someone who uses programs, I would be pretty annoyed if something kept opening fullscreen windows
it's not a public application. I'm building it specifically for myself and I prefer full screen 🙂
how many window do you have?
right now, just the 1. I just started the project last night lol
is there a reason you're not just replacing the content in a single window?
I am lol I use the MainWindowView to display content. I bind it to a Content variable in the view model and I load each "screens" view model and display it when a function is called. Like
// MainWindowViewModel.cs

public partial class MainWindowViewModel : ViewModelBase
{
ViewModelBase _content = new();
[ObservableProperty]
private LoginModel _loggedInUser = new();

public MainWindowViewModel()
{
LoginScreen();
}

internal void LoginScreen()
{
var vm = new LoginViewModel();
Observable.Merge(
vm.Ok,
vm.Cancel
.Select(_ => (LoginModel)null));
.Take(1)
.Subscribe(model =>
{
if (model != null)
{
LoggedInUser = model;
HomeScreen();
}
}

Content = vm;
}

internal void HomeScreen()
{
var vm = new HomeScreenViewModel();
Observable.Merge(...);
Content = vm;
}
}
// MainWindowViewModel.cs

public partial class MainWindowViewModel : ViewModelBase
{
ViewModelBase _content = new();
[ObservableProperty]
private LoginModel _loggedInUser = new();

public MainWindowViewModel()
{
LoginScreen();
}

internal void LoginScreen()
{
var vm = new LoginViewModel();
Observable.Merge(
vm.Ok,
vm.Cancel
.Select(_ => (LoginModel)null));
.Take(1)
.Subscribe(model =>
{
if (model != null)
{
LoggedInUser = model;
HomeScreen();
}
}

Content = vm;
}

internal void HomeScreen()
{
var vm = new HomeScreenViewModel();
Observable.Merge(...);
Content = vm;
}
}
so it goes in the .axaml.cs file then? If yes, how should it be written?
arion
arion9mo ago
If we're still talking about the WindowState, it can be done in any of the views files, that being, .axaml or .cs if in cs, anywhere in the constructor (preferrably after InitializeComponent();) if in the .axaml file its just another parameter in the <Window > tag
<Window WindowState="Maximized">
... Your actual view
</Window>
<Window WindowState="Maximized">
... Your actual view
</Window>
(Something along those lines) You can also remove the window frame typically associated with most windows if you want (though there are reasons not to do that) The property is called "SystemDecorations" and the enum for that is "BorderOnly" or "None" There's also another thing you could do, thats to extend the window into the window area that would look like this:
arion
arion9mo ago
The property for that is ExtendClientAreaToDecorationsHint="True"
Mekasu0124
Mekasu0124OP9mo ago
what do you mean by
. . . extends the window into the window area?
arion
arion9mo ago
sry, meant more like, extends the UI into the window area like the screenshot
Mekasu0124
Mekasu0124OP9mo ago
so in my user control, if I set the usercontrol.background to blue it'll, extend the blue up to the top of hte window bar like the screenshot instead of having a white title bar and blue background user control?
arion
arion9mo ago
like this, the UI area is where the window decorations are
arion
arion9mo ago
i believe so
Mekasu0124
Mekasu0124OP9mo ago
oh ok
arion
arion9mo ago
lemme see what i did here on my event watcher window
Mekasu0124
Mekasu0124OP9mo ago
okie dokie
arion
arion9mo ago
yup, just set the background property
No description
Mekasu0124
Mekasu0124OP9mo ago
sweet tyvm
arion
arion9mo ago
:okHand:
Mekasu0124
Mekasu0124OP9mo ago
another question if you don't mind. I'm moving over from Avalonia.ReactiveUI to CommunityToolkit.Mvvm. I know how to do screen navigation in Avalonia.ReactiveUI by using Observable.Merge()'s, however, I can't find anything to show me how to do screen navigation using CommunityToolkit.Mvvm
arion
arion9mo ago
Personally, I've never used the Mvvm toolkit, i've never had a need for it Though speaking of Reactive, I am a big fan of System.Reactive, i love the IObservable extensions and most of the things relating to IDisposable of the package It's pretty close to one of my other favourite packages (Vanara.PInvoke xD)
Mekasu0124
Mekasu0124OP9mo ago
I just hate writing all the boiler code. I believe I can use them side by side that way I can keep the navigation that I'm used to using, and I don't have to write as much boiler plate code
arion
arion9mo ago
Doesn't Visual Studio have Live Templates? rider does, i use it to generate my avalonia boilerplate
Mekasu0124
Mekasu0124OP9mo ago
I have no idea. The only reason I'm even using Rider is because I updated Visual Studio to it's latest version and it broke the axaml previewer in the IDE and I can't figure out how to get it back. I've tried literally removing every installation and file/folder I could find on my system for Visual Studio and re-install and that didn't work. I tried to install 2019 alongside it, but the installer for 2019 kept saying that a newer version was installed so it can't install a later version. So again, i went through the entire computer and removed everything I could find of Visual Studio and Visual Studio 2022 and it still wouldn't work. restarted the computer multiple times, 2019 still kept detecting a newer version and refusing to download so I setup vscode for c# and avalonia development and that's fine, but I liked the simplicity of Visual Studio so I'm giving rider a try, but now I'm having the issue of my tags won't auto complete. In the axaml, if I type <Grid> and it just stays like that. it doesn't autocomplete the closing tag like vs and vscode do.
Mekasu0124
Mekasu0124OP9mo ago
I do but see in that snippet you have to select the component, but in visual studio I didn't have to do that. Once I pressed the > button to close the opening tag, it auto closed it for me
arion
arion9mo ago
Ah, yea I get the same issue on that. You could open an issue on their github to try to get that added
Mekasu0124
Mekasu0124OP9mo ago
I've honestly just been needing to wipe my computer and start over so that's what I just did lmao I'm going to download vs 2019 now and see what happens
Jimmacle
Jimmacle9mo ago
why not the latest version?
Mekasu0124
Mekasu0124OP9mo ago
because I like having the axaml previewer in the editor with me instead of every time I make a change, having to run/reload the project and wait for it to rebuild, etc.
Jimmacle
Jimmacle9mo ago
No description
leowest
leowest9mo ago
there is a project called avaloniahotreload if u can set it up and it runs u should get a nice hot reload the designer is really not good reference for the most part
leowest
leowest9mo ago
I just dont remember the github, I think its this one https://github.com/AvaloniaUI/Live.Avalonia
GitHub
GitHub - AvaloniaUI/Live.Avalonia: In-app live reload for Avalonia ...
In-app live reload for Avalonia applications. Contribute to AvaloniaUI/Live.Avalonia development by creating an account on GitHub.
Mekasu0124
Mekasu0124OP9mo ago
ok so maybe vs 2019 wasn't what I was thinking. VS 2022 is on version 17.9.6. How do I go to an earlier version of vs 2022? I don't see it on their downloads page
leowest
leowest9mo ago
Visual Studio
Free Developer Software & Services - Visual Studio
Free offers: Visual Studio Community, Visual Studio Code, VSTS, and Dev Essentials.
leowest
leowest9mo ago
left side one purple
Mekasu0124
Mekasu0124OP9mo ago
right. that's goign to download version 17.9.6. I need to find the VS 2022 version older than that for when the axaml previewer wasn't broken
leowest
leowest9mo ago
unless you're on preview which is 17.10.0 preview 3.0 axaml designer is not broken on latest only on preview and if it is as I have not tried mysefl
leowest
leowest9mo ago
GitHub
GitHub - Kir-Antipov/HotAvalonia: 🔥 Supercharge your Avalonia devel...
🔥 Supercharge your Avalonia development experience with hot reload capabilities - Kir-Antipov/HotAvalonia
leowest
leowest9mo ago
No description
Mekasu0124
Mekasu0124OP9mo ago
so i added this to my project, and omg it's pretty cool lol I'm cloning the repo for future use
leowest
leowest9mo ago
when it works is very helpful sometimes its wonky but I never had much issues with it
Mekasu0124
Mekasu0124OP9mo ago
right right ok so another question. To change the task bar icon of my avalonia application in visual studio, i'd just got to my project settings, scroll down to pick an image and that was it. However, I'm using VSCode. How do I do it from there?
leowest
leowest9mo ago
I dont use vscode so can't help u there sorry.
Mekasu0124
Mekasu0124OP9mo ago
what about in rider? found it
Mekasu0124
Mekasu0124OP9mo ago
right click project > Properties > Application > Resources > Application icon. It's right there bottom right as soon as you click properties
No description
Jimmacle
Jimmacle9mo ago
ultimately all of those settings are stored in the .csproj file, it might be beneficial to look those up so you don't have to rely on any built in IDE tools to change them
Mekasu0124
Mekasu0124OP9mo ago
oh I didn't know that. thanks!
Want results from more Discord servers?
Add your server