C
C#3mo ago
DaClownie

Handling exceptions when querying with EF

Looking for a little insight... so I'm just working through how to properly use EntityFramework, and I'm handling a simple login from a list of users from a database (yes I know the password should be hashed and salted, but i was going to handle that after. Just want it to work for now) My Users database has Id which is a BINARY(16) for a smaller method of storing GUID, and it has a virtual column it can reference for IdText which is the full version of the GUID in a string format. I'm passing the GUID string back to my application to use for future queries on courses or semesters in school bound to your user. My login is
public static async Task GetUserId(string username, string password)
{
await using (var context = new AppDbContext())
{
CurrentUser = context.Users.First(u => u.Username == username && u.Password == password).IdText;
}
}
public static async Task GetUserId(string username, string password)
{
await using (var context = new AppDbContext())
{
CurrentUser = context.Users.First(u => u.Username == username && u.Password == password).IdText;
}
}
The documentation says that it will return the first result matching the query or throw back an ArgumentNullException. How do I handle the exception? Or should I be using First? is there a better method similar to an Int32.TryParse which returns the value or silences the exception? or do I create my own TryParse method for my Users model that throws away the exception because the only exception would be if the User doesn't exist? And would I want to mix that into this function of GetUserId? or would I be better putting this inside the SubmitButton_OnClicked method? Sorry, this is probably a lot of ramblings I've never used Try in any of my prior programs so i'm reading on the best practices and looking at docs and I just don't want to develop bad habits.
26 Replies
Jimmacle
Jimmacle3mo ago
use FirstOrDefault and it will return null if there are no matching rows instead of throwing an exception, then you can check for null and handle it however you need to also a couple things 1. that sounds like a very convoluted way of storing IDs for no particular reason, why aren't you using a simple integer ID? 2. it seems like you're storing passwords in plain text, which is tolerable for school projects but you should absolutely not do that in normal projects - passwords need to be hashed and salted 3. if you only need the IdText, you can make your query more efficient by retreiving just that one field like
context.Users.Where(u => u.Username == username && u.Password == password).Select(u => u.IdText).FirstOrDefault()
context.Users.Where(u => u.Username == username && u.Password == password).Select(u => u.IdText).FirstOrDefault()
DaClownie
DaClownieOP3mo ago
1. I was thinking of trying to scale the project afterwards beyond the scope of a school project, and wanted to learn how to use GUID, store them, and also didn't want them sortable by the date of account creation based on privacy things but I could be misguided. If nothing else, its just a learning experience. But had an idea and figured I'd run with it. 2. passwords will definitely be salted and hashed later. I just haven't got to the stage of implementing that logic so plaintext storage is happening now, and then I could take the input from my user input fields for password and run it through my salt and has algorithm after and just pass that value in to the same function. 3. Thats a much cleaner way of handling that query, and also eliminates any sort of exception handling seeing as wrong userid and password could be a common problem, i probably don't want to be catching exceptions everywhere. Thanks for the input! the only users on this at the moment are my test accounts and admin accounts for the project, but plaintext storage won't be the final result when its turned in
Jimmacle
Jimmacle3mo ago
as for 1, guids are generally not recommended as primary keys because unless you're using sequential guids they cause performance issues compared to normal sequential IDs if you don't want to expose the actual values, you can use something like sqids for user-facing data
Jimmacle
Jimmacle3mo ago
Sqids (formerly Hashids) · Generate Short Unique IDs
Sqids is an open-source library that lets you generate short unique IDs from numbers. It supports 45 programming languages.
DaClownie
DaClownieOP3mo ago
would sequential guids be GUIDv7 (I believe that was what it was) that have the timestamp built into the value?
Jimmacle
Jimmacle3mo ago
yeah, though support for them in .NET doesn't exist quite yet afaik i think that's .NET 9
DaClownie
DaClownieOP3mo ago
Ah yea, thats where I saw it
Jimmacle
Jimmacle3mo ago
but that still has the problem of leaking account creation date information, actually moreso than an integer id since there is an actual timestamp encoded into the guid
DaClownie
DaClownieOP3mo ago
right So would I just store a seperate column for the Sqid? or would it be something generated after my query to obtain the userid searching a db for a sqid is probably cancelling the efficiency of using integers in the first place
Jimmacle
Jimmacle3mo ago
the sqid would be calculated in the application on the fly it's just a way to encode the ID in a way that isn't the actual ID
DaClownie
DaClownieOP3mo ago
Just wanted to circle back and say that the query worked perfect, and just handling the public static string? CurrentUser; for null values was much easier than any sort of exception handling. Now I can just interact with the UI to show some red text saying invalid login or password and leave them at the login screen. I appreciate it, plus the other discussions! I kept the sqid tab open to do more reading
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
DaClownie
DaClownieOP3mo ago
Where would you store a password then?
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Jimmacle
Jimmacle3mo ago
tebe we already covered this
DaClownie
DaClownieOP3mo ago
oh, its about the plaintext part. Yea, I mentioned that i was going to do some salt and hash of the passwords, its just not the issue i'm focusing on now And honestly, multiple reminders about the importance of proper password storage isn't the worst anyway. With all these breaches lately, having this beat into my head is fine :kek:
Jimmacle
Jimmacle3mo ago
we just see people make that mistake a lot and many of them don't know there's a proper way to do it :LUL:
DaClownie
DaClownieOP3mo ago
I know about salt and hash, and i'm sure there's many libraries that will handle the inner workings for me. I think i even have a tab open for one talking about the recommended algorithm for hashing etc. lemme look
DaClownie
DaClownieOP3mo ago
GitHub
GitHub - therealmagicmike/PBKDF2.NET: Provides adaptive password-ba...
Provides adaptive password-based key derivation (PBKDF2) functionality for the .NET Framework allowing the use of any System.Security.Cryptography.HMAC-based hashing implementation, whether it&...
DaClownie
DaClownieOP3mo ago
That was the one I had sitting in my Arc browser still, but I wasn't sold on anything yet :kek:
Jimmacle
Jimmacle3mo ago
yeah identity uses pbkdf2, so it should be good enough
DaClownie
DaClownieOP3mo ago
will aspnetcore.identity work with maui? or is there an equivalent i'll need to use my app may turn into a web app in the future, school assignment side of it requires that it is a MAUI app for mobile deployment
Jimmacle
Jimmacle3mo ago
no, identity is specifically tailored for ASP.NET Core applications but basic user management isn't super complicated
DaClownie
DaClownieOP3mo ago
gotcha, figured Yea, for school purposes I just need encryption on passwords, secured database, and that meets the reqs. I'll be much more security focused when it moves to a web app. still not entirely sure what I'll use for that
Jimmacle
Jimmacle3mo ago
*hashing technically encryption is reversible if they tell you to use encryption they're wrong :KEKW:
DaClownie
DaClownieOP3mo ago
ah yes, thats what I meant. My reading on hashing mentioned it wasn't encryption. I thought they were synonymous ok, time to figure out the next steps for this app. I appreciate the chat again!
Want results from more Discord servers?
Add your server