SetRefresh Method for ASP.NET web pages to support postback.

I’ve read Willem’s Blog post Auto-refreshing ASP.NET web pages  and desided to post my helper function SetRefresh(Page page,int nDelaySec) that is similar to suggested by Willem’s third method, but supports postbacks. It’s important to keep values, entered by the user before refresh.


            public static void SetRefresh(Page  page,int nDelaySec)


            { // from http://groups.google.com/group/microsoft.public.dotnet.framework.aspnet/msg/ffec2cc7c4836ed6?hl=en&


 


                  //NOTE: Often the __doPostBack function is inserted into your page by .NET. If not, put the code in manually, or add a dummy LinkButton and set it’s style to be “display:none”.


                  //     from http://www.codeproject.com/aspnet/OneTimeClickableButton.asp?msg=1185901


                  //window.Form1.submit();


                  int nMilliSec=nDelaySec*1000;


                  StringBuilder sb = new StringBuilder();


                  sb.Append(“setTimeout(myRefresh,”+ nMilliSec.ToString()+ “);”);


                  sb.Append( @” function myRefresh()


                        {


                         __doPostBack(document.forms[0].id,”);


                        } “);


                  page.RegisterClientScriptBlock(“SetRefresh”, JScript(sb.ToString()));


            }


The function included in My JScriptHelper class

Advertisements

Support Forms and Windows authentication on the same ASP.NET Application.

I ‘ve posted some details of my implementation of Richard Dudley‘s solution  How to Make Windows Authentication and Forms Authentication Work Together


Please see them here.

Support Forms and Windows authentication on the same ASP.NET Application.

It is quite common request to support both Forms and Windows authentication on the same Web Application.
The best solution that I found is described by  Richard Dudley at posts Using Forms Authentication with Windows Authentication (“Mixed Mode”) and How I Made Windows Authentication and Forms Authentication Work Together.

I want to post some details of my implementation of this approach. 

There is a snippet from my WebLogin.ASPX code Page_Load method:

        If Not IsPostBack Then

            Dim bUseWindowsAuthentication As Boolean = Application(“UseWindowsAuthentication”)

            If bUseWindowsAuthentication Then

                ‘ Redirect to winlogin to try WindowsAuthentication if possible

                ‘http://aspadvice.com/blogs/rjdudley/archive/2005/03/10/2561.aspx

                ‘http://aspadvice.com/blogs/rjdudley/archive/2005/03/10/2562.aspx (How I Made Windows Authentication and Forms Authentication Work Together )

            ‘//only try to force windows if starting with LAN ip address

                ‘//change this logic as your like using a Regex

                Dim r As New Regex(ConfigurationSettings.AppSettings(“lanIPmask”))

                If r.IsMatch(Me.Request.UserHostAddress) = True Or HttpRequestHelper.IsBrowserOnServer Then

                    If Me.Request.QueryString(“WinLoginError”) = Nothing Then ‘avoid indefinite loop

                        Dim sQueryString As String = Me.Request.QueryString.ToString()

                        DebugHelper.TracedLine(“sQueryString =” & sQueryString)

                        Response.Redirect(“Authent/WinLogin.aspx?” & sQueryString)

                    Else

                        lblError.Text = Me.Request.QueryString(“WinLoginError”)

                    End If

 

                End If

            End If

The snippet from Authent/WinLogin.aspx page

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ‘http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/MixedSecurity.asp

        DebugHelper.PrintAspNetIdentities()

        Dim userName As String = Me.Request.ServerVariables(“LOGON_USER”) ‘usually with domain name

        userName = StringHelper.RightAfter(userName, “”) ‘Strip domain if applicable

        CreateFormsAuthenticationTicket(userName)

    End Sub

    Function CreateFormsAuthenticationTicket(ByVal userIdentity As String) As Boolean

        Dim oLogin As New FSWeb.LoginHelper

        Dim bPersistCookie As Boolean = False ‘ = Persist.Checked

        ‘Set Current.Session[“PatronID”] if successful

        Dim bRet As Boolean = False

        If Not DataHelper.IsNullOrEmpty(userIdentity) Then

            bRet = oLogin.LoadUserFromDatabase(userIdentity)

        End If

        If bRet = True Then

            ‘Save WindowsIdentity -from http://weblogs.asp.net/pwilson/archive/2004/02/02/66155.aspx

            Dim sUserToken As String = LoginHelper.GetUserTokenAsString(Me.Context)

            Dim userToken As New IntPtr(Integer.Parse(sUserToken))

            Dim identity As New WindowsIdentity(userToken, “NTLM”, WindowsAccountType.Normal, True)

            Dim principal1 As New WindowsPrincipal(identity)

            bRet = oLogin.SaveWindowsPrincipalInSession(principal1)

        End If

        If bRet = True Then

            oLogin.CreateTicket()

            If FSWeb.Login.RedirectBack(Me) = True Then Exit Function ‘old way of redirect

            ‘ Redirect back to original URL.

            WebFormsHelper.SmartRedirect(Page, FormsAuthentication.GetRedirectUrl(oLogin.PatronID, bPersistCookie))

        Else ‘windows account not found in the database- so use normal forms authentication

            Dim sQueryString As String = HttpHelper.QueryStringCollectionToString(Me.Request.QueryString)

            ‘Expected that oLogin.ErrorMessage is meaningful, but if not, ensure it’s not empty

            sQueryString = HttpHelper.AddQueryStringParameter(sQueryString, “WinLoginError”, Nz(oLogin.ErrorMessage, “Error during windows Authentication”))

            Dim sUrl As String = ResolveUrl(“~login.aspx?” & sQueryString)

            WebFormsHelper.SmartRedirect(Page, sUrl)

        End If

        Return bRet

    End Function

 

To setup this functionality it is required to specify lanIPmask in Web.Config and set authentication on AuthentWinLogin.aspx page to be Windows Integrated only.

 

Procedure to specify lanIPmask:

  1. Open file web.config in your web application folder the text editor(e.g. Notepad)
  2. Search for a line
    <add key=”lanIPmask value=””/>
  3. Change the value to appropriate, e.g. “192.168.d{1,3}.d{1,3}” if your LAN IP addresses are in range “192.168.0.0”- “192.168.255.255”
    For details how mask can be specified see

http://www.regular-expressions.info/examples.html

 

  1. Save the changed file.

 

Procedure to set  AuthentWinLogin.aspx page to be Windows Integrated only.  

1.      On the web server right-click the My Computer icon and click Manage.

2.      Expand the Services and Applications node in the MMC.

3.      Select Internet Information Services.

  1. Navigate to YorApplicationVirtualDirectoryAuthent Folder(Assume that the application is installed in the default virtual folder).
  2. Right-mouse click WinLogin.aspx, then Click Properties, and then click the File Security tab.
  3. Under Authentication and access control, click Edit.
  4. In the Enable Anonymous Access group, clear the Enable anonymous access check box.
  5. Ensure that Integrated Windows Authentication check box is ticked
  6. Click OK to close the dialog.
    UPDATE- See the post Programmatically set IIS Authentication for a page. to set authentication for WinLogin.aspx automatically from the installer.

 It is also required to  change Internet Explorer clients setting to trust your website  as described at

 http://groups.google.com.au/group/microsoft.public.inetserver.iis/msg/4e6c0dda9313f23a?hl=en&

I want to highlight that site should be added to Local Intranet , not to Trusted Sites.

 

 

UPDATE: Jorge Loco requested to post code of helper classes that are referred by these snippets.

 See My DataHelper class.  (including Nz method), My DebugHelper and TraceHelper classesMy HttpRequestHelper class, My StringHelper class.

 

To resolve ‘WindowsIdentity’ and  ‘WindowsPrincipal’ add

imports System.Security.Principal.
 

FSWeb.LoginHelper, FSWeb.Login and HttpHelper classes contain propriatary information and can’t be published. You should replace them with your own code.

UPDATE: there is excellent Michael Morozov‘s post Single Sign-On for everyone ,which suggest easier solution for mixed-mode authentication (Forms and Windows).I haven’t tried, but it looks promising. 

 

WinForms ComboBox SelectedIndexChanged event and SelectedValue assignment.

I am using WinForms.ComboBox and wanted to handle SelectedIndexChanged events. I found that when DataSource is assigned adding each row caused SelectedIndexChanged.
It is a known and aknowledged by Microsoft problem and there are possible workarounds(e.g see http://www.bobpowell.net/ComboBinding.htm  or http://www.windowsitpro.com/Article/ArticleID/41825/41825.html ).


I desided that I don’t need to set DataSource but will use



lst.Items.Clear();
lst.Items.AddRange(coln.ToArray());


It helped with SelectedIndexChanged event not firing before user actually change the value.


The new problem was that  when  I programmatically set cmb.SelectedValue=value , selection of the combobox was not changed and SelectedIndex was still -1.


Checking System.Windows.Forms.ListControl.set_SelectedValue in Reflecter confirmed, that only for bounded controls ( dataManager != null) selection would be changed by assigning SelectedValue.


It seems that the best approach would be to temprary remove comboBox_SelectedIndexChanged event handler before data binding, assign DataSource,DisplayMember, ValueMember , assign SelectedValue and then add comboBox_SelectedIndexChanged event handler again.

Storing User Configurations in .Net 1.1

 .Net 2.0 will introduce My.Settings to store user preferences. For .Net 1.1 i wanted to use approach described by Rockford Lhotka in MSDN article “Storing User Configurations”. It requires to create derived class with properties that you want to store.


I found 2 tips when created the derived class that is using IsolatedStorage.


1. Ignore FileNotFoundException error when load storage the first time.
2. Use assignment with cast when Load class from storage, e.g.
 
 MySettings=MySettings.Load();


See the sample derived class below:


      public class MySettings: vbUserSettings.UserSettingsBase


      {//based on http://msdn.microsoft.com/library/en-us/dnadvnet/html/vbnet07082003.asp


            //in .Net 2.0 will be replaced with My.Settings  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/vbmysettings.asp 


            //Constructors


            public MySettings(): base()//required for serialization


            {}


            public MySettings(vbUserSettings.UserStorageOption StorageOption): base(StorageOption)


            {}


           


            /// <summary>


            /// Loads casted object


            /// </summary>


            /// <returns></returns>


            /// <remarks> IMPORTANT: return value of the function should be used</remarks>


            /// <example>


            ///         MySettings=MySettings.Load();


            ///     MySettings.Load();// Incorrect!!, the cast is not applied and derived class properties are not assigned


            /// </example>


            public  MySettings Load()


            {


                  try


                  {


                        return (MySettings)Restore();


                  }


                  catch (vbUserSettings.UserSettingsException  exc) //System.IO.FileNotFoundException


                  {


                        Debug.WriteLine(exc.ToString());


                        //new file, ignore the error


                  }


                  return this;     


            }


            //Derived class properties and fields


            public ImportModeEnum importMode;


      }


 

ADO RecordSet.Status value after AddNew is not adRecNew

In ADO I wanted to test if the current record  existing or has been added with AddNew.


I ‘ve checked RecordSet.Status value and expected that after AddNew command the Status will be adRecNew(1)  but it returned adRecOK(0).


Possibly the value depends on cursor settings , in my code I had adOpenKeyset, adLockOptimistic.


Fortunately I found that I can use EditMode and check if value is adEditAdd (2)

DotNetNuke “Custom groups” -aka “Security Roles” documentation

I’ve started to read  DotNetNuke documentation. The Guided Tour page  refers


“For more information on custom groups you’ll want to read the tutorial: Manage Users.”

However the link doesn’t described custom groups.

To find more about “Security Roles“ you should read DotNetNukeOnlineHelp