I'm working on an ASP.NET solution with 2 projects. One is the web interface and the other contains my business logic. I'm using LINQ to SQL for my data access in the second project.
Apart of my database, I have a table called Users which holds user information.
I've started to implement a MembershipProvider. I notice that MembershipUser is coupled with MembershipProvider. What is the most correct way of getting my BLL/DAL to talk about Users?
Should I minimally implement MembershipUser and whenever a user calls a method, it will call for eg. GetUserInfo() in my BLL/DAL, to get complete information about the user?
Or should I make the MembershipUser class methods call my custom "Users" class methods (like a wrapper) in the BLL/DAL (this custom users class is not related to linq)?
Or can I somehow extend the Linq to sql class "CFUsers" to extend MembershipUser.
I hope this makes sense.
I usually see this a seperate entities as MembershipUser revolves around membership which is a generic concern and a user in your system revolves around whatever your domain entails, I do see your point of view where both these entities could be contained in one, so. Profiles is definitely the easiest way to go.
There's a walkthough on the MSDN docs at
http://msdn2.microsoft.com/en-us/lib...US,VS.80).aspx and a
good walkthrough from Scott Guthrie at
http://weblogs.asp.net/scottgu/archi...18/427754.aspx
As always It depends on what your goals are. Adding to Profile is a simple mechanism
for additional data. It requires very little in the way of customization and
makes the info easily available for the web application. This may not be
where you want to store this type of data; if not, it is a non-solution.
If this does not fit, making a new provider derived from the default (to
inherit what you already have) is a great option.
and of course the ultimate http://codesmart.wordpress.com/2009/03/27/extending-the-microsoft-aspnet-membership-provider/
Related
I have been reading about entity framework over the past couple of days and have managed to get a fair idea of using it but I still have a couple of questions some of which might seem a bit too basic. For perspective I am using entity framework 4.0 in an asp.net web application.If you can answer any of the questions please go ahead.
What advantage do I get by using POCO templates. I understand that if I wish to get persistence ignorance and keep my Entities clear of any information related to storage POCO entities are the way to go. Also I could switch from Entity framework to say NHibernate with relative ease when using POCO entities? Apart from loose coupling is there any significant reason for me to go towards POCO entities. Also if I do use POCO do I end up losing anything. I still get change tracking and lazy loading with the help of proxies?
Is it normal practice to use the Entities of the EF model as Data transfer Objects or Business Objects. i.e for example I have a separate class library for my entity model.Supposing I am using MVP , where I want a list of Employee's in a company. The presenter would request my business logic functions which would query the entity model for the list of Employee's and return the list of entities to the presenter. In this case my presenter would need to have a reference to the EF model. Is this the correct way? In the case of my asp.net web applciation it shouldnt be a problem but if I am using web services how does this work? Is this the reason to go towards POCO entities?
Supposing The Employee entity has a navigation property to a company table. If I use and wrap the data context in an 'using' block , and try to access the navigation property in the BL I am assuming I would get an exception. Would I also get an exception if I turned off lazyloading and used the 'include' linq query to get the entity? On a previous post someone recommended I use an context per request implying that the context remains active even when I am in the BL. I am assuming I would still need to detach the object and attach it to the context on my next request if I wish to persist any changes I make? or Instead should I just query for the object again with the new context and update it?
This question has more to do with organizing files/best practices and is a followup to a question i posted earlier. When I am using separate files based on entities to organize my data access layer, what is the best practice to organize my queries involving joins between multiple tables. I am still a bit hazy on organization. Have tried searching online but havent had much help.
Terrific question. My first recommendation is to think in patterns. With that said...
You pretty much nailed the advantages of using POCO. There are some distinct advantages to decoupling your business objects (POCO entities) from your data access layer. But the primary reason is like you said the ability to change or modify layers below. However using POCO you are essentially following the Code First (CF) approach. Personally, I consider it Code In Parallel depending upon your software development life cycle. You still have all the bells and whistles that data or model first approach have and some since you can extend the DbContext which is ObjectContext under the hood. I read an article, which I cannot seem to find, that CF is the future of Entity Framework. Lastly the nice thing with POCO is you are able to incorporate validation rules here or else where. You can also provide projections. Lets say you have Date of Birth but you want an Age property as well. That now becomes a no brainer as the Age property is ignored when mapping to the database.
Personally I create my own business objects (POCO) for large projects that tend to have a life of its own where change is a way of life. Another thought is scalability and maintainability. What if down the road I choose to split functionality between applications where, like you mentioned web services, functionality is now delivered from two disparate locations. If you have encapsulated your business objects and DAL within the same code block separation or scalability has now become a bit more complex. However, consider the project. It may be small with very little future change so no need to throw a grenade to kill a fly. At which time data first might be the way to go and let edmx file represent your objects. So don't marry yourself to one technology or one methodology/pattern. Do what makes sense for your time and business.
Using statements are perfectly fine. In fact I've recently been turned on to then wrapping that within a TransactionScope. If an error occurs rollbacks are inherent. Next, something to consider is the UnitOfWork. UnitOfWork pattern encapsulates a snapshot of what needs to be performed where the Data Context is the boundaries from which you work within. For each UnitOfWork you have a subject for which work is to be performed on. For example an Employee. So if you are to save Employee information to keep it simple you would make a call to the BL service or repository (which ever). There you pass in the Employee Id, perform some work under that UnitOfWork where it is either instantiated in the constructor or using Dependency Injections (DI or IoC). Easy starter is StructureMap. There the service makes the necessary calls to your UnitOfWork (DbContext) then returns control back upstream (e.g. UI).
The best way to learn here is to view others code. I'd start with some Microsoft examples. I'd start with Nerd Dinner (http://nerddinner.codeplex.com/) then build off that.
Additional Reading:
Use prototype pattern or not
http://weblogs.asp.net/manavi/archive/2011/05/17/associations-in-ef-4-1-code-first-part-6-many-valued-associations.aspx
[EDIT]
NightHawk457, I'm terribly sorry for not responding to your questions. Hopefully you figured it out but for future readers...
To help everyone visualize, imagine the below Architecture using the Domain Model and Repository as an example. Remember, there are many ways to skin a cat so take this and make it your own and don't forget my Grenade comment above.
Data Layer (Data Access): MyDbContext : DbContext, IUnitOfWork, where IUnitWork contracts the CRUD operations.
Data Repository (Data Access / Business Logic): MyDomainObjectRepository : IMyDomainObjectRepository, which receives IUnitOfWork by Factory class or Dependency Injection. Calls MyDomainObject validation on CRUD operations.
Domain Model (Business Logic): MyDomainObject using [Custom] Validation Attributes. Read this for pros/cons.
MVVM / MVC / WCF (Presentation / Service Layers): What ever additional layers you chose, you now have access to your data which is wrapped nicely in smaller modules who are self encapsulating of their function. The presentation layer (e.g. ViewModel, Controller, Code-Behind, etc.) can then receive an IMyObjectRepository by a Factory class or by Dependency Injection.
Tips:
Pass connection string into MyDbContext so you can reuse MyDbContext.
MySql does not play well with System.Transactions.TransactionScope, example. I don't recall exactly but it was something MySql did not support. This makes Testing a bit difficult since we have created this level of separation.
Create a Test project for each layer and at the minimum test general functionality/rules.
Each Domain Object should extend base object with ID field at minimum. Also do not implement Key attributes here. Domain Object should not describe architecture but rather the specific data as an entity. Even on Code First this can be achieved by the Fluent API.
Think generics when creating MyDbContext. ;) Read Diego's post.
In ASP.NET, the repositories are nice to use with ObjectDataSources.
As you can see, there is clear separation of roles where IUnitOfWork and IMyDomainObjectRepository are the Interfaces which expose the above layers functionality. And as an example, IUnitOfWork could be NHibernate, Entity Framework, LinqToSql or ADO.NET where a change to the factory class or dependency injection registration is all that has to change. FYI, I've heard the Repository called the Service Layer as well. Personally I like the first name to not be confused with Web Services. The next big take away from this structure is realizing the scope for you Database Context (IUnitOfWork). A simple example would be a ASP.NET page where for each page there is one and only one IUnitOfWork for either each repository or for that scope of work. Same holds true for ViewModels, Controllers, etc. So let's say you need to utilize two repositories, EmployeeRepository and HRRepository. You then could share the IUnitOfWork between both or not. To cross page, ViewModel or Controller boundaries, we use the ID for entities where they are then pulled from the DB and work is performed. You could alternatively pass a DTO across boundaries and attach to the context but then you begin losing separation of layers.
To continue, POCO classes do not have to be auto generated. In fact you can create your Entity Classes from scratch and perform the mapping in your extended DbContext class inside the OnModelCreating(DbModelBuilder mb) method. Start here, then here and note the Additional Resources, google Fluent API and read this post by Diego.
As for validation, this is an interesting point because it would be GREAT if all Business Rules could be validated in one location. Well, as we all know that doesn't work real well. So here is my recommendation, keep all data level validation (i.e. required, range, format, etc.) with data annotation as much as possible in the domain object and leave process validation in the Repository with clear roles of the Repository (i.e. if (isEmployee) do this, else that). I say clear, such that you do not want to add an Employee in two different Repositories where validation has to be duplicated. To call the validation, start here. Capture the ValidationResults and send upstream with a MyRepositoryValidationException which contains a collection of validations errors (e.g. Employee is required) which can be presented to the presentation layer. With all that said, don't forget to perform validation at the presentation layer. You don't want post backs to make sure an Employee has a valid Email, for example.
Just remember to balance time and effort with complexity. For something simple, use Data First or Model First with your EDMX file. Then lay a repository on top of that which also contains all the validation rules.
I am currently developing an web site using asp and have a few questions regarding Membership Provider.
I am currently inheriting from Membership Provider class and have just got over the issue of only certain parameters being able to be passed to the CreateUser method.
I have been able to overcome this issue by creating a class that inherits from MembershipUser adding custom properties and then passing that the the UpdateUser method. However to me this seems quite messy and not very efficient as I am making two calls to the database when I could do it in one if I dont use the CreateUserWizard.
So my question is, is using the Provided Login components worthwhile if you are overriding the methods and require more parameters ect in order to keep the use of the properties you can define for this class in the web.config file or is it easier in the long run to just start from scratch. Basically what I want to know is how people have found using Membership by overriding and inheritance over starting from scratch, and how these compare.
Any webpages that talk about this would be good and apologies if the question doesn't make sense or I have missed anything out.
Thanks,
Ric
If I am understanding your question correctly, then yes the membership provider is a great api to build off of so you don't have to reinvent the wheel for the basics of authentication/authorization.
You are using Membership wrong. You should only create your own custom provider when you need to map onto an existing database. IF you are making your own database, then you should just use the default implementation.
Even if you create a custom implementation, you should not do anything that the current membership doesn't already provide. Just map those functions on to your database.
To add additional information, you create a secondary table called UserData or something. This table will be keyed by the MembershipUser.ProviderUserKey, so you lookup any data you need from the other table using the userid from the membership class.
You're really fighting upstream trying to change membership to give you custom things. You can do it, but why cause yourself trouble?
I wrote a custom Membership Provider and it was relatively easy.
Now I need to create users with first name, last name and other fields not considered in the any of the MembershipProvider.CreateUser overloads.
I read that I should not overload CreateUser. Instead, I should write my own Profile Provider.
It seems like a lot of work and I am not sure of the benefits. Can you help me decide the right way to go? (It is for a MVC 3.0 web app.)
It depends. If it isn't a lot of info, you could just create a custom MembershipUser class with the appropriate additional fields. You can look at codeplex.com to find examples of custom Profile implementations.
I'm writing a custom .NET MembershipProvider (not the built in one) and trying to update using Entity Framework. But of course i have no access to (Try)UpdateModel. How can i update it? Thanks in advance.
You can't do this kind of thing with the ASP.NET Membership Provider, that is, write custom updates to the tables.
If it were that easy, less people would have issues/problems with it. =)
Don't even bother adding the ASP.NET Membership SQL Tables onto your EDMX - you won't know the relationships or how the tables really work together. Forget about trying to represent it as a "Model".
My advice is don't try and bind to the MembershipProvider as a Model (i.e dont create a strongly typed view), just call the Membership methods directly from your controller.
This is where we start to miss the 'drag and drop' of Web Forms, can't drop on a ChangePassword control. =)
Your best bet would be to create a regular view (not strongly typed), then have regular buttons that post to your controller methods.
Don't try and pass through the object as a model, get the fields in the Request.Form collection.
[HttpPost]
public ActionResult ChangePassword()
{
string userName = Request.Form["userName"];
string passWord = Request.Form["passWord"];
MembershipProvider.ChangePassword(userName, password);
return View("ChangePasswordSuccess");
}
The above code would be (roughly) the equivalent of passing through a strongly typed User object, changing the password and calling UpdateModel.
Of course, you could implement your own membership provider, but i dont believe implementing a custom provider just to make your code "easier" should be the driver, because unless coded properly (which is not easy to do), you compromise a lot of the built-in security features and wealth of account management options of the ASP.NET Membership provider that we take for granted.
To do this with the default provider is a little complicated, however what would be much easier would be to create your own CustomMembershipProvider as outlined here:
Implementing A Membership Provider
As you can do this to your OWN account model, you can code the repository/DAL code however you choose, and use standard EF practices and conventions, allowing you to perform simple and strongly mapped operations such as UpdateModel.
A similar question was asked here.
Here is a CodeProject sample app that could get you started that uses EF and Microsoft's MembershipProvider. There is a class they built that inherits from MembershipProvider.
http://www.codeproject.com/KB/web-security/EFMembershipProvider.aspx
My problem is quite simple - I think. I'm doing an ASP.NET MVC project. It's a project that requires the user to be logged in at all time. I probably need the current user's information in the MasterPage, like so; "Howdy, Mark - you're logged in!".
But what if I need the same information in the view? Or some validation in my servicelayer?
So how to make sure this information is available when I need it, and where I need it?
How much user information do you need? You can always access the Thread.Current.Principal and get the user's name - and possibly use that to look up more info on the user in a database.
Or if you really really really need some piece of information at all times, you could implement your own custom principal deriving from IPrincipal (this is really not a big deal!), and add those bits of information there, and when the user logs in, create an instance of the MyCustomPrincipal and attach that to the current thread. Then it'll be available anywhere, everywhere, anytime.
Marc
I've had exactly the same issue, and have yet to find a satisfactory answer. All the options we've explored have had various issues. In the specific example you mention, you could obviously store that data in the session, as that would work for that example. There may be other scenarios, that we've had, where that may not work, but simple user info like that would be fine in the session.
We've just setup a BaseController that handles making sure that info is always set and correct for each view. Depending on how you're handling authentication, etc, you will have some user data available in HttpContext.User.Identity.Name at all times. Which can also be referenced.
Build a hierarchy of your models and put the shared information in the base model. This way it will be available to any view or partial view.
Of course it has to be retrieved on each request since web applications are not persistent.
You should store this in Session and retrieve it into your controllers via a custom ModelBinder.
Not sure if I get what you want to ask, but if you are looking for things like authentication and role-based authorization, actually ASP.net is providing a great framework to work on/start with.
This article (with also 2nd part) is something I recently discovered and read about which is really good start with the provider-pattern which help to understand the underlying authentication framework of ASP.net. Be sure to read about the membershipProvider class and the RoleProvider class in msdn also, they together make a great framework on most basic role-base authentication to work with (if you are comfortable with the function they provided, you even don't need to code data-access part, all are provided in the default implementation!)
PS: Check out Context.Users property too! It stores the current authenticated user information.
HttpContext.Current.Users.Identity returns the current user's information. Though I am not sure whether it gets passed implicitly when you make a webservice call.