3

Im thinking of getting usernames of my site using this in my view(Razor syntax):

@MySite.Helpers.Utils.UserName

heres the utils class:

public class Utils
{
    static FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;

    public static string UserName { get { return id.Ticket.UserData; } }
}

Are there any potential problems with this code?

The reason Im doing it like this is because Im going to store username in the userdata field of a new FormsAuthenticationTicket when the user logs in.

I'm handling it like this because Im using facebook connect and want to store there ID in the username field in the db and their usernames/fullnames in a separate table.

so my logic to handle facebook usernames and my site registered usernames needs to be handled differently. Upon login Im thinking of handling it there then setting userdata as the actual username.

therefore throughout the site i can just get the logged in users name using : @MySite.Helpers.Utils.UserName

does this sound ok? will the fact that its a static variable be an issue?

or is there a better way to manage this? session variables maybe?

thanks

raklos
  • 28,027
  • 60
  • 183
  • 301
  • 1
    I'm pretty sure storing `id` as a static variable will cause you problems. Make it into a property instead. – Jesse Buchanan Dec 23 '10 at 14:15
  • @jbinto that's an inaccurate statement since the op has the value of id bound to a the contextual instance at run time through the HttpContext.Current object. With the way @raklos has this coded you can gaurentee at run time you will access the id only for the current request, if you are in a state that does not have access to HttpContext.Current you will get a null reference error. – Chris Marisic Feb 11 '11 at 18:55

1 Answers1

1

The reason Im doing it like this is because Im going to store username in the userdata field of a new FormsAuthenticationTicket when the user logs in.

The username of the currently logged in user is already stored in the authentication cookie. You don't need to store it once again in the UserData. And in order to retrieve it in your Razor template you could simply:

@User.Identity.Name

Obviously it is recommended to decorate the controller action rendering this view with the [Authorize] attribute to ensure that a user is authenticated before accessing it or you might get a NullReferenceException with this code.

As an alternative you could write a helper:

public static MvcHtmlString Username(this HtmlHelper htmlHelper)
{
    var identity = htmlHelper.ViewContext.HttpContext.User.Identity;
    if (identity.IsAuthenticated)
    {
        return MvcHtmlString.Create(identity.Name);
    }
    return MvcHtmlString.Empty;
}

which you could use like this:

@Html.Username()
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I realise that, but I go on to explain why I'm storing it there. my facebook users usernames are held in a different table. I basically want a simple way of getting the username whther its a facebook user or a site registered user. – raklos Dec 23 '10 at 14:02
  • @raklos, so the username stored in the UserData is not the same as the one stored in the authentication cookie, i.e. the currently logged in user is different than the user stored in the UserData property? – Darin Dimitrov Dec 23 '10 at 14:04
  • @Darin - People who register on my site - @User.Identity.Name will give the username. people who register using facebook @User.Identity.Name will give their facebook ID - a bunch of numbers. Their Names are stored in a separate table. I want to seamlessly be able to get the username in one way which is why im considering putting it in UserData. – raklos Dec 23 '10 at 14:14
  • @raklos, OK, I understand now. So you just have to readapt my helper method a little and you should be good to go. Personally I prefer helper method instead of using static methods. – Darin Dimitrov Dec 23 '10 at 14:18
  • @Darin, - Will I need to include @using Mysite.Helpers.Extensions; in every view that uses username? – raklos Dec 23 '10 at 14:23
  • @raklos, not at all. Place the helper into a static class and then simply add the namespace this class is defined into to the `` section of your web.config: ``. Then in all templates you could simply write `@Html.Username()`. It's a simple extension method to the `HtmlHelper` class. And if you define it in the `System.Web.Mvc.Html` namespace there's nothing to do: it will be automatically available. – Darin Dimitrov Dec 23 '10 at 14:25
  • :( Im getting this error: 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'Username' and no extension method 'Username' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference? – raklos Dec 23 '10 at 14:31
  • @raklos, where did you declare the extension method? In which class in which namespace? – Darin Dimitrov Dec 23 '10 at 14:39
  • class is called Extensions in namespace MySite.Helpers. – raklos Dec 23 '10 at 14:44
  • @raklos and did you add `` to the namespaces section of your web.config? Make sure that the class is public static and that the extension method is public static, exactly as it is in my example. If you still have problems writing a custom helper you may take a look at the following detailed step by step tutorial: http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs and especially the second part which is about extension methods. Also try recompiling and running the application at least once. It could be some nasty VS bug in design mode. – Darin Dimitrov Dec 23 '10 at 14:45
  • got it working now:- http://stackoverflow.com/questions/4136703/razor-mvc-3-rc-htmlhelper-extensions-not-found/4136773#4136773...I had to close and reopen the files! grr – raklos Dec 23 '10 at 15:47
  • @raklos, yeah, Intellisense is far from perfect. I never trust it by the way in the views. I always run the application and see what happens at runtime. – Darin Dimitrov Dec 23 '10 at 15:48