none
Using roles to set visibility

    Question

  • I did this in VBNET but how do you do it in C# silverlight?

    void Page_Loaded(object sender, RoutedEventArgs e)
    	{
    		if (HttpContext.Current.User.IsInRole("Administrator"))
    	{
    		AdminButtons.Visibility = Visible ;
    	}
    	}


    Thanks

     

    Monday, November 29, 2010 3:30 PM

Answers

  • Oh, I thought that part is already correct, but now I see you're using HttpContext instead of WebContext. So it should be:

    if (WebContext.Current.User.IsInRole("Administrator"))
    {
      ...
    }


    "WebContext" is an automatically generated class in a RIA services project.


    Monday, November 29, 2010 5:13 PM

All replies

  • Hi. Like this:

    AdminButtons.Visibility = Visibility.Visible;


    Monday, November 29, 2010 4:29 PM
  • Hi MisterGo -

    Thanks, that gets me halfway there. I also need help with the IF statement. My app is built as a RIA business model so the roles are already set up but I can't quite figure out how to access them. Any more advice on that one?

     

    Monday, November 29, 2010 4:44 PM
  • Oh, I thought that part is already correct, but now I see you're using HttpContext instead of WebContext. So it should be:

    if (WebContext.Current.User.IsInRole("Administrator"))
    {
      ...
    }


    "WebContext" is an automatically generated class in a RIA services project.


    Monday, November 29, 2010 5:13 PM
  • Oh, I thought that part is already correct, but now I see you're using HttpContext instead of WebContext. So it should be:

    if (WebContext.Current.User.IsInRole("Administrator"))
    {
      ...
    }


    "WebContext" is an automatically generated class in a RIA services project.

    Well, that looks good and runs without error but does not produce the desired result. Perhaps there is some additional setup that is required? Here is my code.

    void Page_Loaded(object sender, RoutedEventArgs e)
    		{
    			ShowPopupButton.Click += new RoutedEventHandler(ShowPopup_Click);
    			ClosePopup.Click += new RoutedEventHandler(ClosePopup_Click);
    			SavePopupButton.Click += new RoutedEventHandler(SavePopupButton_Click);
    			
    			if (WebContext.Current.User.IsInRole("Administrator"))
    			{
    			    AdminButtons.Visibility = Visibility.Visible ;
    				MessageBox.Show("Is admin") ;
    			}
    
    			MessageBox.Show("Page loaded" ) ;
    		}


    When the Administrator logins in, I still get only the second messagebox.


     

    Monday, November 29, 2010 6:32 PM
  • Well, you did set up the infrastructure for it, right? Like, create a role that is named "Administrator" (also made sure that this is the role's name, and not "Administrators" or similar), and added the user to that role?

    Tuesday, November 30, 2010 4:16 AM
  • Well yes. Sometimes I'm slow but this time I got that right. AND in double checking I find that the code does work fine. The problem looks like this. Go to the page not logged in. Then log in as administrator and refresh the page. Result - the page still does not see the Administrator user. However, if I then navigate to a different page and then come back to the original page, it does see the Administrator user. So I need a way to reload the page after the login in a way so the newly logged in user is visible.

    Any ideas on that one? 

    Tuesday, November 30, 2010 10:59 AM
  • Then log in as administrator and refresh the page.

    How do you do that? If you mean "hit F5 in the browser" by that, then take a look here.

    So I need a way to reload the page after the login in a way so the newly logged in user is visible.

    Take a look at my answer here. You can hook the LoggedIn event and refresh the frame to achieve that.

    Tuesday, November 30, 2010 11:09 AM
  • Thanks. I got the first suggestion and now the F5 does refresh to include the new user. However I don't quite understand the second suggestion. It looks like I need to add

    				// refresh the current page 
    				ContentFrame.Refresh();       
    


    somewhere but where? Everyplace I try to add it says ContentFrame does not exist in this context.

    Tuesday, November 30, 2010 12:03 PM
  • In your MainPage.xaml.cs. Like the post in the linked thread says, there should already be a reference to your authentication service. You can then hook the LoggedIn event (if it isn't already), and add the code in the event handler. "ContentFrame" is the default name of the navigation frame in the business template. If you've changed that name to something different, use the custom name you're using there.

    Tuesday, November 30, 2010 12:21 PM
  • A reference to AuthenticationService is not there. What using reference is needed to include it?

     

    Tuesday, November 30, 2010 12:44 PM
  • The using reference needed is:

    using System.ServiceModel.DomainServices.Client.ApplicationServices;


    Then you can use the same code I provided in my answer here.

    Tuesday, November 30, 2010 5:56 PM
  • Got that. Where does this line go? It has problems whereever I try to put it.

     

    _AuthService.LoggedIn +=

    new EventHandler<AuthenticationEventArgs

    >(AuthService_LoginChanged);

    Tuesday, November 30, 2010 6:44 PM
  • Ok:

    // That should be a field in your MainPage class
    private readonly AuthenticationService _AuthService = WebContext.Current.Authentication;

    // Hook the event in your MainPage class constructor
    _AuthService.LoggedIn += new EventHandler<AuthenticationEventArgs>(AuthService_LoginChanged);

    // This is the event handler, a separate method in your MainPage class;
    // Make sure your frame actually is named "ContentFrame" in Xaml
    private void AuthService_LoginChanged(object sender, AuthenticationEventArgs e)
    {
            // refresh the current page
            ContentFrame.Refresh();                         
    }


    I hope this helps you sort it out.


    Tuesday, November 30, 2010 11:59 PM
  • Thanks Peter. I'm afraid my newness to the whole framework doesn't allow me the necessary insight to figure this out. I have the first and third snippets but can't figure out where to put the second one. For example, I'm not even sure it belongs in mainpage.xaml.cs or some other place, login.xaml.cs perhaps? And what exactly do you mean by "Hook the event in your mainpage class constructor"? I am assuming the code belongs in mainpage.xaml.cs but there must be an additional wrapper needed to put it there. Can you show me the full detail? Below is my complete page. How would I finish this? Thanks for your patience.

     

    namespace SLEventManager
    {
    	using System.Windows;
    	using System.Windows.Controls;
    	using System.Windows.Navigation;
    	using SLEventManager.LoginUI;
    	using System.ServiceModel.DomainServices.Client.ApplicationServices;
    
    
    	/// <summary>
    	/// <see cref="UserControl"/> class providing the main UI for the application.
    	/// </summary>
    	public partial class MainPage : UserControl
    	{
    
    		private readonly AuthenticationService _AuthService = WebContext.Current.Authentication; 
    
    		
    
    
    		/// <summary>
    		/// Creates a new <see cref="MainPage"/> instance.
    		/// </summary>
    		public MainPage()
    		{
    			InitializeComponent();
    			this.loginContainer.Child = new LoginStatus();
    			
    		}
    
    		/// <summary>
    		/// After the Frame navigates, ensure the <see cref="HyperlinkButton"/> representing the current page is selected
    		/// </summary>
    		private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
    		{
    			foreach (UIElement child in LinksStackPanel.Children)
    			{
    				HyperlinkButton hb = child as HyperlinkButton;
    				if (hb != null && hb.NavigateUri != null)
    				{
    					if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
    					{
    						VisualStateManager.GoToState(hb, "ActiveLink", true);
    					}
    					else
    					{
    						VisualStateManager.GoToState(hb, "InactiveLink", true);
    					}
    				}
    			}
    		}
    
    		/// <summary>
    		/// If an error occurs during navigation, show an error window
    		/// </summary>
    		private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
    		{
    			e.Handled = true;
    			ErrorWindow.CreateNew(e.Exception);
    		}
    
    		private void AuthService_LoginChanged(object sender, AuthenticationEventArgs e) 
    		{ 
    			// refresh the current page 
    			ContentFrame.Refresh();                          
    		}
    	}
    }


     

    Wednesday, December 01, 2010 10:20 AM
  • Hi again. Here is the code with the needed line added. You were only missing one line, hope you can spot it:

    namespace SLEventManager
    {
            using System.Windows;
            using System.Windows.Controls;
            using System.Windows.Navigation;
            using SLEventManager.LoginUI;
            using System.ServiceModel.DomainServices.Client.ApplicationServices;
    
    
            /// <summary>
            /// <see cref="UserControl"/> class providing the main UI for the application.
            /// </summary>
            public partial class MainPage : UserControl
            {
    
                    private readonly AuthenticationService _AuthService = WebContext.Current.Authentication; 
    
                    
    
    
                    /// <summary>
                    /// Creates a new <see cref="MainPage"/> instance.
                    /// </summary>
                    public MainPage()
                    {
                            InitializeComponent();
                            this.loginContainer.Child = new LoginStatus();
    
                            // Hook the event in your MainPage class constructor
                            _AuthService.LoggedIn += new EventHandler<AuthenticationEventArgs>(AuthService_LoginChanged);                        
                    }
    
                    /// <summary>
                    /// After the Frame navigates, ensure the <see cref="HyperlinkButton"/> representing the current page is selected
                    /// </summary>
                    private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
                    {
                            foreach (UIElement child in LinksStackPanel.Children)
                            {
                                    HyperlinkButton hb = child as HyperlinkButton;
                                    if (hb != null && hb.NavigateUri != null)
                                    {
                                            if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                                            {
                                                    VisualStateManager.GoToState(hb, "ActiveLink", true);
                                            }
                                            else
                                            {
                                                    VisualStateManager.GoToState(hb, "InactiveLink", true);
                                            }
                                    }
                            }
                    }
    
                    /// <summary>
                    /// If an error occurs during navigation, show an error window
                    /// </summary>
                    private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
                    {
                            e.Handled = true;
                            ErrorWindow.CreateNew(e.Exception);
                    }
    
                    private void AuthService_LoginChanged(object sender, AuthenticationEventArgs e) 
                    { 
                            // refresh the current page 
                            ContentFrame.Refresh();                          
                    }
            }
    }


    Don't worry if you don't get everything right the first time. We all had to get used to it at first. The more you work with all these things the better you'll become, and you'll see results and make progress in no time. However, it seems you maybe should think about taking a step back and learn a bit more about the basics. Don't get me wrong; Silverlight is a great tool for rapid application development and it makes a lot of things easier, but if you're lacking knowledge about some basic concepts (events, OOP etc.) it can still lead to frustration quickly, especially with more advanced topics like networking and web services. You mentioned you worked with VB.NET. So maybe it's just the new C# syntax that throws you off track - a short intro to the specifics of that language should also give you a nice boost then.

    Wednesday, December 01, 2010 10:53 AM
  • Thanks Peter. I had tried that insertion as you show

    public MainPage()
    		{
    			InitializeComponent();
    			this.loginContainer.Child = new LoginStatus();
    
    			// Hook the event in your MainPage class constructor 
    			_AuthService.LoggedIn += new EventHandler<AuthenticationEventArgs>(AuthService_LoginChanged);
    		}


    but it give an error that says EventHandler cannot be found, perhaps another reference is needed?

    Wednesday, December 01, 2010 11:19 AM
  • Hm, yes.

    using System;


    Small tip: When you click on the erroneous code and then hover with the mouse over it, a small marker appears in Visual Studio. Hover of that small marker, and you will get a list of options to resolve the problem. The first entry should be the one to add the required using automatically. Alternatively, right-click the erroneous code and choose the "Resolve" entry from the context menu. Or, depending on your keyboard settings, click on the code and press Ctrl + . 



    Wednesday, December 01, 2010 2:26 PM
  • Thanks Peter. I in this case the suggestions box did not appear (I already knew about that) but the right-click did work (I did not know about that). Adding the using statement does resolve the issue but the line in question

    	_AuthService.LoggedIn += new EventHandler<AuthenticationEventArgs>(AuthService_LoginChanged);


     

    creates new problems. The page now runs and the login works as expected but, the page now has errors on load that say

    "navigation to a null uri is not supported. Parameter name: uri. " I have never seen an error message of this type before. After clicking OK the page continues to load and seems to operate OK. If I comment out the line above all goes well and the error is gone. Any ideas on what I should look for now?

     

    Wednesday, December 01, 2010 3:17 PM