2011-05-05 18 views
6

Farklı görünümlerin kendi içeriklerini burada oluşturmasına izin vermek için _Layout.cshtml içinde @RenderSection("Contextual", false) kullanın. Bazıları yok, diğerleri var. Ayrıca, belirli bir kullanıcının belirli denetleyici eylemlerine erişip erişemediğini ve böylece sitemdeki yönlendirmeleri kontrol etmek için rol tabanlı güvenlik ve bir ActionFilter kullanıyorum.Rol tabanlı güvenlik temelli Html.ActionLinks'in gizlenmesi

Ne yapmak istiyorum benim _Layout.cshtml üzerinde @RenderSection("Contextual", false) bölümünü sağlamak ve daha sonra belirli bir sayfa bağlamsal ne şeyler o sayfa için mantıklı ve gelen kontrolör bir kullanıcı olup olmadığı incelemeden işlemesi sağlaması olduğunu numaralı bir eylemi gerçekleştirebilir ve belki de bu seçeneklerin olduğunu görebiliyor ancak bunun doğru olduğunu düşündüğümden emin değilim. Şu anda

ben şöyle benim Index.cshtml dosyalarından birinde bir bölüm var: Burada işler şu anda nasıl benim tekabül denetleyicisi sonra

@section Contextual { 
    <div>@Html.ActionLink("Create New", "Create")</div> 
    <div>@Html.ActionLink("Generate Report", "Report")</div> 
    <div>@Html.ActionLink("Other Stuff", "Other")</div> 
} 

ve ben şöyle bir şey var :

[Authorize(Roles = "Editor")] 
public ActionResult Create() 
{ 
    // stuff 
} 

istediğim gibi bu çalışacaktır ancak girişi oluşturma görmesi için orada (olmayan Editörler yeni öğeler oluşturmak için almazsınız).

@section Contextual { 
    @if (User.IsInRole("Editor")) 
    { 
    <div>@Html.ActionLink("Create New", "Create")</div> 
    } 
    <div>@Html.ActionLink("Generate Report", "Report")</div> 
    <div>@Html.ActionLink("Other Stuff", "Other")</div> 
} 

Ve bu olmayan Editörler gelen bağlantı oluşturma gizleme, yeteri kadar iyiyse, ama iyi olmadığı konusunda çit değilim ya bu şekilde işlemek için değil artı: ben şöyle bir şey yapabilirsiniz yolun aşağısında, kuralların değiştiği durumu anladım ve sonra senkronize olmak için iki noktam var: denetleyici eylemindeki öznitelik ve görünümdeki kod.

Bu makul bir yaklaşım mıdır? Buna yaklaşmanın daha iyi bir yolu var mı?

cevap

8

Contorller üzerinde bulunan görünüm modeli için daha açık olan bayrakları kullanmayı seviyorum. Örneğin

:

// on the controller 
viewModel.CanCrete = User.IsInRole("Editor"); 
// ...snip... 
return View(viewModel); 
} 

Yani, görünüm modellerinin temel sınıf içinde muhtemelen görünümü modeline bu bayrağı eklemek veya gerekir. Birkaç denetleyicide doldurmak için Custom Action Filter oluşturma yoluna gidebilir veya denetleyici ana sınıfınızda bazı işlemleri gerçekleştirebilirsiniz.

Ben de kullanışlı uzantısı yöntemi tanımlamak istiyorum:

public static string If(this string s, bool condition) 
{ 
    return condition ? s : String.Empty; 
} 

kullandığınız API'ler göstermek bağlı olarak, aynı zamanda MvcHtmlString uzatmak gerekebilir. Sonra görünümünde

:

@section Contextual { 
    <div>@Html.ActionLink("Create New", "Create").If(Model.CanCrete)</div> 
    <div>@Html.ActionLink("Generate Report", "Report")</div> 
    <div>@Html.ActionLink("Other Stuff", "Other")</div> 
} 

Sen div bağlantıları sarar başka yardımcı olmasını isteyebilirsiniz, ya da belki ulaşmak için CSS kullanabilirsiniz, sen div hakkında yapmak istiyorum karar verebilir ne olursa olsun görsel düzeniniz.

+0

Yanıt için teşekkürler. Çözümünüzle ilgili hoşuma giden şey, Kullanıcı rolü kontrolünün kontrolörde yapıldığı ve daha sonra Görünüm işinin gerçekten endişelenmediği fikridir * Neden * Oluşturma işlevi etkinleştirildi/devre dışı bırakıldı - bunu ayırır bilgi çıkışı. Denetleyici tarafında CanCreate biti çevirmek için kullanılabilecek çeşitli nedenlere izin verir. İyi şeyler. Ben * kesinlikle * bu uzantısı yöntemi gibi - bu * kullanışlı *. :) – itsmatt

+0

@itsmatt sorun değil. Üzerinde çalıştığım mevcut sistem (context + role) tabanlı güvenlik ile dolu, bu yüzden çok fazla çalışın. Sanırım kilit noktayı vurup, kontrolün görüşlerini endişelendiriyorsunuz. Başka bir rota, role göre bağlantı listesi oluşturmak olabilir (kontrolörde de olabilir). – TJB

0

TJB'nin cevabını çok beğeniyorum ve aslında benzer bir şey yapacağımı düşünüyorum.Ancak farklı bir rotaya gitmek istiyorsanız standart LinkExtensions'ı aşırı yükleyen kendi LinkExtensions'ınızı oluşturabilirsiniz.

public static class MyLinkExtensions 
{ 
    public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, YourAccessStuff access) 
    { 
     if(access.Has(actionName)) 
     { 
      ActionLink(htmlHelper, linkText, actionName);    
     } 
     else 
     { 
      // Maybe only show the link text as if it's disabled and not a link? 
      // Maybe do nothing?   
     } 
    } 
} 

"YourAccessStuff" aslında uygulandığını burada varsayalım. Bu erişim kontrollerini, her ActionLink'e yapıştırmanın aksine merkezileştirirdi. Dezavantajı, açık bir şekilde, güvenlik kontrolünü yapmayı unuttuğunuz. Bir çeşit bağımlılık enjeksiyonunun kullanılması bunu daha da güzelleştirecektir.

İlgili konular