Dot Net

Syrinx .NET Development Blog
Need help on your project? info@syrinx.com, or toll free (888) 579-7469, press 1

News



Need help with your .NET Development project?

Syrinx works with clients throughout New England to architect, design, develop, and deploy .NET Applications. Working on fully outsourced projects, as part of your team, helping to train your team, or rescuing projects in trouble, we are comfortable doing it all. Projects from a couple weeks to several months in duration, reference clients available. Contact us today - info@syrinx.com, or toll free (888) 579-7469 and press 1 to speak to someone now!

December 2007 - Posts

Data Source Controls in ASP.NET 2.0

The 4 Guys from Rolla continue to publish some excellent hands-on tutorials about ASP.NET, one of the most recent details how to handle the editing of NULL values in a GridView. If you've ever had a database table editor app where you need to let the user set a column's value to NULL, check this one out:

 http://aspnet.4guysfromrolla.com/articles/112807-1.aspx

This is the latest in a series of articles from Scott Mitchell on the 2.0 Data Source Controls. There's a link to the rest of the articles at the top of the page, or you can subscribe to the RSS here:

http://aspnet.4guysfromrolla.com/rss/dataSourceControls.xml

 

A Simple Custom Sql Membership Provider Part 1

The benefits of using Microsoft's new Membership Provider, and an explanation of how to configure and use them, are well documented on MSDN (http://msdn2.microsoft.com/en-us/library/yh26yfzy(VS.80).aspx).  Certainly the Sql Membership Provider, in conjunction with the suite .Net controls, does a great job providing everything needed for creating and managing user accounts for a common web application.  But sometimes your needs may be a little outside of what can be configured or coded using the Provider as is.  Fortunately, extending the provider is a very straightforward task.

I recently implemented a .Net 2.0 website using many of the providers, including Membership, Role, and Profile.  While the Membership Provider gave us industry standard security "for free", the requirements dictated that a few features needed to be changed.  One of those features was the passwords that are automatically created when using the Password Reset button.  By default, the provider creates a string of characters that is long and contains non-alphanumeric values.  Even cutting and pasting these into the browser becomes difficult (not to mention confusing) when the first character of your new password is a ":" (colon).  My requirements called for a simple string of letters and numbers, preferably 10 characters in length.  Despite the numerous configuration options available, this functionality was nowhere to be found.

The solution involved creating a CustomSqlMembershipProvider class that inherited from the existing SqlMembershipProvider to do most of the heavy lifting. 

 Below is the code that provides configurable length Password Reset function that contains only numbers and lowercase letters, leaving out ambiguous characters to avoid confusion.

 Some things to note...

  • Inherit from SqlMembershipProvider to gain access to the base implementation.
  • Read any custom config entries in the Initialize override method, but be sure to remove those entries as the base provider will not recognize them and will throw an exception.
  • Be sure to call base.Initialize to trigger the default implementation.

Hope this helps!

JoeP


 

public class MembershipProvider : SqlMembershipProvider

{

    System.Random rnd;

    string[] characters;

    const int DefaultResetPasswordLength = 10;

    private int ResetPasswordLength;

 

    public MembershipProvider()

    {

        rnd = new Random();

        characters = FillCharacters();

    }

 

    public override void Initialize(string name,

        System.Collections.Specialized.NameValueCollection config)

    {

        ResetPasswordLength = DefaultResetPasswordLength;

        string ResetPasswordLengthConfig = config["resetPasswordLength"];

 

        if (ResetPasswordLengthConfig != null)

        {

            // Have to remove the config entry as the provider we are

            // inheriting from doesn't understand it and will throw an

            // exception

            config.Remove("resetPasswordLength");

 

            if (!int.TryParse(ResetPasswordLengthConfig,

                out ResetPasswordLength))

            {

                // Have to reset to default as TryParse will set it to 0

                // if the value can't be parsed

                ResetPasswordLength = DefaultResetPasswordLength;

            }

        }

        base.Initialize(name, config);

    }

 

    // Create a more user friendly password to avoid confusion when

    // trying to key in the new value

    public override string GeneratePassword()

    {

        string newPassword = string.Empty;

        for (int i = 0; i < ResetPasswordLength; i++)

        {

            newPassword += GetRandomAlphaNumericCharacter();

        }

        return newPassword;

    }

 

    /// <summary>

    /// Create an array of characters to user for password reset.

    /// Exclude confusing or ambiguous characters such as 1 0 l o i

    /// </summary>

    /// <returns></returns>

    private string[] FillCharacters()

    {

        string[] characters = new string[31];

        characters[0] = "2";

        characters[1] = "3";

        characters[2] = "4";

        characters[3] = "5";

        characters[4] = "6";

        characters[5] = "7";

        characters[6] = "8";

        characters[7] = "9";

        characters[8] = "a";

        characters[9] = "b";

        characters[10] = "c";

        characters[11] = "d";

        characters[12] = "e";

        characters[13] = "f";

        characters[14] = "g";

        characters[15] = "h";

        characters[16] = "j";

        characters[17] = "k";

        characters[18] = "m";

        characters[19] = "n";

        characters[20] = "p";

        characters[21] = "q";

        characters[22] = "r";

        characters[23] = "s";

        characters[24] = "t";

        characters[25] = "u";

        characters[26] = "v";

        characters[27] = "w";

        characters[28] = "x";

        characters[29] = "y";

        characters[30] = "z";

        return characters;

    }

 

    private string GetRandomAlphaNumericCharacter()

    {

        return characters[rnd.Next(characters.GetUpperBound(0))];

    }

}

Bob and Chris Roadshow

Today I am at the Bob and Chris Roadshow - they are doing a whirlwind tour thru various topics such as Visual Studio 2008, Multi Tennant Data Architectures, LINQ and more.

Chris Bowen, Microsoft Developer Evangelist for New ENgland just covered some great new features in Visual Studio 2008. He gave a great presentation, that was not just full of useful information, but jokes too. Some of the highlights for me were:

VS2008 is easy to move to since when you create a new project you can target the version of the .Net framework to be used - so you can use the new IDE to build your .Net 2.0 web application. This is a huge benefit and allows for early adoption. A nice touch is that as you pick the version of the framework you want to use, the list of available project types changes.

 The feature that got the biggest ahhhh - if you are typing in a code window and the intellisense pops up, you can now hold the Ctrl key down and it fades into the background - nice touch.

For web development - the Expressions web editor has largely been incorporated into the VS2008 IDE. This is a great improvement, you can see CSS being applied, create new styles etc. Also - the IDE now supports nested master pages - finally! There are too many features to list here - but if you have used SharePoint Designer or Expressions Web - you will now be able to get a lot of that functionality in VS2008. However if you are a SharePoint developer, like me, you be disappointed to hear that it cannot connect to a SharePoint site - you will still need to use SP Designer for a lot of things. But you can create SharePoint Workflows in VS2008.

For Windows Application Developers there is a new pair of container controls, formerly codenamed Crossbow, now called WinForms WPF Interop, which allow you to host WPF inside a WinForms application or Win Forms controls inside a WPF application. Why is this good? Well if you have somoe custom Win Form controls that you want to use in a new WPF application - you can now host them and use them. From a Win Forms point of view, you can now get all the cool 3D features, Audio etc from WPF in your application.

Building web services is something I have always been a big fan of, but one of the draw backs was the need to build a test harness to exercise the API endpoints. Now with VS2008 you can define the API and then just hit F5 to run debug - VS2008 looks at the API and dynamically provides a UI to allow you pick the function to call and define parameters to be passed and call your API. This is a big time saver for quick testing. Of course you should also write your unit tests - but thats a topic for another day.

Finally, VS2008 professional now includes Unit Testing - this is in response to user demand. However if you want all thye code analysis and coverage etc you will need Team System.

 Great Session, thanks Chris.

Build Versus Buy: PDF Creation

Many times when writing an application, requirements dictate that some of the application output be available as a PDF. Perhaps you are showing an invoice and want a printable, emailable, and nice looking "frozen" copy of the invoice. Or you want to make a non-editable but executable contract copy on the fly. Or perhaps you don't know if the user has Office installed, and you want formatted documents that they can open. Your next thought is, "Someone must have done this before." You search for ".NET component create pdf" and find that there are several components available. You then need to do some research and try to "bake-off" the components, to determine the best combination of development licensing cost, ease of use, runtime license terms, stability (of the component itself) and stability (of the company who publishes the component - will they be around to support this in a year or two?).

We have been in this situation a few times, and can say that Tall PDF component (http://www.tallcomponents.com/) has been great. Supports .NET 1.1 and 2.0, runtime licensing is reasonable, good help and example code, and it gives you a ton of functionality that would take you forever to write on your own. If this helps you short-circuit your bake-off, we are glad to help. We have three successful projects where we have used it, and it works great.