Posts tonen met het label LINQ. Alle posts tonen
Posts tonen met het label LINQ. Alle posts tonen

dinsdag 23 september 2008

Dynamic Data integreren in bestaande web applicatie

Één na de nieuwe features in Visual Studio 2008 SP1 is de Dynamic Data Web Application. Een heel handige feature die het mogelijk maakt om je databronnen middels een website te bekijken of te muteren.

Als je een nieuw project in Visual Studio 2008 aanmaakt bestaat de Dynamic Data Web Application uit één van de vele mogelijkheden die Visual Studio tegenwoordig biedt. Indien je deze keuze maakt wordt een complete web applicatie voor je gegenereerd en hoef je eigenlijk alleen maar een 'LINQ to SQL classes' diagram toe te voegen; de benodigde tabellen op het diagram te slepen en de gecreëerde DataContext toe te voegen aan de MetaModel instantie in global.asax.cs en je bent klaar.

Wat nu als je deze functionaliteit wilt integreren in een bestaande web applicatie?
Ik heb wat zitten vogelen met deze functionaliteit en heb deze zo aangepast dat het relatief eenvoudig is om te integreren in een bestaande web applicatie. Hiervoor moet je het volgende doen:
  1. Download dit zip bestand en importeer de folder uit de zip in je web applicatie. De zip bevat een 'LINQ to SQL classes' diagram welke als voorbeeld is toegevoegd. Deze kan gewoon verwijderd worden!
  2. Voeg de volgende references toe aan je project:
    System.Web.DynamicData
    System.Web.Routing
  3. Voeg een 'LINQ to SQL classes' diagram toe aan je project en sleep de benodigde tabellen op het diagram
  4. Registreer de DataContext, van bovenstaand diagram, middels de model.RegisterContext functie van de RegisterRoutes methode in de DynamicDataModule klasse
  5. Wijzig de DynamicDataApplicationName constante in de DynamicDataMaster klasse naar je eigen applicatienaam

    == Web.config aanpassingen ==
  6. Voeg in de sectie de volgende assemblies toe:
    <add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add assembly="System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  7. Voeg in de / sectie de volgende tag prefix toe:
    <add tagPrefix="asp" namespace="System.Web.DynamicData" assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  8. Activeer ASP.NET Routing
       IIS5/IIS6 : voeg de module toe aan de httpModules sectie:
    <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
       IIS7 - deel 1: voeg de module toe aan de / sectie:
    <remove name="UrlRoutingModule" />
    <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
       IIS7 - deel 2 : voeg de handler toe aan de / sectie:
    <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  9. Voeg de DynamicDataModule aan de modules sectie toe (wijzig [WebApplitionName] in de naam van je assembly):
    <add name="DynamicDataModule" type="DynamicDataModule, [WebApplitionName]"/>

Als je nu de pagina DynamicData\Default.aspx opstart zou de Dynamic Data feature moeten werken.

Succes ermee !!!

donderdag 8 mei 2008

Active Directory benaderen in .Net 3.5

Microsoft heeft in het .Net framework versie 3.5 de assembly System.DirectoryServices.AccountManagement toegevoegd, welke mogelijkheden biedt om redelijk eenvoudig de Active Directory (of de accountdatabase (SAM) op een lokale PC) te benaderen en te wijzigingen. In deze blog richt ik me alleen op de Active Directory (AD).

Je maakt hierbij gebruik van de PrincipalContext klasse. Hieronder een voorbeeld hoe deze klasse te instanciëren:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "MijnDomein");
Hierbij word een 'context' gecreëerd wat de basis is voor alle acties die in de AD uitgevoerd zullen gaan worden. Er wordt daardwerkelijk een verbinding met de directory ('MijnDomein') gemaakt.

Hierna kan je eenvoudig een User of Group ophalen en eventueel wijzigen. De basis klasse die hiervoor gebruikt wordt is de Principal klasse. Hieronder een voorbeeld hoe je een User of Group ophaalt:
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "Danny");
en
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "Administrators");
Met behulp van de Save methode kunnen wijzigingen op de principals doorgevoerd worden.

Een gebruiker kan ook gevalideerd worden (op bestaandheid én op correct wachtwoord). De ValidateCredentials(string userName, string password) methode van de PrincipalContext klasse kan hiervoor gebruikt worden.

Dankzij de PrincipalSearcher klasse en LINQ is het mogelijk ook relatief eenvoudig te zoeken naar Members (Users en Groups) in de Active Directory. In het voorbeeld hieronder wordt gezocht naar alle Users, welke de voornaam 'Danny' hebben:
//Creëer de context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "MijnDomein");

//Creëer een UserPrincipal om te gebruiken voor de Query
UserPrincipal u = new UserPrincipal(ctx);
//Zet de eigenschappen om naar te zoeken
u.GivenName = "Danny";

//Creëer de PrincipalSearcher om mee te zoeken
PrincipalSearcher ps = new PrincipalSearcher(u);
// Voer de Query uit
PrincipalSearchResult results = ps.FindAll();

De FindAll methode in de PrincipalSearcher klasse geeft een PrincipalSearchResult terug, welke de mogelijkheid biedt om met behulp van LINQ queries op het resultaat uit te voeren.

Ik heb zelf wat onderzoek gedaan naar de System.DirectoryServices.AccountManagement namespace, omdat ik een lijst met gebruikers op wil vragen uit een specifieke groep in de AD. De standaard methodieken hiervoor bieden helaas alleen de mogelijkheid om de gebruikers die in de groep zelf zitten te bepalen, maar niet om recursief (groepen in groepen) te zoeken naar de gebruikers. Hieronder de code die ik heb ontwikkelt, welke dit wel mogelijk maakt:
public static List GetGroupUsers(string domainName, string groupName, bool recursive)
{
//Creëer de context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
//Haal de AD Group op
using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, groupName))
{
//Loop door de Members om de Users te bepalen
List result = new List();
foreach (Principal principal in groupPrincipal.Members)
{
if (principal is UserPrincipal)
result.Add(principal);
}
//Loop door de Members om de Groups recursief te benaderen
if (recursive)
{
foreach (Principal principal in groupPrincipal.Members)
{
//Controleer of de member een Group is
if (principal is GroupPrincipal)
{
//Roep deze methode aan, zodat de recursie ontstaat
foreach (Principal p in GetGroupUsers(domainName, principal.Name, recursive))
{
//geen dubbele Users in de lijst
if (!result.Contains(p))
result.Add(p);
}
}
}
}
return result;
}
}




Bronnen:
Microsoft MSDN
Boeken:
The .NET Developer's Guide to Directory Services Programming