Malte Baden's blog
web / general development stuff =)

Rendering links based on ActionMethod Authorize attribute ASP.NET MVC2 Beta

januar 17, 2010 02:42 by Moulde

Jeg har siddet og leget lidt med en MVC website de sidste par dage, og nu fik jeg den ide at jeg ville lave en alternativ ActionLink extension method.

Klokken er mange så grusomme stavefejl og lign vil måske forekomme.

Fordi
Hvorfor vente på at Authorize attributen på ens actionmethod smider en videre til loginsiden hvis man forsøger at tilgå et view man ikke har adgang til.

Normalt vil ActionLink metoden generere noget lignende dette.

   1:  <a href="/Profile/Browse">Browse</a>


Det jeg ville var at få den til at tjekke den actionmethod der bliver linket til når ActionLink genererer linket, og så gøre noget forskelligt alt efter om brugeren er logget ind, og om brugeren har adgang til den actionmethod der linkes til.

Lige nu tjekker den bare om metoden har en AuthorizeAttribut, det virker, men ligeså snart der kommer roller og så videre ind i billedet, så bliver det lidt noget hø.
Men den gør det den skal, så om det overhovedet bliver logisk at udbygge den så meget mere tager jeg som det kommer.

Tilbage til ideen..
Hvis man er logget ind eller viewet der linkes til ikke har en authorize attribut, så bliver linket genereret som eksemplet.

   1:  <a href="/Profile/Browse">Browse</a>


Men hvis man ikke er logget ind og metoden har en authorize, så bliver linket erstattet med “javascript:SomeJavascriptFunction”. Eksempel

   1:  <a href="javascript:ShowLoginForm()">Browse</a>


Metoden kan så fx vise en simpel login form.
Og i den form kunne man jo så sende en returnUrl med, som jo så kunne være link til det view man i første omgang prøvede at få adgang til.

Så istedet for 2 “postbacks” / sideskift vil man få en hurtig form smidt i hovedet vha. javascript og så et enkelt sideskift før man ankommer til det view man bedte om at få.

Hvis login somehow fejler, så skal man selvfølgelig bare sendes til det normale login-view hvor man så kan prøve igen.

Det er jo meget fint, men hvad nu hvis brugeren ikke kan køre javascript enten fordi det er slået fra, eller fordi brugeren har en lorte browser?
Så kan vi istedet for at erstatte linket i C#, markere det på en anden måde, og så få javascript til at erstatte det når det når ud i browseren..

Hvis ikke brugeren har javascript, bliver linket ikke fjernet og det hele virker.
Hvis brugeren har javascript bliver linket erstattet og han får en login form i hovedet.

Men tag det lige med at gran salt, det har taget en 30 minutters tid at bikse sammen.
Det er cirka første gang jeg bruger reflection, så der er sikkert nogle meget bedre måder at gøre det på, (Shoot me)! ;)

   1:  public static string AuthorizedActionLink(this HtmlHelper html, string linkText, string ActionName, string ControllerName, string javascriptFunction)
   2:          {
   3:              bool isAllowed = true;
   4:              if (!HttpContext.Current.User.Identity.IsAuthenticated)
   5:              {
   6:                  string fullControllerName = "ProjektNamespace.Controllers." + ControllerName + "Controller";
   7:   
   8:                  foreach (MethodInfo method in Type.GetType(fullControllerName).GetMethods())
   9:                  {
  10:                      if (method.Name != ActionName)
  11:                          continue;
  12:   
  13:                      foreach (Attribute attribute in method.GetCustomAttributes(false))
  14:                      {
  15:                          if (attribute is AuthorizeAttribute)
  16:                              isAllowed = false;
  17:   
  18:                          if (!isAllowed)
  19:                              break;
  20:                      }
  21:                      break;
  22:                  }
  23:              }
  24:   
  25:              string linkHtml = html.ActionLink(linkText, ActionName, ControllerName).ToHtmlString();
  26:   
  27:              if (!isAllowed)
  28:              {
  29:                  XElement element = XElement.Parse(linkHtml);
  30:   
  31:                  element.Attribute("href").Value = "javascript:" + javascriptFunction + "()";
  32:                  //element.Add(new XAttribute("id", javascriptFunction));
  33:   
  34:                  linkHtml = element.ToString(SaveOptions.DisableFormatting);
  35:              }
  36:   
  37:              return linkHtml;
  38:          }

 

Nu håber jeg ikke koden strækker sig ud over siden..
Hvis nogen kan bruge koden til noget som helst, så hapser folk selvfølgelig bare :) 

DISCLAIMER:
Hvis din server dør en grusom død pga ovenstående kode så kan jeg selvfølgelig ikke holdes ansvarlig.

Jaja, men jeg har sku hørt så meget grumt om reflection, you never know!

Happy coding :)


Tags:
Categories: ASP.Net Mvc | C#
Actions: E-mail | Permalink | Kommentarer (0) | Comment RSSRSS comment feed

Kommentarer

Tilføj kommentar




biuquote
Loading