[ Shadowed @ 27.12.2011. 23:13 ] @
Dakle, ako imam u kontroleru:
Code (csharp):

[Authorize(Roles="Manager")]
public ActionResult Delete()
{
    ...
}
 


Ja mogu u Razoru da proverim da li je trenutni korisnik u grupi Manager ali bih vise voleo da proverim da li trutni korisnik ima pravo da koristi Delete i ako ima onda da mu renderujem link za delete. Tako posle menjam samo atribut, ne moram da jurim po view-ovima. Postoji li neka mogucnost za to?
Mozda je resenje trivijalno, al' tek sam pre neki dan poceo da ucim MVC :)
[ Dejan Carić @ 28.12.2011. 08:43 ] @
Zaštićene akcije na kontroleru bi uvek trebao da dekorišeš sa Authorize atributom, čak i ako nemaš link ka toj akciji na view-u, jer korisnik može da ukuca šta god hoće u URL i onda nastaje haos. Redosled izvršavanja je takav da se uvek prvo izvrši Action Filter pa tek onda kod koji se nalazi u kontroleru.
Ukoliko su sve akcije na kontroleru zaštićene, onda možeš da dekorišeš samo kontroler sa nekim atributom umesto da dekorišeš svaku akciju posebno.

U kontroleru ispitaj da li je korisnik autorizovan i tu vrednost prosledi na View:
Code:
public ActionResult Index()
{
    var viewModel = new HomeViewModel();
    ...
    viewModel.IsAuthorized = ...

    return View(viewModel);
}

[Authorize(Roles="Manager")]
public ActionResult Delete(int id)
{
    ...
}

i na View samo ispitaš taj uslov:
Code:
@if(Model.IsAuthorized)
{
    <a href="@Url.Action("Delete", "Home", new { id = ... } )">Delete</a>
}

Ukoliko ti je smor da na svakom View-u proveravaš taj uslov i generišeš link, možeš da napraviš custom HTML helper i time uštediš malo vremena.
http://weblogs.asp.net/scottgu...elper-syntax-within-razor.aspx


Generalno sva biznis logika (da li je korisnik autorizovan da uradi nešto itd.) se nikada ne piše u View jer možeš vrlo lako da se pogubiš šta ide u kontroler, šta ide u View, a šta ide u neke druge slojeve tvoje aplikacije...

Ja to radim ovako:
- Repository za data access i on nikada nije referenciran u web projektu
- Service kao proxy i za svu biznis logiku, keširanja, itd. On je referenciran u web projektu i ako ti je potreban pristup Repository-u, to ide preko njega
- Controller poziva Service, domenske modele mapira u ViewModel-e i poziva odgovorajući View
- View iscrtava samo ono što mu je prosleđeno preko ViewModel-a. Ne sadrži nikakvu logiku osim prostih foreach i if petlji

Od alata gotovo uvek koristim AutoMapper, StructureMap i Elmah.

[Ovu poruku je menjao Dejan Carić dana 28.12.2011. u 10:12 GMT+1]
[ Shadowed @ 28.12.2011. 11:38 ] @
E, hvala na opsirnom odgovoru. Zapravo, ako idem preko ViewModel-a onda bi trebalo nesto kao ViewModel.IsAuthorizedFor("Delete") jer mi treba posebno za tu akciju. Pa onda ViewModel.IsAuthorizedFor("Add") itd. Tako bih nesto i uradio ako ne postoji direktna podrska, samo me zanimalo da li postoji nesto ugradjeno za to, cisto da ne ubacujem podatke o tome u Model (ili ViewModel) ako vec postoje dostupni.
[ mmix @ 28.12.2011. 11:52 ] @
samo mali predlog, izegavaj magic strings ako ikako mozes. Meni se generalno asp.net mvc ne svija ali mi je ceo taj koncept sa konvencijom preko stringova posebno odbojan i potpuno kontra sa celom "testable" koncepcijom koju MVC prodaje.
[ Shadowed @ 28.12.2011. 11:59 ] @
Slazem se za to, ni ja ne volim koriscenje stringova na taj nacin, nevezano za mvc, al' je ovde dobro posluzilo za jednostavni prikaz.
[ Dejan Carić @ 28.12.2011. 11:59 ] @
Nema ništa ugrađeno, moraš sam da napraviš... ali nema potrebe ni da praviš ViewModel.IsAuthorizedFor("Delete")

Jednostavno, napraviš ovakav ViewModel:

Code:
public class FooViewModel
{
    public bool ShowAddLink { get; set; }
    public bool ShowDeleteLink { get; set; }
    ...
}

u kontroleru mu nasetuješ te vrednosti, a na View pozoveš HTML helper koji kao argumente prima bool showLink, string actionName, string controllerName i object routeValues:

Code:
@TvojHelper.ActionLink(Model.ShowAddLink, "Delete", "Foo", new { id = 3 })

I tvoj helper bi trebalo da vrati null ukoliko mu proslediš false ili pravi link ukoliko mu proslediš true.


Obično takve html helpere koristim za img tagove da bih izbegao pisanje if petlji.
Helper prima putanju do slike i alt text kao argumente. Ako je putanja prazna, vraćam string.Empty ili default sliku. Ukoliko je alt text prazan vraćam alt="".