I am using a membership provider that specifies required fields in user such as username and password. You can then inherit this user class to create your own user with any other fields you need.
I added an account like so
public Account AdminAccount { get; set; }
when i now get my user using the membershipprovider it does this:
return _context.Set<TUser>().SingleOrDefault(u => u.Username == username);
The class definition for this membership class looks like so
public class FlexMembershipUserStore<TUser>
: IFlexUserStore
where TUser: class, IFlexMembershipUser, new()
So I send in my user class when creating it, and the class knows about Tuser as a IFlexMembershipUser.
However IFlexMembershipUser does not have my AdminAccount property, only my class that inherits from IFlexMembershipUser has that.
And so when I fetch my user even tho he in the database has a field called AdminAccount_Id which is set correctly I only get AdminAccount to be null.
I see the problem of course with the membership only seeing IFlexMembershipUser and my property not existing on that class but other scalar values are read in properly.
Is there anything I can do about it.
In this particular case I can make the account keep track of it's admins as a user list instead. So I can solve this that way but I am still curious if this can be solved otherwise.
The issue here is that EF only loads things you tell it to for performance reasons. You have two options for loading the remote nav properties, Eager loading (my prefered) or lazy loading.
With Eager loading you tell EF at query time you are interested in the specific nav property and it will go ahead and load it for you. To do this:
using System.Data.Entity;
....
_context.Set<TUser>().Include(u=>u.AdminAccount).SingleOrDefault(u => u.Username == username);
Related
i am trying to implement repository pattern in mvc. but I am stuck. I want to return related data. I have two classes , tbl_Account (contains users )and tbl_Country (contains countries).
public class AccountRepository : IAccount
{
public IEnumerable<Account> GetCountry()
{
var Account = this.storeDB.tbl_UserAccount.Include(s => s.tbl_Country).ToList();
return Account; // it gives error here, saying explicit cast required
}
}
Account is a model class i have created on top of tbl_Account for field validations.
how to cast this or i am missing something else... please please help
1.) Variable name must start lower case.
2.) Method name 'GetCountry' but you return Account.
3.) After include you need to Select countries in account and then return countries.
4.) Please share your entities (model classes) in your question if you wanna get cool answers
Just a question to poll how you guys would tackle this in Laravel:
I have a user preferences page defined in UserController.php which creates the view at user/preferences.blade.php.
Administrators should of course be able to edit the user's preferences and have some extra administrative fields shown to be changed. Furthermore I'd like to collect all admin functionality concerning users in a separate controller called AdminUserController.php
I'm thinking of some possibilities to achieve this functionality:
Create an additional view (e.g. admin/user/preferences.blade.php) and almost replicate the GET and POST methods of UserController.php to accommodate the extra fields. However this seems to me like a lot of redundant code...
Convert the GET and POST methods of UserController.php to something like this:
public function postPreferences($user = NULL, $admin = FALSE) {
if (!isset($user)) $user = Auth::user();
// Process regular fields.
if ($admin) {
// Process admin fields.
}
}
Add the admin fields to user/preference.blade.php and conditionally show them if $admin is TRUE, and then call the UserController's methods from within AdminUserController, e.g.:
public function postPreferences($user) {
return (new UserController)->postPreferences($user, TRUE);
}
However, there are some drawbacks. First: controllers shouldn't call each other... Second: this only works for the POST method. Upon requesting the GET method from UserController an exception is being thrown...
I'm curious about how you would tackle this!
Thanks.
This is mostly a question of preference, but I really suggest you to completely separate all that is possible here. Administration is a process that is very sensitive and not in any way should it be possible, that a normal user will be able to see it under any circumstance.
I believe that we all are humans and we make mistakes more or less often, that's why we need to make sure that our mistakes in not assigning right value to the right variable or making a type of = instead of == not to ruin business logic.
I think you should make a separate view and a separate controller for user self management and administration and never tie them up. If you want to keep your code DRY as much as possible, you may extend your user controller and model from your admin controller and model, but not the other way around. That's just my 2 cents, it all depends on what type of application you are working on and what the stakes are.
<?php
class AdminController extends UserController
{
public function __construct(AdminModel $model)
{
// Use dependency injection
$this->model = $model;
}
// In the original UserController class:
public function postPreferences($user) {
$this->model->edit($user, Input::all());
// you may do it this way so your user only saves user data and
// you admin model saves all the data including administrative
}
// ...
}
how to save class extend in grails?
example i have class user and administrator
class User {
String name
String password
}
class Administrator extends User {
String authoritySelected
}
example in class User i have save "user1",
and then i want to change user1 from class user to class administrator and update authoritySelected
def update(){
def user1 = User.get("user1")
user1.authoritySelected
user1.save(flush:true)
}
and get error :
No such property: authoritySelected for class:User
so, how to save authoritySelected in class User and change that to class Administrator? thanks.
Speaking about the syntax, the code you wrote has no sense. Speaking about design, neither.
May I suggest you to study a bit a OOP before attempting doing this kind of stuff? :)
But let's face the problem you submitted.
First suggestion: don't implement the security system for your application, there's a lot of stuff that can do it for you. One above all: Spring Security plugin.
Second: the code you wrote doesn't work because extending a class is a way to make another class 'son' of the parent. In you example, Administrator is a son of User.
def update(){
def user1 = User.get("user1") // I don't get how this should work, but I'll leave it like this in this example
user1.authoritySelected // you're trying to GET the value a property that doesn't exist in the User class, you should SET something here
user1.save(flush:true)
}
If you want your User to change role, the easiest think is to think at the role not as another class, instead it should be an attribute of the User, so you can change it. Once the instance of a class is created, you can't change it (probably this is not totally true, but you shouldn't).
OK, some code:
class User {
String name
String password
String authority // a property of the class you can change
}
def update(){
def user1 = User.get("user1")
user1.authority = 'Administrator' // change the property on the instance you retrieved
user1.save() // save the instance itself
}
This is still not a good design solution to me, I'm just trying to make you able to see what you're doing wrong.
When you say "and then i want to change user1 from class user to class administrator", what exactly are you trying to do?
You are trying to access a property of an object that doesn't exist in that object. Downcasting simply doesn't work like that. You should instantiate an object of type Administrator in order to save one of its properties after.
if you want to create a USER you have to create an USER's instance, for example:
User u = new User(name: "xpto", password: "xptopass").save(flush:true)
An Administrator is a USER too, but with one more data, the authoritySelected, so if the Administrator extends User, he have the same data like a User too.
Administrator a = new Administrator(name: "xpto", password: "xptopPass", authoritySelected: "ADMIN").save(flush:true)
Attention, Object.get(X) methods needs an ID (Long), "X" would be a Long value, not a String.
http://grails.org/doc/2.3.x/ref/Domain%20Classes/get.html
this is really annoying
I have something like this:
class Person {
..properties id, name etc..
}
class Task {
..properties id, name etc..
Person Moderator {get;set}
}
public class DataModel : DbContext {
public DbSet<Task> Tasks { get; set; }
public DbSet<Person> People { get; set; }
}
I can then create new tasks and add People objects to the task and save, and I can see the data correctly saved in the sql backend - each Task saved has the correct Person id saved
with it and the Person with that id is saved back as well.
But when I try and get back a task, the person object is always null.
using (DataModel db = new DataModel()) {
Task t = db.Tasks.SingleOrDefault(p => p.Id == 22);
assert(t.Name.Lenght>0)
assert(t.Moderator != null) // always null!!!!!!
....
}
What do I have to do to get the whole object graph bought back? Do I have to do a join in the SingleorDefault call? seems a bit wrong somehow.
Did I mention this is really annoying.
TIA,
Two options for you. By default the code first / dbContext model returns a proxy object that derives from your model (this is important to understand when you run into JSON serialization issues). The proxy object uses lazy loading of associations but only under certain circumstances. The Moderator property has to be declared as virtual so that the proxy can override it and do the lazy loading for you.
However lazy loading can create a problem called Select N+1. If in most cases you only need the Task and not the Moderator, this won't be a problem. However if you frequently display a list of tasks and their associated moderators, you will effectively have to run an extra round trip to the database for every task in that list in addition to the 1 for the original list(e.g. for a list of 100 tasks you would do 101 queries to display the tasks and their moderators).
To get around this, EF provides the Include operator, this forces the relation to load. Use it as such
Task t = db.Tasks.Include(t=>t.Moderator).SingleOrDefault(p => p.Id ==
22);
Hope this helps.
You have lazy loading turned off for your Moderator property, so it will only be loaded if you explicitly do so using Load().
You can force EF to eagerly load your related Person entity by using the Include() method in your query like this:
Task t = db.Tasks.Include(x => x.Moderator).SingleOrDefault(p => p.Id == 22)
There is a pretty good overview in this article.
Hey guys, I'm starting with Zend, and trying to understand the way it works (getting there), and with Acl classes, people seem to declare all the roles and resources in one file. Now to me this seems a bit of a waste of system resources if the person is only logging in as a basic user, or even just a guest/visitor to the site. So I was thinking is it possible to have different classes which set the roles dependant on the role/resource of the current user.
My current idea is to use switch/case on the role in the bootstrap, and load individual Acl classes based on the role name (for example sake, 'visitor' => 'Model_VisitorAcl', 'users' => 'Model_UserAcl' and 'admin' => 'Model_AdminAcl'), each with a corresponding class file. Then within the class files do something for each one. This is working, and currently I could define all my 'admin' acls in one (backtracking through the rights heirarchy of admin-user-visitor), then in 'user' have 'user'-'visitor' roles and resources.
However this doesn't seem the best way, as if I wanted to change the role permissions for 'user' I'd need to change it for 'user' and 'admin'. This is obv not a problem with 2 roles, but on bigger systems it obviously is.
So I tried something like
class Model_AdminAcl extends Zend_Acl{
function __construct(){
$d = new Model_UserAcl();
//defining the admin role and permissions, with inheritance from the roles
//set in Model_UserAcl
}
}
To try and get the Model_UserAcl construct function to run, thus setting the role 'user', however this does not seem to work, throwing "Uncaught exception 'Zend_Acl_Role_Registry_Exception' with message 'Parent Role id 'users' does not exist'"
error.
So whats the next step? Having individual include files for each module, and have the required classes include them as needed?
Or am I just making mountain out of molehills with this issue?
Thanks,
Psy
Ok, solved this, not sure why I didn't think to try this in the first place (Friday brain frazzle I think)
I just put the contents of the constructor into its own function, and then called that function in the constructor, and make the classes inherit from the class below it.
//Model/VisitorAcl.php
class Model_VisitorAcl extends Zend_Acl{
function __construct(){
$this->addVisitorRules();
}
function addVisitorRules(){
//adding the role and permissions
}
}
//Model/UserAcl.php
class Model_UserAcl extends Model_VisitorAcl{
function __construct(){
$this->addVisitorRules();
$this->addUserRules();
}
function addUserRules(){
//adding the role and permissions
}
}
//Model/AdminAcl.php
class Model_AdminAcl extends Model_AdminAcl{
function __construct(){
$this->addVisitorRules();
$this->addUserRules();
$this->addAdminRules();
}
function addAdminRules(){
//adding the role and permissions
}
}
If this is not the way I should go about it, then by all means please let me know.
Psy