Microsoft Exam 70-547 Beta

Today, I took advantage of the free offer from Microsoft to take a beta exam for free.  In case you missed the memo, I put the details about the free beta exams at the end of this post.  The beta exam I took was 70-547: Designing and Developing Web-Based Applications using the .Net Framework.  Since it was a beta exam it was a pretty lengthy exam of 71 questions that took three hours long.  Here are some notes about the exam:

  • Since it was a design exam, there were a lot of questions about if a solution solved all of the requirements given.  So they stated the requirements and then told you what the solution was and you have to decide if the solution met the requirements, or select a reason as to why it did not.  This got real redundant, but I think that was because I was taking a beta exam.  I think they were really trying to figure out what questions would be good ones to ask for the real exam.
  • There were about 5-10 questions or so on the new ASP.NET health check API.
  • There were about 5-10 questions in regards to writing test cases using VS 2005.
  • There were a few questions that asked you to design out a class when given a certain set of requirements.  This was not your normal multiple choice question either.  They did help you along a bit and gave you a list of methods and properties that you have to move into your class.
  • There were also questions in regards to how to handle exceptions correctly and ensure that you maintain a proper stack trace across tiers such as presentation, business, and data.  Also, how to configure apps so that end users don't see the error, while admins can.
  • There was not a lot of code in this test, whcih was NOT a surprise since it was a design test.
  • Just a few questions on what controls to use when in your design.  There was a question about the datagridview control and master pages.  These questions were more interested in how to work these new features into your design.

Beta Exam Info:

Through March 12 Registration is open for free beta exams, which count toward certification in the same way as the final version of the exam. Candidates who achieve a passing score in the beta exam will receive a free exam voucher* for any Microsoft Certification Exam. Vouchers will be sent after exam scores are tabulated.

  • Exam 71-547 Pro - Designing and Developing Web-based Applications by Using the Microsoft .NET Framework (promo code: PRO547)
  • Exam 71-548 Pro - Designing and Developing Windows-based Applications by Using the Microsoft .NET Framework (promo code: BTA548) 
  • Exam 71-549 Pro - Designing and Developing Enterprise Applications by Using the Microsoft .NET Framework (promo code: 549BTA)

Seating is limited. Pre-register via http://securereg3.prometric.com/.

Winforms and SendMessage

I finally got a project where I can start playing with some winform stuff.  I have been doing .net for a few years now, but only in the c#/asp.net world.  I now have the chance to write an application in a winform environment, which I have been looking forward to.

One of the things I wanted to play with was customizing the listview.  I wanted to set the listview up so that the column widths automatically adjust their width based on the data that is being displayed within them.  Back in my VB6 days, we ended up subclassing a lot of the common controls and I have used Randy Birch's vbnet web site quite a bit, so I figured I would start there for the info. Since all of the code is in VB, I use this little vb to c# converter to convert some of the constants and such.

The next part was getting the send message called defined, so here is what I came up with:

    public class UnsafeNativeMethods

    {

 

        public const int LVM_FIRST = 4096;

        public const int LVM_SETCOLUMNWIDTH = (LVM_FIRST + 30);

        public const int LVSCW_AUTOSIZE = -1;

        public const int LVSCW_AUTOSIZE_USEHEADER = -2;

 

        public UnsafeNativeMethods()

        {

        }

 

        public IntPtr SendMessage(IntPtr hWnd, int msg, int wparam, int lparam)

        {

            return UnsafeNativeMethods.SendMessage(new HandleRef(this,hWnd), msg, wparam, lparam);

        }

 

 

        [DllImport("user32.dll", CharSet=CharSet.Auto)]

        internal static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);

 

    }

Once I got that defined, I was able to create a method that would setup this extended style for my ListViewEx control:

            UnsafeNativeMethods methods = new UnsafeNativeMethods();

 

            for( int x=0;x<Columns.Count;x++ )

            {

                methods.SendMessage( this.Handle, UnsafeNativeMethods.LVM_SETCOLUMNWIDTH, x, UnsafeNativeMethods.LVSCW_AUTOSIZE_USEHEADER );

            }

One final thing I had to do for the listview was to ensure that when the listview was resized that the far right column fills out the unused area of the listview.  To ensure this, I had to override the WndPrc method and capture the onpaint method and reset that style:

        protected override void WndProc( ref Message message )

        {

            const int WM_PAINT = 0xf ;

 

            // if the control is in details view mode and columns

            // have been added, then intercept the WM_PAINT message

            // and reset the last column width to fill the list view

            switch ( message.Msg )

            {

                case WM_PAINT:

                    if ( this.View == View.Details && this.Columns.Count > 0 )

                        this.Columns[this.Columns.Count - 1].Width = -2 ;

                    break ;

            }

 

            // pass messages on to the base control for processing

            base.WndProc( ref message ) ;

        }

Krypton Toolkit

I just started my first project that involves creating a winform app.  While researching some various UI controls that I can  use within my app I came across the Krypton Toolkit that has been  recently released with a free commerical license.  I was looking for something that was designed for the 2.0 framework, which this library is.

Some of the controls:

Krypton Button
Krypton Group
Krypton Header
Krypton HeaderGroup
Krypton SplitContainer
Krypton Panel
Krypton Label

 

Download here, http://www.componentfactory.com/downloads.php

Stored Procedure Debugging

Yesterday I saw that one of my co-workers was connecting to SQL Server through Visual Studio and figured I would give it a try.  Normally I use query analyzer but I liked the idea of working with Sql Server within Visual Studio, but forgot you can do that.  As I was writing some stored procs and playing around with some data, I noticed an option on the context menu, "Step Into Stored Procedure" which allows you to debug and walk through stored procudures.  So I gave it a whirl, and man will this be a huge time saver.  You have all your normal debug windows available such as watches and auto so you can look at variables, which is a lot better than the print statements I used to use.

Blog Question

What is the difference between a blog post and an article?

Also, if you guys have some code that you want to provide for download with a post/article, how do you guys usually do that?

Community Server COJAX Code Viewer

Over the next few weeks I'll be posting a series of articles about what I am learing from looking through the Community Server source code and how I am working some concepts into my applications. 

One tool that I find extremely helpful in doing so is the COJAX tool that they put together.  This is a code viewer tool that uses AJAX to display the code for the application.

Check it out at http://code.communityserver.org

 

Reading Config Values

Over the past few weeks I have taken the advice of a few people and have started using Community Server as a model for the applications I am working on.  Community Server is a very complex application and as I study it more, the more I learn and start to see how I can integrate some of their designs into my applications.  To check out the latest code tree for CS, visit CoJax at http://code.communityserver.org or visit http://www.communityserver.org to download the source code.

One thing that caught my eye was the way they read configuration values for their application.  In the past when I needed this functionality in my application I would write my own configuration handler for the web.config file, and then write a custom object that the xml data from the config file could be serialzied into.  I saw this approach done in other articles and applications and it was pretty easy and "SEXY" to implement.  One drawback that I saw to this approach though was the fact that the data was stored in the web config file so when a change was made to the configuration the application would be restarted.  Another drawback that I was always concerned about was the cost of the serialization of the xml data into the custom object.

In community server they have their own configuration file that gets loaded into a CSConfiguration object.  Instead of serializing the data into a custom object, they process the xml document using the DOM and populate the properties of their custom configuration object.  What I really like about this approach is the fact that it provides a clean and straight forward way to set the default values of the object.  You can also establish your own config file that will not cause the application to restart.  Instead, what you can do, which is what Community Server does, is store the custom config object into the cache, and create a cache dependency against the config file so when changes are made to the config file the cache reference will expire.

To see an example of this check out the links above and look for the CSConfiguration.cs class file located at "CS Tree \ CS 1.1 \ Components \ Configuration \ CSConfiguration.cs

I like my new home

Well, I took Dave up on his offer to setup a new blog for me and so far I am happy with my new home.  I am very excited to be running on the latest version of Community Server.  I just brought over a few of my blog posts from DotNetJunkies and I am happy to report that I did not get any of those nasty errors, but I did get them while trying to retrieve the posts from DotNetJunkies.

I'm glad to make the jump.  While I don't post a whole lot, I am really trying to start posting more but my problem has always been topics.  What I am going to start doing though is start blogging more about what I am currently working on, and how I accomplished certain tasks.  Then, hopefully through other blog posts or comments, people may suggest better/different ways of doing things.

Happy Blogging!

Share session state across virtual directories

I just got done reading Peter's post about a limitation he ran into about sharing session variables across web applications, and thought I would blog about an approach we recently took with one of our web apps to get around this problem.

We got our solution from this MSDN article, which shows you how to separate out your web applications into smaller web applications. The first step is to create an IIS application and this is the root of your web application. Under this root, you create your smaller modules as virtual directories, but don't configure them to have their own web application. (now refer to the article to see how to make this friendly to VS.Net) Now, because the root is setup as a web application, this is the guy that manages your session state for all of the modules below it, and our session state can no be shared across all of the different modules.

Now I understand that this won't be for everyone, but in our case it has worked out great. We are currently building a pretty large web system that consists of various modules, and one requirement we would like to satisfy is to allow us to deploy each module separately but also be able to share session state across all of the modules. We have a main IIS root application and each module is setup as a virtual directory under it. The root, and each of the modules each has its own ASP.NET web project and can be compiled separately. This would allow us to only update specific modules when needed. So now when we make changes to just module A, we can build the web app for module A, plus all of its supporting assemblies.  By having all of the modules under the root, all of the modules can now also share session state.

Hope this makes sense, but if it doesn't the MSDN article will really clear things up since they provide good instructions on how to get everything configured.

Debug your Javascript

Clarke Scott just posted about some free tools that could be found at http://devcenter.infragistics.com/.  While I was there I noticed an article about JavaScript debugging and decided to see if there was anything new there. (A direct link to the article is http://devcenter.infragistics.com/Articles/ArticleTemplate.Aspx?ArticleID=2183  I have never seen this technique for debugging JavaScript before and it will be a true time saver for me to help debug all the JavaScript we do in our apps.  If you are looking for a way to debug JavaScript you need to check this article out.  While the IE script debugger has always been available it has never worked well enough for me as I had numerous problems with it and it also did not debug JavaScript include files.  This technique does just that.

Here is a snipped from the article as a reference.  I did this just in case they ever take down the article.
--------------------------------------------------------------------------------

ASP.NET has many advantages over classic ASP in the area of debugging. You can now easily debug your server-side code using the full power of a modern debugger such as Visual Studio .NET. This, along with the introduction of server controls and a postback architecture, has simplified Web-based development. But what about the other half of a Web application, the client-side script?

Although server controls and postbacks have reduced the need for Web developers to interact with JavaScript in an ASP.NET application, many developers are learning that they cannot forget about client-side scripting altogether.

Developers creating Web pages designed to display even a moderate amount of data know the cost of posting back to the server. Using JavaScript to perform simple tasks minimizes the number of roundtrips to the server, potentially avoiding unnecessary queries to the database and reducing the number of times the ViewState is pushed over the wire.

Besides reducing the amount of network traffic, the use of client-side JavaScript enables ASP.NET developers to provide a richer and more interactive experience to the end-user. By moving appropriate functionality from the server to the client you provide the user with instant responsiveness and feedback without the latency implicit in a postback. Balancing functionality between both the client and the server helps reduce some of the load on the Web server, which in turn yields better server response times.

A substantial roadblock to using JavaScript, though, is that it can be difficult to write and debug.

First, IntelliSense for JavaScript is limited at best, which leads to errors in the initial coding stage. Because JavaScript is case-sensitive, the lack of IntelliSense can be aggravating - particularly for developers turning to ASP.NET from a case-insensitive language like Visual Basic.

Also, when a browser's JavaScript error message provides a line number to look at, it often doesn't match the line numbers indicated in the code. The line number will get you in the right area, but after that, it often becomes a guessing game.

Furthermore, if you try putting a breakpoint in the JavaScript in your ASPX, you'll find that when running the project, control will not stop on it and, at best, you may get the not-so-helpful message, "Breakpoint will not be hit, symbols have not been loaded for this document."

Tap into HTML

With Internet Explorer 6 and VS .NET, Microsoft has provided a way to tap into the HTML and JavaScript that Internet Explorer is running, thereby closing the loop in the debugging cycle. By closing this hole developers can now debug their entire application in a single IDE - from client-side script to server-side code, and possibly right through to the database.

Unfortunately for most developers, this won't work without some basic set up. To verify that Internet Explorer is set up correctly, open Internet Explorer, choose Tools | Internet Options. Click the Advanced tab and find Disable script debugging about halfway down the list. Make sure there is no check in the box next to this option. Click OK and close Internet Explorer. The browser is now ready to work with Visual Studio .NET to debug your application.

To begin exploring the basic functions of the debugger, start a new WebForms project and run it without adding any controls or code. When the empty project loads in Internet Explorer, return to Visual Studio and open the Running Documents window by selecting Debug | Windows | Running Documents from the Debug menu.

The Running Documents window will appear docked on the right edge of the IDE. The name of the page, "WebForm1.aspx", will appear in the window. Double-click the page and the HTML rendered to the browser when the ASPX page was evaluated by the server will be shown in a code window on the left.

The code provided by the Running Documents window is where a developer can set breakpoints and step through the code, just like in server-side code.

Debug Startup Code

Unfortunately, the technique described above breaks down when you try to debug code that executes on start up, such as from a server-side Page.RegisterStartUpScriptBlock method in the page load event. Because the JavaScript code runs as the page loads, you have no opportunity to return to the IDE to set a breakpoint.

Debugging startup script code requires a different method for debugging. There are three ways to debug startup script. First, start your project with F10. Pressing F10 will load your default startup page in the browser and immediately put you in break mode on the first line of JavaScript. You can then set another breakpoint elsewhere in your code, or you can step through line by line until you reach the line of interest.

Next, run the page, let the error occur, then set the breakpoint and hit F5. This method comes in handy when you receive an unexpected error. After the page has loaded in your browser and you get an error or incorrect behavior, open the appropriate Running Documents window and place a breakpoint where you would have wanted execution to stop. Return to the browser and hit F5. Visual Studio .NET will recognize that this is the same page you loaded before and will keep your breakpoint in place. When execution reaches the breakpoint, control will return to the IDE.

Finally, use the debugger keyword. The debugger keyword works just like a breakpoint. When the JavaScript interpreter reaches this keyword, it halts execution and returns control to the IDE.

Debugging startup script is a little more difficult than debugging script behind a button click or a validation routine because it is hard to insert a breakpoint at the right place. Starting the page with F10 or using the debugger keyword can help break into the code. From that point, a developer can find the errors in his logic using the same powerful tools he is accustomed to using with server-side code.

Visual Studio .NET provides the same powerful and flexible tools for debugging your client-side code as it does for server-side code. Get the most out of Visual Studio .NET by using the techniques described here to close the loop and debug your entire ASP.NET application in one IDE.

ASP.NET Tracing as a popup window

I just saw Dino's post on his wish list for ASP.Net tracing and saw he wanted the tracing window in a popup window.  This is something we wanted for our web apps as well, so here is how I tackled the problem. I know its not perfect and the output is still put out to the main page, but the reason why I had to come up with this scheme was because in our web apps we are using absolute positioning. When we did this our content was placed over the top of the trace div.

Here is the code.....

============== Parent ASPX Page =================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
 <HEAD>
  <TITLE>Parent Page</TITLE>
  <SCRIPT>
  function SetupTraceWindow()
  {
   var div = GetTraceDiv();
   if(div==null) return;
  
   win = window.open("Trace.htm","Trace");
   if(win==null) windown.status="The trace window was blocked.  Please make sure popup blockers are off.";
  }

  // Called by the child window to get the html of the trace output and also hides the trace output on the parent page.
  function GetTraceHTML()
  {
   var div = GetTraceDiv();
   if(div==null) return "";
   var html = div.outerHTML;
   div.style.display="none";
   return html;
  }

  // Returns the div that is created by the ASP.Net trace function
  function GetTraceDiv()
  {
   var div = document.getElementById('__asptrace');
   return div;
  }
  </SCRIPT>
 </HEAD>
 <BODY ms_positioning="GridLayout" onload="SetupTraceWindow();">
  <FORM id="Form1" method="post" runat="server">
  This is the parent page.
  </FORM>
 </BODY>
</HTML>

======================= Trace.htm =======================
<!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
<HTML>
<HEAD>
<TITLE>ASP.Net Trace Output Popup</TITLE>
<SCRIPT language="javascript">
function SetupTrace()
{
 var html = opener.GetTraceHTML();
 document.writeln(html);
 opener.focus();
}
</SCRIPT>
</HEAD>
<BODY onload="SetupTrace()">
<DIV id="myTrace"></DIV>
</BODY>
</HTML>

Control Your ViewState

I just came across a post on the asp.net forums about wanting to control how view state is saved with a page. As we all know by default view state is rendered as a hidden element on the page, but that can easily be changed and you can set your pages up so that viewstate is saved to the cache, session, or the database.

The first step I would suggest is to create a base page for your aspx pages and override two methods, LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium. As you can tell by their names, these are the two methods responsible for determining how view state is actually handled in the page.

The following is what I put together for the SavePageStateToPersistenceMedium method. This method will take the viewstate object that is passed in and run it through a special formatter to serialize the object. According to MSDN, the LosFormatter object is designed for highly compact ASCII format serialization and serializes the view state for a WebForm page. Once the object has been serialized, I then save the viewstate to a session variable. I used a session variable for demonstration purposes only, but once the object has been serialized, it can be saved to session, cache, or a database. Here is the code for the SavePageStateToPersistenceMedium method:

protected override void SavePageStateToPersistenceMedium(object viewState)
{
     // Saftey check to ensure we have a valid object
    
if( viewState==null) return;
     
     // Instantiate the formatter used by the framework to serialize viewstate
    
LosFormatter formatter = new LosFormatter();
     // We need a stream writer to write the viewstate text to
    
StringWriter writer = new StringWriter();
     try
     {
          // Serialize our view state to the string writer
         
formatter.Serialize( writer, viewState );
          // Save the view state to session state
         
Session["ViewState"] = writer.ToString();
     }
     catch
     {
          throw new HttpException("Invalid view state"); 
     }
     finally
     {
          // Clean up
         
writer.Close();
     }
}

The next step is to override the LoadPageStateFromPersistenceMedium and load the viewstate data from the same location it was saved to in the SavePageStateToPersistenceMedium method. This is where we take the data out of our session object and then deserialie the data. Here is the code for the LoadPageStateFromPersistenceMedium method:

protected override object LoadPageStateFromPersistenceMedium()
{
     object viewStateObj = null;
     // Instantiate the formatter used by the framework to serialize viewstate
     LosFormatter formatter = new LosFormatter();
     // Grab our viewstate from session
     object sessionViewState = Session["ViewState"];
     try
    
{
          // Deserialize the object
          viewStateObj = formatter.Deserialize(sessionViewState.ToString());
     }
     catch
    
{
          throw new HttpException("Invalid view state");
     }
     return viewStateObj;
}

Once you implement this code, you will notice that a hidden viewstate field is still dumped out into your page, but its empty.