Your question is the programming equivalent of asking if you should lock every door in your house.
In general, locking your doors is a good approach which everyone will recommend on principle, but if you start locking every single door in the entire house, you're going to end up frustrated and walking around your house is going to be slow and cumbersome.
There needs to be a line of reasonability here. Overdoing or underdoing it each come with their own drawbacks and you need to see what is relevant for you (it's mostly a conflict between strict access control vs easier development).
Inside the business layer, we use models to transfer data from classes to classes. Is it good practice to make these models and all their properties, methods and constructors internal?
Since the only purpose of the models is to travel around inside the same assembly, it makes sense to make these internal. Especially if these can be abused when exposed to consumers, but I surmise that this might not be the case for this particular scenario.
Is it good practice to make everything internal in C#?
Ehhh, I find it an arguable point. I definitely see the reasoning behind a "make everything internal by default" approach, but then again I also don't quite see the benefits gained from policing this in most projects I've worked on.
It's a matter of approach and a question of whether you find the effort of enforcing this rule to be worth the potential gains. Some considerations:
- There's no discernable benefit to doing it in small home projects that only you use.
- There's a notable benefit to doing it in projects that are exposed to consumers (it limits their access to things they actually care about).
- While it can be beneficial for the business (rigorous access control for security purposes) ...
- ... it can also be detrimental, e.g. incurring extra development time from developers who reinvent the wheel because they didn't know the wheel already existed somewhere else (as an internal). This might set a precedent for developers starting to look everywhere for something they need because it may have been hidden behind an internal access modifier. That sounds innocuous but if it becomes the standard it will be a drain on development time.
This is something you're going to have to evaluate for yourself. There is no "one approach fits all" solution here.