hi,
I just started reading the book and attempting to use CSLA. Firstly, I must say it seems to be a great framework. Just trying to follow along with the book without getting too confused.
I have a few questions that I would like clarification on if possible.
Firstly, with authentication and authorization, along with using ASP.NET for the web interface. I want to be able to have both a Windows forms interface and a web interface, so I don't want the implementation to be specific to the web.
It spoke a bit about this in the book, in chapter 10 I believe, but it was a bit confusing and I was hoping for a bit more of an explanation.
Let's say I have a custom identity and principal, similar to that in the code examples. Let's also say I have a custom provider for forms authentication and membership in ASP.NET. How can I tie these two together, without making the identity and principal tied too closely or too specific to the web interface?
Second question:
More a matter of design. Let's say I have a list of categories and products. Products have a many to many relationship with the categories, but categories are also related to other categories, where one category may have several children categories.
The only way I could think of to solve the above would be using a switchable kind of class, where it is either a parent or a child. There obviously has to be at least one category with no parent. Further, say I'm on a page where the category ID was passed, I'd just want to fetch that particular category, along with its products.
However, the only thing is it'd be nice to retrieve the category's immediate parent, but I'm not sure how I'd go about doing this.
Any help is much appreciated.
if (Membership.ValidateUser(criteria.Username, criteria.Password))
{
_name = criteria.Username;
_isAuthenticated = true;
_roles = new List<string>(Roles.GetRolesForUser(_name));
}
hi,
thanks for the reply. I'm still trying to figure out exactly how it was done in the book. It seems the most flexible way really.
Also, any comments about the categories issue?
Thanks again.
hi,
OK, this isn't actually implemented in the PTWeb project, but it is talked about in the book I think somewhere around page 537.
So, it looks like using this method, there would actually be two principals? One that wraps IPrincipal, and one that is called by the membership provider, which is the one in the project library itself. Would this be correct?
Yes, exactly. You just create a custom principal that inherits from BusinessPrincipalBase, which delegates all its work to an underlying principal object that you obtain from the membership provider. Your custom principal's code isn't complex then, since IPrincipal only defines two members, and they both delegate to the underlying principal. Something like this:
<Serializable()> _
Public Class MyPrincipal
Private mMembershipPrincipal As IPrincipal
Public Sub New(membershipPrincipal As IPrincipal)
mMembershipPrincipal = membershipPrincipal
End Sub
Public Overrides Function IsInRole(role As String) As Boolean
Return mMembershipPrincipal.IsInRole(role)
End Function
Public Overrides ReadOnly Property Identity() As IIdentity
Get
Return mMembershipPrincipal.Identity
End Get
End Property
End Class
This may not be perfectly right, but it is close anyway. Then you follow the basic pattern in the book, where in global.asax and login.aspx, AFTER the user's identity has been determined by the membership service, you set the principal object to this object - passing the previous principal into the constructor.
The only real reason for wrapping the principal from membership services is so your principal can flow through the data portal. Note that this technique ONLY works if the original principal/identity objects are serializable - which the membership ones are (or were when I tested this while writing the book).
But what this means is that if your data portal is running in local mode then you don't need to worry about this at all, because the data portal would run in the "client" context and automatically has the same security. This is only important if you configure the data portal to be remote.
Ah, thanks for replying.
True, it only needs to be used when it'll use DataPortal remotely, but if it ever needs to be used like that, I really don't want to have to change any code. I want to make it as simple as possible.
RockfordLhotka:Yes, exactly. You just create a custom principal that inherits from BusinessPrincipalBase, which delegates all its work to an underlying principal object that you obtain from the membership provider. Your custom principal's code isn't complex then, since IPrincipal only defines two members, and they both delegate to the underlying principal. Something like this:
<Serializable()> _
Public Class MyPrincipal
Private mMembershipPrincipal As IPrincipal
Public Sub New(membershipPrincipal As IPrincipal)
mMembershipPrincipal = membershipPrincipal
End Sub
Public Overrides Function IsInRole(role As String) As Boolean
Return mMembershipPrincipal.IsInRole(role)
End Function
Public Overrides ReadOnly Property Identity() As IIdentity
Get
Return mMembershipPrincipal.Identity
End Get
End Property
End ClassThis may not be perfectly right, but it is close anyway. Then you follow the basic pattern in the book, where in global.asax and login.aspx, AFTER the user's identity has been determined by the membership service, you set the principal object to this object - passing the previous principal into the constructor.
The only real reason for wrapping the principal from membership services is so your principal can flow through the data portal. Note that this technique ONLY works if the original principal/identity objects are serializable - which the membership ones are (or were when I tested this while writing the book).
But what this means is that if your data portal is running in local mode then you don't need to worry about this at all, because the data portal would run in the "client" context and automatically has the same security. This is only important if you configure the data portal to be remote.
hi,
On membership:
The thing about the default membership implementation is firstly, it's hard to extend; to add any additional functionality you have to wrap Membership and add your own methods. Secondly, it complicates the business logic a bit. You can't quite have a Member business object, because there's already MembershipUser, so you can't use the business object class interface you do for other objects.
On categories:
Are you saying there'd be a RelatedCategories list as child to Category, and a RelatedCategory as child of that list? Still there can be multiple levels of categories. Unless RelatedCategory also has a child RelatedCategories list, but I'm not sure if there is anything wrong in doing that. Also most of the business logic would be duplicated, unless I have some generic Category class that wraps all data access common to both.
Also, however it is implemented, how could a category retrieve it's parent category? Would it be acceptable to have a _parentID field, and just a method, GetParentcategory(), which could call Category.GetCategory(_parentID);
bcdennis:re: Membership
Then I think your best solution would be to implement a custom membership & role provider for ASP, instead of using ASP as your membership provider for your CSLA application.
I presume you mean a membership provider, while still working within ASP.NET membership so it can use the login controls and such. Admittedly not the easiest way, but I can probably use this from project to project. Code reuse.
bcdennis:re: Categories
How's your underlying data modeled?
It's not, yet. I'm thinking something like:
CategoryID | ParentID | Name | Description | Image
devbanana:
I presume you mean a membership provider, while still working within ASP.NET membership so it can use the login controls and such. Admittedly not the easiest way, but I can probably use this from project to project. Code reuse.
The default membership provider for ASP is AspNetSqlMembershipProvider (which itself defaults to attaching a aspnet.mdf database file) and role provider is ASpNetSqlRoleProvider (which also houses its data in aspnet.mdf). You can change this to a custom membership & role provider that sources its data from your own tables which ASP will use for all the Forms Authentication stuff (including login controls.) To view this configuration, go to IIS management console. Right click on your virtual root and select "Properties". On the Service Properties dialog, click on the ASP.NET tab, then click "Edit Configuration". On the ASP.NET Configuration Settings dialog, click on the Authentication tab and you'll find the settings for the Membership Provider and Role Provider (to ASP). You can also manually edit the Web.config file accordingly.
devbanana:
It's not, yet. I'm thinking something like:
CategoryID | ParentID | Name | Description | Image
hi,
I don't need categories to have a many to many relationship with other categories, just a one to many. Each category has one parent, each category may have no, one, or many children.
So how would you organize the objects in this situation?
Thanks again.
hi,
The top category, it really wouldn't have a parent, only the child categories. Again, there should be multiple levels of child categories, or at least the option for there to be an unknown number of levels of child categories for each parent category.
These categories all act the same, just some are children and some are parents.
If there would be a parent field, would it just contain the ID of its parent, or the actual top category? I would think only the ID, as otherwise you'd have a nice loop of references going, lol.
Thanks again.
hi,
How about this?
Category is the root
ChildCategories is under that, and this holds ChildCategory objects
ChildCategories basically has the same definition but also has private string _parentID; and a GetParentCategory method.
Common behavior is delegated to a GenericCategory class.
Would this be OK?
Also, back to membership:
Can IPrincipal be serialized? I see no such attribute in the class definition in MSDN. I'm hoping it can, or that'll immensely complicate things.
hi,
Excellent.
Yes, I hope so. I'll have to test it so I can be sure.
This is my first project using CSLA, so I'm still ironing out some things.
By the way, this forum doesn't keep you logged in, even when you check the appropriate box. Quite annoying.
Copyright (c) Marimer LLC