I controlli View e MultiView con visualizzazione in base ai ruoli

di Marco Leoncini, in ASP.NET 2.0, Custom Control, Roles API,

Il controllo LoginView permette di presentare template differenti in base all'autenticazione o all'appartenenza di un utente ad un determinato ruolo.

In certi scenari l'utilizzo di questo controllo risulata macchinoso, vista la necessità di ricorrerre al metodo FindControl per recuperare le istanze dei controlli contenute nei template.

Sfuttando come base i controlli MultiView e View è possibile ricreare le stesse funzionalità del control LoginView superandone i limiti.

Per prima cosa ci occuperemo di creare un controllo RoleView estendendo la classe View, aggiugendo una proprietà Role per specificare il ruolo associato alla vista:

public string Role
{
  get { return _role; }
  set { _role = value;}
}

Successivamente rendiamo visibile il controllo solo se l'utente che richiede la pagina appartiene al ruolo specificato:

public override bool Visible
{
  get
  {
    if (Parent != null && !this.DesignMode)
    {
      if (this.Parent.Visible)
      {
        if (this.Page.User.IsInRole(Role))
        {
          _active = true;
          return true;
        }
        else
        {
          _active = false;
          return false;
        }
      }
      return false;
    }
    
    return true;
  }
}

Infine creiamo due metodi wrapper che permetteranno al controllo MultiRoleView di lanciare rispettivamente l'evento di attivazione e disattivazione del controllo View:

internal void OnRoleViewActivate(EventArgs e)
{
  OnActivate(e);
}

internal void OnRoleViewDeactivate(EventArgs e)
{
  OnDeactivate(e);
}

Passiamo alla creazione del controllo MultiRoleView, aggiungendo per prima cosa la proprietà ActiveViews, al fine di contenere le viste attive.

public Collection<View>ActiveViews
{
  get
  {
    EnsureActiveView();
    return _activeViewCollection;
  }
}

La proprietà richiama il metodo EnsureActiveView che scorrendo la collezione originale Views recupera i controlli RoleView visibili preparandoli per il rendering:

private void EnsureActiveView()
{
  if (_activeViewCollection == null)
  {
    _activeViewCollection = new Collection<View>();
    
    foreach (View v in Views)
    {
      RoleView rw = v as RoleView;
        
      if (rw != null)
      {
        if (rw.Visible)
        {
          _activeViewCollection.Add(rw);

          rw.OnRoleViewActivate(EventArgs.Empty);

          rw._active = true;
        }
        else
        {
          if (rw._active)
          {
            rw.OnRoleViewDeactivate(EventArgs.Empty);

            rw._active = false;
          }
        }
      }
      else
      {
        _activeViewCollection.Add(v);
      }
    }
  }
}

Infine eseguiamo l'override del metodo Render per renderizzare tutte le viste attive:

protected override void Render(HtmlTextWriter writer)
{
  //per ogni vista renderizzo il contenuto
  foreach (View v in ActiveViews)
  {
    v.RenderControl(writer);
  }
}

Per utilizzare i nuovi controlli è sufficente aggiungere le classi nella cartella App_Code, piuttosto che creare una class library, e procedere alla registrazione.
Ulteriori dettagli sono contenuti nella soluzione d'esempio allegata alla script.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi