Make a Linq-to-SQL Generated User Class Inherit from MembershipUser - asp.net-mvc

I am currently building a custom Membership Provider for my Asp.net MVC website. I have an existing database with a Users table and I'm using Linq-to-Sql to automatically generates this class for me.
What I would like to do is have this generated User class inherit from the MembershipUser class so I can more easily use it in my custom Membership Provider in methods such as GetUser. I already have all the necessary columns in the table.
Is there any way to do this? Or am I going about this the completely wrong way?
Thanks!

Usually code generation tools creates so called partial classes, like:
public partial class User
{
// class definition here
}
This means that you can extend definition of that class somewhere within the same namespace like that:
public partial class User: MembershipUser
{
// if MembershipUser doesn't have parameterless constructor then you need
// to add here one
}
And then you'll have User class inheriting from MembershipUser.

Related

Need help working with Abstract Classes and Generics

i'm trying to build a class library for all of my mvc-5 projects. For that task i started with setting up some Abstract Classes for my DB Context and Indentity User like this
Public MustInherit Class ApplicationUserAbstract
Inherits IdentityUser
End Class
Public MustInherit Class DatabaseContextAbstract
Inherits DbContext
Public Property Users as DBSet(of ApplicationUserAbstract)
Sub New()
MyBase.New()
End Sub
Public Sub New(nameOrConnectionString As String)
MyBase.New(nameOrConnectionString)
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
MyBase.OnModelCreating(modelBuilder)
End Sub
End Class
I think i have to get another approach to set DatabaseContextAbstract.Users to the correct Class inherting something like T of ApplicationUserAbstract. Any sugestions for that? I have no clue how to pass this to Users except Using something like
Public MustInherit Class DatabaseContextAbstract(of T as ApplicationUserAbstract)
Inherits DbContext
Public Property Users as DBSet(of T)
End Class
My next question: how would i access the current Instance of DatabaseContextAbstract in my abstract class? All approaches of DatabaseContextAbstract(of DatabaseContextAbstract(... would be nonsense...
EDIT:
The basic idea behind this is to pack Tables and Functions in that abstract Classes. e.g. There are the same UserRight and Group Tables behind every ApplicationUser in all of my projects. But every project may have project specific tables additionally to the base tables. There is still just one Application user in every project.
I don't see a whole lot of point to what you're doing here. IdentityUser is already abstract. It's intended that you're going to create a concrete class that inherits from it. If you perhaps intended to have multiple different types of users that all shared some subset of custom properties, I could see maybe adding an abstract subclass of IdentityUser that implements those, but you're not doing that here. However, even if you did, the user for Identity is a bit of a special case. You can only have one user table, so inheritance must start from a concrete base class, regardless. For example, the following will work fine:
public class ApplicationUser : IdentityUser {}
public class FooUser : ApplicationUser {}
public class BarUser : ApplicationUser
This will not work:
public abstract class ApplicationUserAbstract : IdentityUser {}
public class FooUser : ApplicationUserAbstract {}
public class BarUser : ApplicationUserAbstract {}
In the second scenario, FooUser and BarUser would get separate tables, which is not supported by Identity. In the first scenario, single-table inheritance will be utilized so FooUser and BarUser will be in the same table as ApplicationUser, with a discriminator column.
When it comes to your context, again, there's limited utility in having a base abstract context class. The context is inherently tied to a database, and it doesn't make sense to have multiple context each interacting with its own unique database that are all virtually carbon-copies. Even if you're dealing with a multi-tenant app, you only need one context. The individualization of the databases would be handled via the connection string, not which context class is utilized.
Finally, if you're using Identity, your context should inherit from IdentityDbContext, not DbContext. Among other things IdentityDbContext already contains a DbSet for users, so the one you added is unnecessary.
Long and short, none of this code does anything for an application. It's pointless abstraction for the sake of abstraction.

Partial class on a model when Entity Framework is in separate library

I am not sure if this is the correct way to go, if so, please advise otherwise.
This is an ASP.Net MVC 4 site using EF 5.x
Suppose you have your Entity Framework in a class library on it's own.
Code Generation Item has now generated all of your Models (the xxx.tt section of your EF mode)
This project is then added/referenced in the development of a site.
You can now access the data via the EF.
Now - in the site project I want to create a partial class of one of my EF models, for example "Users", with an additional property that isn't in the DB.
In the past on a web forms project when the EF was part of the project and not a reference I would simply create the partial class and all would be good; my "Users" would now have a bunch of other stuff in it that wasn't database related but needed on the "User".
I can't seem to get this to work in this MVC project where the EF is in a separate project.
I have tried doing this for example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyTestEntity.Entity;
namespace MyTestMVCSite.Models
{
public partial class Email
{
public string OtherEmail {
get { return "me#myEmail.com"; }
}
}
}
I have also tried inheriting the EF models class, like this:
public partial class Email : MyTestEntity.Entity.Email
{
public string OtherEmail {
get { return "me#myEmail.com"; }
}
}
Nothing I seem to be doing gives me access to "OtherEmail"
What I actually want to be able to do is create a partial class for some of my models and then have this partial class implement an interface so i can inject an instance of this interface into another object rather than overloading.
Am i talking crazy nonsense?
You cannot have two partial classes referring to the same class in two different assemblies (projects). Once the assembly is compiled, the meta-data is baked in, and your classes are no longer partial. Partial classes allows you to split the definition of the same class into two files.
Is it possible to have two partial classes in different assemblies represent the same class?
If you wish to augment your models with additional properties used for display purposes, then you should consider using view models, and a mechanism for mapping data to and from your models to view models.
You can then perform validation independently from the model based on the current view. View models will also protect you from accidentally exposing properties on your model that you do not wish users to alter through post data, even if you haven't explicitly specified them in your view.

Custom Membership Provider with EF

I am trying to implement a custom membership provider in ASP.NET MVC 3 with the Enitty Framework. For the user data I created a User class that holds all the login data plus some more.
When I tried to implement the MembershipProvider, some methods appeared that I need to implement which have a MembershipUser parameter in the signature:
public override void UpdateUser(MembershipUser user)
I know I can make my User class inherit the MembershipUser class and this won't be a problem. But when I tried to make it inherit, I couldn't set values for the readonly properties, like Email and others.
Is there any way that these methods can accept an object of type User? Or maybe there is some other better approach to this?
References
http://msdn.microsoft.com/en-us/library/ms152065.aspx
Custom MembershipUser with only needed parameters
http://www.codeproject.com/Articles/165159/Custom-Membership-Providers
Answer
You can create instances of MembershipUser and pass the properties (readonly or not) on the constructor, and then return that MembershipUser instance.
The documentation for the MembershipUser class has a quote that helped me to understand this better:
Creating a new MembershipUser object does not add a new membership
user object to the membership data store.
If adding the custom properties is important that will require you to subclass MembershipUser.
For an example see: Custom MembershipUser with only needed parameters
The last reference link shows a nice article with a custom membership provider using Linq-to-Sql rather than EF but the similarities are many.
Hope that helps.

how to make entity method available at client side?

EF + WCF Ria Service:
Suppose I have entity People, because it is a partial class, so I can extend it to add a method to it:
partial class People{
static string GetMyString(){
//......
return string;
}
}
then at client side, I want to method GetMyString available for entity People. what's the best way to implement this?
In your server side project, you should have (but is not necessary) a People.cs class that contains your metadata, such as attributes for validation.
Also in your server project, create a public partial class named People.shared.cs. In this class you can add your methods such as the GetMyString() method. The People.shared.cs class gets code-generated (copied) to the client project.

MVC Retrieve Model On Every Request

Let’s say I'm developing a helpdesk application that will be used by multiple departments. Every URL in the application will include a key indicating the specific department. The key will always be the first parameter of every action in the system. For example
http://helpdesk/HR/Members
http://helpdesk/HR/Members/PeterParker
http://helpdesk/HR/Categories
http://helpdesk/Finance/Members
http://helpdesk/Finance/Members/BruceWayne
http://helpdesk/Finance/Categories
The problem is that in each action on each request, I have to take this parameter and then retrieve the Helpdesk Department model from the repository based on that key. From that model I can retrieve the list of members, categories etc., which is different for each Helpdesk Department. This obviously violates DRY.
My question is, how can I create a base controller, which does this for me so that the particular Helpdesk Department specified in the URL is available to all derived controllers, and I can just focus on the actions?
I have a similar scenario in one of my projects, and I'd tend to use a ModelBinder rather than using a separate inheritance hierarchy. You can make a ModelBinder attribute to fetch the entity/entites from the RouteData:
public class HelpdeskDepartmentBinder : CustomModelBinderAttribute, IModelBinder {
public override IModelBinder GetBinder() {
return this;
}
public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
//... extract appropriate value from RouteData and fetch corresponding entity from database.
}
}
...then you can use it to make the HelpdeskDepartment available to all your actions:
public class MyController : Controller {
public ActionResult Index([HelpdeskDepartmentBinder] HelpdeskDepartment department) {
return View();
}
}
Disclaimer: I'm currently running MVC Preview 5, so some of this may be new.
The best-practices way: Just implement a static utility class that provides a method that does the model look-up, taking the RouteData from the action as a parameter. Then, call this method from all actions that require the model.
The kludgy way, for only if every single action in every single controller needs the model, and you really don't want to have an extra method call in your actions: In your Controller-implementing-base-class, override ExecuteCore(), use the RouteData to populate the model, then call the base.ExecuteCore().
You can create a base controller class via normal C# inheritance:
public abstract class BaseController : Controller
{
}
public class DerivedController : BaseController
{
}
You can use this base class only for controllers which require a department. You do not have to do anything special to instantiate a derived controller.
Technically, this works fine. There is some risk from a design point of view, however. If, as you say, all of your controllers will require a department, this is fine. If only some of them will require a department, it might still be fine. But if some controllers require a department, and other controllers require some other inherited behavior, and both subsets intersect, then you could find yourself in a multiple inheritance problem. This would suggest that inheritance would not be the best design to solve your stated problem.

Resources