navigation
 Sunday, February 21, 2010
We, at Falafel, are very excited to be exhibiting at MIX in Las Vegas between March 15 – 17 2010.  We hope you will stop by and say hello.  We will have some fun T-Shirts to give away :)  It will be an excellent conference as usual with tons of news and announcements that will shake the software industry. I am excited to be there this year to see what’s in store for Silverlight, Mobile, ASP.NET, MVC, did I mention Mobile :)
See you there!
 
     
posted on February 21, 2010  #    by Lino Tadros  Comments [0]
 Friday, January 22, 2010

This is a very important placement. The Global 100 is Red Herring’s roll of the top 100 privately held global tech companies; sort of "the Fortune 500 list but for tech", according to Stephen Forte's blog. Our industry looks to this list to see who the next mover and shakers are.

Previous winners inclue Skype, YouTube, Salesforce and of course Google.

Finalists are selected from the regional recipients or finalists of the Red Herring 100 awards in 2007, 2008, or 2009 from Asia, Europe, and North America. The award is based on their technological innovation, management strength, market size, investor record, customer acquisition, and financial health.

Congratulations Telerik!

FALAFEL is proud to serve as Telerik's consulting and training arm.

For very interesting info on Telerik, see Stephen's blog at: http://www.stephenforte.net/PermaLink,guid,9f76e8ed-67fe-4730-8754-f2144c0cb546.aspx

posted on January 22, 2010  #    by Anneke Leigh  Comments [0]
 Thursday, July 02, 2009

On July 1st 2009, Falafel presented a 90 minute Webinar on the WebAii Framework and the Automation Design Canvas product from ArtOfTest.  The Webinar touched on several areas like using the Automation Design Canvas in Visual Studio 2008, TestRegions, Browsers, AJAX testing and most of all Silverlight application testing in the new Q2 2009 Beta 2 release.

You can view the recording of the Webinar below, make sure you view it full screen.  We hope you enjoy viewing the video and get a better understanding of the whole framework.

Let us know what other Webinars and videos you would like to see about these topics for future presentations.

posted on July 2, 2009  #    by Lino Tadros  Comments [0]
 Friday, May 29, 2009
If you're like me, you sometimes use AJAX controls in your web page. And, if you're like me, you find that when they fail to behave as expected, you as the user are not notified as to the reason. Instead, the page will just stare back at you blankly: no spinning globe, no twirling fox to indicate that it is processing your request. Of course, what's really happened is that your AJAX request caused an unhandled exception on the server and the request was canceled. If you're like me (and if you've read this far I am forced to conclude we must be twins) you'd like some visibility into that unhandled exception.

There is a quick and easy solution! Simply add the following to your ASPX code-behind and during your debugging session Visual Studio will report the exception being thrown, complete with the exception message and stack trace. If you'd like to report the exception to the user, you would wrap the inner call in a try/catch block and update your UI (or Logging) accordingly.

Good luck!

C#
protected override void RaisePostBackEvent(IPostBackEventHandler source, String eventArgument)
{
    base.RaisePostBackEvent(source, eventArgument);
}

VB.NET
Protected Overrides Sub RaisePostBackEvent(ByVal source As IPostBackEventHandler, ByVal eventArgument As String)
    MyBase.RaisePostBackEvent(source, eventArgument)
End Sub

posted on May 29, 2009  #    by Brad Divine  Comments [0]
We, at Falafel Software, are very excited that for the second year in a row, Telerik training has won the ASP.NET PRO Readers’ Choice Award for Training.  This year is extra special as the award went to the Telerik Trainer, a WPF based training tool Falafel developed for Telerik and has been gaining tremendous success and adaptability in the market since its release last year.  Microsoft Germany has standardized on Telerik Trainer for all their Visual Studio Express offering on the MS Germany site.
Since 2006, Falafel Software has been providing all Telerik training & Consulting worldwide and it has been a tremendous honor and a rewarding relationship.  Congratulations! to the Telerik team and the Falafel team as well! :)
Telerik Collects 12 Awards at asp<i>.</i>netPRO Readers' Choice Awards
posted on May 29, 2009  #    by Lino Tadros  Comments [0]
 Wednesday, April 01, 2009

Our dear friend at Falafel Software Gary Campbell, this week, achieved MCP Certification status (Microsoft Certified Professional) on ASP.NET.  Congratulations Gary! 

Gary has been a solid member of the team working on the latest and greatest of technologies for our customers with great success.

posted on April 1, 2009  #    by Lino Tadros  Comments [2]
 Wednesday, February 11, 2009

Are you looking for training on Telerik’s radControls for ASP.NET AJAX? Why not learn directly from the people who wrote the book on it. Falafel has played a large part in Telerik’s customer education efforts and we can bring that knowledge directly to your organization where you can learn from the pro’s.

Check out the Telerik page on our website for details on our online, onsite and open classes hosted here on the Monterey Bay.

Falafel also offers consulting services on Telerik’s products and for a taste of what the Falafel team can do for your next project take a look at Telerik’s Trainer software written entirely by the Falafel team using Microsoft’s WPF platform.

[Update: March 16, 2009] For list of our upcoming training classes click here.

posted on February 11, 2009  #    by Steve Trefethen  Comments [1]
 Monday, September 15, 2008
My latest challenge is to learn everything there is about Sitefinity. When I first came to Falafel, one of my first assignments was to update some of Falafel's DNN modules, one of which was QuoteMax. This was a simple module that would manage a list of quotes and would pick one for display upon each page load. Of course, you might have a hard time saying any DNN module development was simple. In any case, this simple control would be my first try at custom Sitefinity development.
 |  |  |  | 
posted on September 15, 2008  #    by Bary Nusz  Comments [2]
 Thursday, July 17, 2008
.NET 3.5 includes new abilities to easily leverage web services and Windows Communication Foundation (WCF) services from AJAX enabled web applications.
posted on July 17, 2008  #    by Noel Rice  Comments [2]
 Wednesday, July 16, 2008
By the time I found the handy JavaScriptSerializer class, it had been introduced, deprecated and brought back from the hellish purgatory where Microsoft keeps objects that have outlived their usefulness.
 |  | 
posted on July 16, 2008  #    by Noel Rice  Comments [0]
 Monday, June 23, 2008
See a solution for a common problem encountered with the built-in ASP.NET membership controls
posted on June 23, 2008  #    by Adam Anderson  Comments [0]
 Monday, May 26, 2008
Read about a cool hack in Visual Studio 2008 SP1 that allows the designer to fall back on a hardcoded master page if it doesn't manage to locate the correct one.
posted on May 26, 2008  #    by John Waters  Comments [0]
 Friday, April 25, 2008
This week I needed a particular VisualStudio 2005 project template called "ASP.NET AJAX-enabled Web site" and I could not for the life of me get it to show up. Here are the steps I used to fix it.
posted on April 25, 2008  #    by Aaron Rhodes  Comments [1]
 Tuesday, April 15, 2008
After a Vista upgrade none of my .NET 3.5 web applications would run! Visual Studio gives a "Child nodes not allowed" error for the web.config file, but there is a simple solution - once you find it.
posted on April 15, 2008  #    by Rachel Hagerman  Comments [3]
 Friday, April 11, 2008
Passing Microsoft Exam 70-315 Web Applications with Visual C# and Visual Studio.NET - A recent exam-taker's experience and tips for success.
 |  | 
posted on April 11, 2008  #    by Rachel Hagerman  Comments [0]
 Monday, March 10, 2008
ControlParameters are a really nice way to declaratively define the behavior of DataSources, but often you need values that aren't directly in controls. Here is how to bind a ControlParameter so that it reads any page property you define.
posted on March 10, 2008  #    by Adam Anderson  Comments [1]
 Monday, February 25, 2008
With new technology making the web a viable option for more and more applications, we are now seeing the web browser take over for the traditional desktop. Developers making this transition, quickly learn about some of the key differences between the two paradigms. One of the issues they are often forced to deal with is Session expiration. Out of the box, ASP.NET and IIS typically allow only 20 minutes of idle time before the session expires. This can be configured, but knowing that the session expired, or redirecting to a particular page often comes in handy. One way to do this is to add a cookie during the Session_Start method of the global.ascx.cs file, and then check for that same cookie the next time a session is created. If the cookie is there, the session either timed out, or was reset.
posted on February 25, 2008  #    by Mike Dugan  Comments [0]
 Thursday, February 21, 2008
I was designing a load test against Active Focus the other day using TestComplete. I kept getting the error "Connection 0 of the task assigned to the virtual user VirtualUser1 was simulated partially. Only 3 of 41 requests were completed." in the test log.
posted on February 21, 2008  #    by Falafel Author  Comments [4]
 Monday, December 17, 2007
Three ways to access the query string as key-value pairs.
posted on December 17, 2007  #    by Adam Anderson  Comments [1]
 Tuesday, December 04, 2007
This technique is useful to show a page immediately upon request, then begin loading data after the page appears in the browser.
posted on December 4, 2007  #    by Adam Anderson  Comments [0]
 Tuesday, November 20, 2007

Falafel is partnering with Microsoft to offer this free half day seminar at the beautiful Saint Claire hotel in downtown San Jose, CA to celebrate the release of Visual Studio 2008, LINQ, WPF, WCF, WF and other exciting technologies.

ActiveFocus Hosting

Please join us on December 10th from 9:00 AM to 1:00 PM
Register on the Microsoft event site ASAP as space is limited.

Charlie Calvert, the C# Community Project Manager will be there to talk about LINQ and Lino Tadros will present the usefulness of the new technologies.
Hope to see you there!
 |  |  |  |  |  |  |  |  |  | 
posted on November 20, 2007  #    by Lino Tadros  Comments [0]
 Tuesday, November 06, 2007
Read about the problems I encountered and the final solution I arrived at. Source code inside.
posted on November 6, 2007  #    by Adam Anderson  Comments [23]
 Saturday, November 03, 2007
We will be in Las Vegas between Nov 5th and 8th exhibiting at booth # 832. Please stop by and say hello, we have a cool T-Shirt for you and some other goodies! We will be demonstrating our Project Productivity Management Solutions "ActiveFocus 2007" and we will also be showing a sneak peek at ActiveFocus 2008 due at the end of this year. If you can't find us in the booth, look in the Rum Bar at Mandalay Bay or the Craps table near by
posted on November 3, 2007  #    by Lino Tadros  Comments [1]
 Monday, September 17, 2007
Here is an interesting thing I noted the other day. I have an ASP.Net 2.0 application, and in one of the forms, I store the search criteria that you enter on that page in an instance of my ScheduleSearchCriteria class:
posted on September 17, 2007  #    by John Waters  Comments [1]
 Monday, August 27, 2007
If you need to share resources across multiple pages you can use global resources as opposed to the local resources shown in the previous blog. Global resources are implemented using explicit binding, i.e. server tags like this one:
posted on August 27, 2007  #    by Noel Rice  Comments [0]
 Monday, August 20, 2007

ASP.NET 2.0 has a rich set of localization features built-in. Early in the ASP.NET 1x lifecycle we "rolled our own" using an HTTP handler that reflected for a [localize] tag, looked up the control name in a resource file and assigned the localized value.  I prefer out-of-the-box solutions though when available and the MS resource provider model approach provides enough flexibility to be worthwhile.

ASP.NET 2.0 Localization adds two new resource flavors: local and global resources.  Local resources are used for controls on a specific page. The resources are located in the ASP.NET App_LocalResources folder with the same name as the page you're localizing.  So, if you're translating default.aspx then your App_LocalResources might also contain default.fr-FR.resx with a French translation. Global resources are contained in App_GlobalResource and can be used anywhere in the application.

You bind resources to your controls using explicit or implicit expressions. Explicit expressions use an inline server syntax similar to the data binding syntax you're already familiar with.  Implicit expressions syntax use a "<meta>" tag in the control you're localizing to identify the resource.

Local Resources, Implicit Expressions

It all makes more sense in practice so here's a basic walk-though using local resources with implicit expressions:

  • Create an ASP.NET web application.
  • Add a TextBox control to the default form.
  • While you're on the page to localize (default.aspx in this case), select Tools |Generate local resources. This step has a number of effects. 
    • An App_LocalResources folder appears populated with "Default.aspx.resx". 
    • In the Source view, the ASP.NET markup page tag will have a Culture="auto" attribute added. The value of "auto" lets the application react to the browser language settings.
    • In the ASP.NET HTML markup for the control will have a "meta:resourcekey" attribute added:

      <asp:TextBoxID="TextBox1" runat="server" meta:resourcekey="TextBox1Resource1"></asp:TextBox>

      This identifies a single element in the ASP.NET HTML markup.  If there are other nested elements, each needs to be marked with a "meta:resourcekey" attribute before you can implicitly bind to them (as when you have BoundField elements within a GridView for example).  The general rule is, if the element is qualified with a namespace, it needs a "meta:resourcekey" attribute.

    • The properties are marked with an icon that show they are implicitly bound.

image

  • Double-click default.aspx.resx to edit the resource. This will contain resources for the page as a whole and for any controls on the page. The naming convention for resources is <resourcekey>:property name (you typically don't have to know that, but if localization support for a component is incomplete you can still add the "meta:resourcekey" tags by hand). Add text for the page title and TextBox Text property.

Resource for Default.aspx

  • Copy default.aspx.resx to default.aspx.fr-FR.resx.
  • Edit the values in the resource file to French translations.  You can use a tool like Google Translate to get a fair approximation of what the translation should look like. I wouldn't use it as a production tool though unless you want chuckles from the target audience (try translating to and from the target language a few times and you'll see what I mean). 

image

  • Run the application.  Assuming Internet Explorer as your browser, go to Tools | Options | Languages.  Select the "fr-FR" culture code, then refresh the page and Voila! (or "Blick dort!" or "sguardo là!".  Hmm, sure hope I'm not insulting anyone).

image

Slightly More Complex Scenarios

The same pattern works for more complex objects, such as GridView.  Notice there is a "meta:resourcekey" for the grid and also for each of the BoundField objects.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" meta:resourcekey="GridView1Resource1"> <Columns> <asp:BoundField DataField="ProductName" HeaderText="ProductName" meta:resourcekey="BoundFieldResource1" SortExpression="ProductName" /> <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" meta:resourcekey="BoundFieldResource2" SortExpression="UnitsInStock" /> </Columns> </asp:GridView>

Again, you can bind to any resourcekey/property name combination:

image

And because the page Culture is set to "Auto", you can change the browser language settings and the translated text is displayed automatically:

image

 

The localization facilities built-in to ASP.NET 2.0 should save you some time if they fit your requirements.  If you need a heavier weight solution that uses a database (or other data store) instead of XML to store resources, check out this article by Jeff Modzel "ASP.NET 2.0 Custom SQL ResourceProvider".

posted on August 20, 2007  #    by Noel Rice  Comments [1]
 Sunday, August 12, 2007

I was configuring Custom Errors in the web.config of my ASP.Net 2.0 application, and set it up as follows:

<customErrors mode="remoteOnly" defaultRedirect="~/Error.aspx">
  <error statusCode="403" redirect="~/AccessDenied.aspx" />
  <error statusCode="404" redirect="~/Error404.aspx" />
</customErrors>

I had found the syntax on MSDN. To my surprise, the applicationm wouldn't start, it told me there was something wrong with the value of the mode attribute.

So I went back to MSDN and noticed I had looked at the .NET Framework 1.1 documentation. Clicking on the corresponding 2.0 documentation, I found it had changed to initial Caps:

<customErrors mode="RemoteOnly" defaultRedirect="~/Error.aspx">

Duh! I guess my chances of getting this right the first time were remote only...

posted on August 12, 2007  #    by John Waters  Comments [1]
 Tuesday, July 31, 2007

The other day I was trying to figure out why the ItemCommand associated with an ImageButton in a DataGrid had stopped firing and was surprised by why...

Here is the grid in action:

When I clicked on any of the ImageButtons in the grid, the page did post back, but the ItemCommand didn't fire. I experimented with binding the grid at different points in the page lifecycle, but that didn't help. I also tried switching from a DataGrid to a GridView, thinking such a drastic change might get rid of whatever oddity was going on. No such luck.

Finally, I noticed that the grid attribute EnableViewState was false. Originally, this grid had contained some template items with editable content, including text boxes, drop down lists and checkboxes, and ViewState was turned on. But I replaced that functionality with some client side logic using JavaScript and JSON web service calls, so I figured no viewstate was needed any more, and had turned it off. It wasn't until a few weeks later when someone clicked on these image buttons that the problem showed up.

So, long story short, I changed EnableViewState to true, and voila, it started to work again. It beats me why viewstate is needed for a command event to fire when an image is clicked (I could see the image.x and image.y variables in the postback even when it was turned off), somehow the event bubbling from the image click to the containing DataGrid's ItemCommand handler (RowCommand in the GridView) is dependant on viewstate being turned on. If anyone knows why I am all ears!

posted on July 31, 2007  #    by John Waters  Comments [1]
 Tuesday, July 24, 2007

So you have a cool asp.net application and everything is running great. You're running it under NET 2.0 and you're using a report server on the same machine. It may run great for months, and then out of nowhere your web application starts displaying the “Service unavailable” page. It does this until you do an iisreset. Where did this message come from? I recently had to find out for myself. My search lead me to the Event Viewer on the server and five warnings about various system failures that read something like this:

A process serving application pool 'ASP.NET V2.0' suffered a fatal communication error with the World Wide Web Publishing Service.

After the fifth warning I would get the following error:

Application pool 'ASP.NET V2.0' is being automatically disabled due to a series of failures in the process(es) serving that application pool.

After the iisreset, things would go OK, but eventually the above warning/error pattern would repeat. What was going on? Why five warnings, the single error, and then the “Service unavailable” page? Well, when you search for "Application pool 'ASP.NET V2.0' is being automatically disabled due to a series of failures", you get plenty of hits. There are plenty of ways to get these errors. What I ended up finding out was that my report server and my web application were using the same application pool. I would not think this would be a big deal, until I found this tab in the properties of the application pool within the IIS Manager.

Mystery solved. It was doing exactly what it was supposed to do. The Enable rapid-fail protection was enabled and I had gotten five failures within 5 minutes to cause the application pool to be disabled. Let's say your web application calls for a report from your reports server. If your reports server fails for some reason, you can also get a failure with your web application. Since they are both in the same application pool this is two strikes with one failure. A couple more of these and your application pool gets shut down. Lesson Learned. It's good practice to move the web application and reports servers into their own application pools.

posted on July 24, 2007  #    by Bary Nusz  Comments [0]
 Tuesday, July 17, 2007

There is a pattern to these errors.  Same asp.net source, same database, same IIS version, same Visual Studio version, same components version, but still some chunk of JavaScript is absent without leave. The actual error messages tend to be new each time, but at least the pattern is recognizable. The reason is that the missing JavaScript functions live in webresource.axd, webresource.axd is handled by an aspnet_isapi.dll, and chances are you are missing a mapping for "axd" in your IIS configuration for your web site. To fix:

  • In the IIS Microsoft Management Console snap-in, right-click the virtual directory and select Properties.
  • On the Virtual Directory tab click the Configuration button. 
  • On the Mappings tab of the Application Configuration dialog click the Add button. This brings you to the Add/Edit Application Extension Mapping dialog. Enter for the Executable the full path to aspnet_isapi.dll located in .NET framework directory.  In this case the path was C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll. Set the Extension to be ".axd".  Don't forget the dot or the dialog will not let you proceed. Uncheck the "Check that file exists" checkbox.
  • If the OK button doesn't become enabled, there's a weirdity here (in the tech support business we used to call these "issues", in the real world we call it a "bug").  Click the Executable textbox entry and the OK button should become enabled.

Cycle the website and try again.  Different flavors of this problem occur periodically, so tag this page for later and save yourself some pain.

posted on July 17, 2007  #    by Noel Rice  Comments [0]
 Sunday, July 15, 2007

A while back I was trying to figure out how to make F1 bring up a custom help window in our web application ActiveFocus. It is easy enough to trap a keypress and open a window showing the help, but to my frustration, after popping up the new window, the built in Internet Explorer help window popped up too!

I tried various variations of cancelling the kepress event, but nothing seems to work. This is for instance how I cancel Ctrl+F (which normally pops up IEs built in Find dialog, but I wanted it to show a custom search dialog instead) :

<script type="text/javascript">

function onKeyDownH(e)
{
  e = window.event;

  var ctrl = (e.ctrlKey) ? true : false;
  if (ctrl == true )
  {
    if ( e.keyCode == 70)
    {
      e.returnValue = false;
      e.keyCode = 0;
      ShowSearchPage();
    }
  }
}

function onloadH(e)
{
  document.onkeydown = onKeyDownH;
  return true;
}

window.onload = onloadH;

</script>

This cancelling approach by the way does work for other keypresses, just not F1, which has some kind of special internal handing. After much head scratching I finally stumbled across this simple solution:

<body onhelp="ShowHelp(); return false;">

Here, ShowHelp does the actual showing of the help window.

Simple, huh? If anyone knows how to make this cross browser compatible I am all ears!

posted on July 15, 2007  #    by John Waters  Comments [1]
 Sunday, July 01, 2007

Last week I needed to add some personalization features to our ActiveFocus application, and it seemed like the built in logic around the Profile class in ASP.Net 2.0 Personalization would do the trick. It's actually pretty neat. First, you "declare" your profile data in web.config, something like this:

<profile enabled="true">
  <providers>
    <clear/>
    <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ActiveFocus"       applicationName="/ActiveFocus"/>
  </providers>
  <properties>
    <group name="Grids">
      <add name="MainGridRows" type="System.Int16" />
      <add name="DetailGridRows" type="System.Int16" />
    </group>
    <add name="LastProject" type="System.Int32" />
  </properties>
</profile>

The Properties portion defines the profile data structure. You can use simple data types like System.Int16, nested types (like the Grids property), and your own data types. You can also declare how these types are to be serialized.

When you add a declaration like this to your project, Visual Studio 2005 generates a class for you that implements this data structure (more on how this actually needs a little help for it to work later!). The class basically wraps the HttpContext.Current.Profile object, which is of type ProfileBase. It adds accessors for the members you declared in the web.config file, and sub objects for nested types.

In runtime, the ProfileBase reads and writes it values to a column in the table aspnet_Profile. Here is what it looks like when an instance of the profile class above is written to that table:

UserId                               PropertyNames                                                          PropertyValuesString

7B07AE10-61A7-4DEE-AFF1-172BB42A5E95 Grids.DetailGridRows:S:0:1:Grids.MainGridRows:S:1:2:LastProject:S:3:1: 8202

The profile is tied to user using the UserID column, and the PropertyNames column determines what offset and length in PropertyValuesString each data item occupies. For instance, MainGridRows starts at offset 1 and is 2 characters (so the value is 20). You can use attributes in web.config to control how the properties are serialized.

In code, to access the profile, you just need to declare a property in your form that casts the Profile object of the current Page (or HttpContext.Current.Profile) to a WebProfile (this is the type name of the auto generated ProfileBase wrapper) :

protected WebProfile Profile
{
  get
  {
    return (WebProfile) this.Profile;
  }
}

Now you can read and write the Profile using this property:

tbRowsPerMainGrid.Text = Profile.Grids.MainGridRows.ToString();
tbRowsPerDetailGrid.Text = Profile.Grids.DetailGridRows.ToString();

Here is how you can save it back:

Profile.Grids.MainGridRows = Int16.Parse( tbRowsPerMainGrid.Text );
Profile.Grids.DetailGridRows = Int16.Parse( tbRowsPerDetailGrid.Text );
Profile.Save();

Pretty cool, huh?

Profile data can be stored for authenticated users, but it can also be stored for anonymous users and "upgraded" to an authenticated user if the anonymous user becomes an authenticated user.

So what is the catch with all this magic?

Well, it turns out that this handy dandy auto generating of wrapper classes is only done for Web Site Projects, not Web Application Projects (WAPs)! This is true even of the latest Visual Studio 2005 SP1. I tried doing this in the ActiveFocus WAP, and the compile failed miserably, there was no WebProfile class to be found. I figured this would be easy to Google, and indeed it was, and it turns out that there is a Visual Studio add in on gotdotnet that adds this capability to WAPs, but to my dismay I saw that the gotdotnet site is "being phased out", and the download is gone!

So I turned to my old colleague and friend Charlie Calvert at Microsoft, and he did some digging. He found this post at andornot.com, which references the original post by Scott Guthrie on scottgu.com, and helpfully provides the vanished download!

I downloaded the software and installed it, and now when I right clicked on the web.config node in the Solution Explorer, there was a menu option saying Generate WebProfile:

And what's more, it actually worked! ActiveFocus is now equipped with a user profile capability! Thanks for the help, all of you guys with helpful blogs above! Hopefully this blog will help you too.

posted on July 1, 2007  #    by John Waters  Comments [1]
 Friday, June 22, 2007

I have an ASP.Net 2.0 form that uses Teleriks RadServiceManager to call a web service in the same application. All was working fine, but when I deployed it to another machine, the web service calls failed. I checked the Event Log and found something like this:

 

Request format is unrecognized for URL unexpectedly ending in '/ArtifactSearch/'. 

 

Googling turned up this helpful article. Apparently, web service calls using HTTP GET and POST are disabled by default on 1.1 installations, and I guess that can linger in machine.config or somewhere, and even though my app was a 2.0 app, it inherited these settings. You can enable the calls by adding this to the <system.web> section of your apps web.config: 

 

<webServices>

  <protocols>

    <add name="HttpGet"/>

    <add name="HttpPost"/>

  </protocols>

</webServices>

 

That did the trick for me!

posted on June 22, 2007  #    by John Waters  Comments [0]
 Wednesday, June 20, 2007

Today I worked on an AJAX application that uses JSON over xmlhttp to provide a quick search feature in our product ActiveFocus. Here you can see it in action: as you type in the searchbox, each time a key is pressed, the search string is sent to the server, a freetext search is done against the database, the results are returned in a JSON array, and then rendered as a HTML table:

Originally, this was hand coded in JavaScript at a very low level, using an ASP.Net 2.0 page on the server side to create and return the JSON object. The task at hand was to convert this to a more high level approach using Teleriks RadServiceManager to call a ASP.Net 2.0 Web Service, which returns a standard .NET type that is automatically converted to a JSON object.

In my Search Web Service, I return an array of SearchResultRows:

public struct SearchResultRow
{
  public int ID;
  public string ArtifactType;
  // ...
}

[WebMethod(EnableSession = true)]
public SearchResultRow[] ArtifactSearch( string searchKey)
{
  //…

This was amazingly straight forward. On the client side, when the callback returns, you can access the array through JSON indexing, something like this:

function CallSearch( searchKey )
{
  Search.ArtifactSearch(
    searchKey,
    SearchServiceCompleteCallback, SearchErrorCallback);
}


function SearchServiceCompleteCallback(ResponseAsJSON, ResponseAsXml, ResponseAsText)
{
  var Results = ResponseAsJSON;
  for( i=0; i < Results.length; i++)
  {
    // …
 

After debugging it in FireFox/FireBug (highly recommended! See article by my colleague Noel), I switched back to Internet Explorer 7.0 to test it there, confident that all was well. At first, the search behaved just like it should. But when I typed a search phrase that narrowed the search down to just one record in the returned array, I suddenly found that the table of results did not get displayed at all. It would display two or more results, but not one!

Intrigued, I switched back to FireBug to debug the mystery. But in FireFox, a one row array worked just fine. I could inspect the value of Results and see the JSON encoding, and verify that it was correct. So, I switched back to IE, this time using the VS 2005 IDE Script Debugger, which is pretty primitive compared to FireBug, but I had no choice.

Now, when I went to inspect Results, I found something very strange. When two or more records were returned, the JSON looked just like the FireFox version:

But when the call only returned one row, the JSON object had a different layout! Instead of a JSON  array of SearhResultRow records, there was an inner object named the same thing as the type of the array elements (SearchResultRow), which contained the field values for that one record!

Go figure!

At this point I had spent way too much time debugging and needed to get the job done, so I just added a check to see if the singleton format was present and handled the two different cases in seprate branches of the if statement, which did the trick.

However, I am curious as to whether this is a bug or not. Clearly, it is the same code running both server side and client side, yet in the two main browser versions, the JSON objects differ for one record arrays.

Let me know if you have any input! If not, maybe at least this blog will save you some debugging time…

posted on June 20, 2007  #    by John Waters  Comments [0]
 Friday, June 15, 2007

I just spent some quality time with Firefox and Firebug trying to figure out why my client-side validators weren't preventing a postback when invalid data was entered. The symptoms were puzzling: when I entered invalid data and then attempted to submit the form, the validators would appear briefly, but then the page would post anyway!

A little debugging revealed that the button I was clicking called the JavaScript function WebForm_DoPostBackWithOptions, which called Page_ClientValidate, which called ValidationSummaryOnSubmit. This function looped through a list of validation summaries named Page_ValidationSummaries and then performed operations on each list element, which naturally meant accessing its properties.

ValidationSummaryOnSubmit doesn't test each summary in the list to ensure that the summary is not null before attempting to access its properties, so if a null reference finds its way into this list, an error occurs, which causes the entire call chain to terminate abnormally, in this case resulting in a failure to prevent the form from posting.

A little more debugging followed, and I located where the Page_ValidationSummaries list is initialized, and found which reference was returning a null value. It was a validation summary in the footer of a DataGrid, and the DataGrid's ShowFooter property was false. This of course meant that all of the controls within the footer were never rendered to the client, but the code that generated the list of summaries was including the reference anyway.

The solution to the problem was clearly to find a way to get the generated script to exclude the summary when the footer wasn't visible. I tinkered with a few alternatives, ultimately settling on this one: set the summary's Enabled property to be databound to the expression:

Enabled='<%# DataBinder.Eval( Container.NamingContainer, "ShowFooter" ) %>'

Within templated controls such as a DataGrid, Container refers to the DataGridItem of the current row. DataGrids are naming containers for DataGridItems, so accessing Container.NamingContainer gives a reference to the DataGrid. Eval then uses reflection to find the ShowFooter property of the grid and assign it to the Enabled property of the contained ValidationSummary. My testing showed that with this expression, the summary no longer appeared in the Page_ValidationSummaries initialization list when the footer was hidden, and client-side validation prevented postbacks again. Problem solved!

posted on June 15, 2007  #    by Adam Anderson  Comments [0]
 Thursday, June 14, 2007

If you create a brand-new web application in ASP.NET 2.0 or later, client-side validation will automatically work in Firefox. However, if you have legacy applications originally written in ASP.NET 1.1 or earlier, client-side validation will not automatically work in Firefox. To enable this feature in legacy applications, simply open your web.config file and locate the xhtmlConformance element and change it to this:

<xhtmlConformance mode="Transitional"/>

posted on June 14, 2007  #    by Adam Anderson  Comments [1]
 Monday, May 07, 2007

We recently decided to use Developer Express XtraReports for one of our projects. While it's an impressive product with rich functionality, its design-time support within a web project definitely isn't as robust as it is within a windows project. After some trial and error, I discovered the trick to getting the designer preview tab to work with a parameterized query. Here's how it's done:

  1. In a web project, add a new XtraReport
  2. With the XtraReports designer open, double-click on a DataAdapter. If no DataAdapters are visible in your toolbar (none were in mine by default), you'll have to add them to the toolbar manually.
  3. Configure the DataAdapter using the wizard
  4. In the property grid, navigate to the DataAdapter's SelectCommand | Parameters property. Use the Parameters dialog to set a default value for each parameter. This will enable the report to execute the command at design-time.
  5. Select "Generate DataSet" from the DataAdapter's context menu. In the dialog that appears, make sure to check the box that says "Add this dataset to designer."
  6. The report's DataSource, DataMember, and DataAdapter properties should already be set correctly. Click on the report and examine the properties to confirm.
  7. Try adding a few fields to the detail band of the report, then click the preview tab. After a short delay, the preview should appear!

This approach uses DataAdapter classes directly. The default adapter created by Visual Studio if you create the DataSet first and then add a table will be a TableAdapter. TableAdapters will not work with this approach, because they have no facility to set default parameter values at design time. Unfortunately, the only adapters that appear in the XtraReports' DataAdapter property editor are TableAdapters. However, if you click in the grid and start typing the name of your DataAdapter, the property grid will locate it and assign it to the property correctly.

posted on May 7, 2007  #    by Adam Anderson  Comments [0]
 Sunday, May 06, 2007

I recently ran into an unexpected behavior of SSRS while writing a complex report. The report required various calculations that would refer to specific previous groups and details, and I had decided to solve the problem by writing a custom report function that would evaluate on each detail row, saving the information I would need later in a dictionary. My solution worked fine, as long as my custom calculation in a group footer didn't depend on the contents of that group's details. Upon further investigation, I learned something very interesting about the order in which SSRS evaluates group headers, footers, and details...

Here is how to observe the behavior for yourself: create a stored procedure like this one, that generates some simple test data:

CREATE PROCEDURE dbo.HundredRows
AS
SET NOCOUNT ON

create table #result (
id int,
grp int
)

declare @id int
set @id = 1

while @id <= 100
begin
insert #result
values ( @id, ( @id - 1 ) / 5 )

set @id = @id + 1
end

select *
from #result

This will return a result set whose id column increments in steps of one from 1 to 100, and whose grp column increments in steps of one for every five rows. Next, create a simple report layout with a table, showing the values of each column and grouping by the grp column. In the group header and footer, include the same column references. Next, add this custom code:

Dim eval_order As Integer = 0

Public Function show_eval_order() As String
  eval_order = eval_order + 1
  Return eval_order.ToString()
End Function

Display the result of this function in the group header, footer, and detail rows. Your layout should look like this:

Once you have the report set up, click on the preview tab to see the surprising results:

I've only shown the first two groups here, but notice what has happened! The order column clearly indicates that the group header and footer are both evaluated before the details in between! By looking at the value of the id column in the footer, we can see that the the group's header and footer rows are printed while the "current" row in the dataset is still positioned on the first row in the group.

While this is interesting, it isn't very important as long as you stick to using SSRS's built-in aggregation functions. It is only when you attempt to "roll your own" by saving the dataset in your own storage for later reference that you might run into trouble. In my case, I used the following workarounds:

  1. Move calculations that rely on the details having been traversed from the group footer to the following group's header. It's clunky and less intuitive, but that's what SSRS has forced upon us.
  2. For the final group, move the calculation out of the table entirely, and put it into textboxes just below the table. While there is no way to tell SSRS to evaluate the textboxes after it evaluates the table, it does so at least for the 2005 version.

In summary, it sure would have been nice if SSRS would have evaluated group headers and footers after it evaluated the details that each group contains, but since we have clearly demonstrated that it doesn't, we now know what we will have to do in order to make custom report code produce the output we want: by putting those custom calculations into the following group's header, and by putting the final footer calculation outside the table entirely.

posted on May 6, 2007  #    by Adam Anderson  Comments [1]
 Wednesday, May 02, 2007

We recently completed a self-paced tutorial for Telerik RadControls.

You can download the self paced tutorial from the Telerik site at:

http://www.telerik.com/support/self-paced-tutorial.aspx

The tutorial addresses the entire suite of RadControls, AJAX, client-side scripting, and custom data-binding techniques.

posted on May 2, 2007  #    by Noel Rice  Comments [0]
 Tuesday, May 01, 2007

You can support docking in your web applications using Telerik's new control suite "Prometheus".  Prometheus is completely redesigned to use Microsoft's ASP.NET Ajax.  The Prometheus docking controls make it easy to define objects that may be dragged and areas where objects may be dragged to.  With docking support you can create web portal sites, "PageFlake" style web pages (where the user can dynamically add controls and drag them around on the page), or even "post-it notes" can be added to the page.  The current state-of-play is that the controls are in beta and have a few quirks, but the performance is very responsive and the look and feel is also quite good.

To use Prometheus "RadDock" controls first download and install the Microsoft ASP.NET Ajax extensions at http://ajax.asp.net/, then get the free Prometheus beta download at: http://www.telerik.com/products/aspnet-prometheus/download.aspx.  Once installed, create a new project type "ASP.NET AJAX-Enabled Web Application".  BTW, if you try to use the standard ASP.NET web application you will get really interesting results.

Your toolbox will have the new AJAX extension controls, including "ScriptManager".  ScriptManager is the workhorse of Microsoft's ASP.NET Ajax that registers client side scripts that enable AJAX functionality. The ScriptManager is automatically placed on the default web page so you don't need to do anything further there.

Also in the toolbox are the new Prometheus controls.  The three you need for drag and drop support are:

  • RadDock is the container for text or other controls that need to be dragged on the web page.
  • RadDockZone defines an area on the screen where a RadDock can dropped onto.
  • RadDockLayout can contain a number of RadDockZone controls so you can set the skin for everything at once.  RadDockLayout also has a property StoreLayoutInViewState that can be used to persist the RadDock locations across multiple postbacks.

To test these controls drop a RadDockLayout, two RadDockZones within the RadDockLayout and RadDock controls in each of the RadDockZones. 

How about adding content to the RadDock? 

  • Use the Radock Text property for simple text only that doesn't involve any other controls.
  • Create your own ITemplate implementation class and set the RadDock ContentTemplate property to that class in the code behind.
  • Add to the ContentTemplate property markup.  At this stage of development I don't see a smart tag or other UI assistance so instead add a ContentTemplate tag and add controls within the tag.

For example we could add another new Prometheus control "RadColorPicker":

<ContentTemplate>
  <telerik:RadColorPicker ID="RadColorPicker1" runat="server" Preset="Standard">
  </telerik:RadColorPicker>
</ContentTemplate>

To finish up we set the Skin property of RadDockLayout to "Longhorn".  If you've used the current version of RadDock you're used to adding various skin files to the project.  Not with the Prometheus version where the skins are built-in and you can choose the Skin property value from a drop down list.  Finally you can set the title bar text for each RadDock using the Title property.

When you run the Prometheus version of the docking controls you should experience snappy responsiveness and a very respectiable UI.  Try downloading Prometheus and retrofit some part of your current web application to support docking.  Enjoy!

Note: if you want to learn Telerik RadControls from the ground up, check out the Falafel-authored, self-paced tutorial at http://www.telerik.com/support/self-paced-tutorial.aspx and download the sample projects from our community download site at http://www.falafel.com/community/files/Default.aspx.

posted on May 1, 2007  #    by Noel Rice  Comments [1]
 Tuesday, April 17, 2007

You might overlook the JavaScript debugging utility that's already built in to Visual Studio 2005: the Script Explorer window.  The Script Explorer can take care of the usual debugging tasks like stepping through code, adding watches and evaluating variables. 

To use the debugger in Internet Explorer navigate to the browser Tools | Internet Options | Advanced tab and make sure that "Disable script debugging" is turned off. 

Run your web application in Visual Studio 2005.  Then select the menu option for Debug | Windows | Script Explorer.  Notice in the background the tags for telerik RadEditor controls...

The first thing you notice in the Script Explorer window is a series of JavaScript and resource files that are currently loaded.  Double click on the aspx file you're currently working with and you will see the evaluated HTML returned from the server.  The RadEditor control now shows as its computed HTML, CSS and JavaScript that will actually be functioning in the browser. 

You can also navigate up to the script for the page and set breakpoints and watches.  When the JavaScript executes and hits your breakpoint you get all the usual Visual Studio debugging capabilities for free.

Next blog I'll show the excellent "Firebug" debugging utility for Firefox.  Firebug doesn't stop at just JavaScript but works with the entire stack of AJAX related technologies (and has a high cool-factor).

posted on April 17, 2007  #    by Noel Rice  Comments [0]

The Firebug debugger add-in for Firefox handles the entire stack of AJAX related technologies.  Ever wanted to tweak the margins in your style sheet while you watch the changes?  Profile a web page and see a visual representation of when scripts are loading and how big they are?  Watch the XmlHttpRequest (i.e. AJAX) requests move over the wire in real time?  You can do all this in Firebug, and of course you can step through your JavaScript code.  At Falafel we use this tool in our consulting work and telerik recommends Firebug for use in web applications using their RadControl suite.

Firebug is an innovative tool that handles usual tasks you would expect from a combined DOM explorer, AJAX/JavaScript profiler, and JavaScript debugger.  But it combines technologies in a new way that is definitely cool and a lot of fun to use.  This will take a few blogs to talk about in depth, but this should get you started.

Firebug only installs and runs in Firefox.  Get Firefox at http://www.mozilla.com/en-US/firefox if you don't already have it installed.  In Firefox download and install Firebug from http://www.getfirebug.com/Now run any page in Firefox and notice the green checkbox in the lower right hand corner.  Click it to start up Firebug for the page you're on. 

The Console tab is used for logging output.  The logging statements can be embedded in your script or run interactively on the Firebug interactive JavaScript command line.  The image below shows the special "dir" command line API dumping the contents of the "<body>" tag to the console.  A series of "console" commands output with visually helpful icons.  There's more on this tab that will wait for another blog (or jump ahead by checking out the API documentation at http://www.getfirebug.com/docs.html).

If you couldn't wait and are running Firebug right now, try clicking the Inspect button, then move your mouse on a web page.  The HTML and Style tabs will display the corresponding markup in real time as you move.  Click once on the page to stop inspecting.  Notice the crossed out items in the Style window?  The window is showing how styles are cascading and what styles are not in effect.  Try double clicking a style value -- you can edit the value and see the results immediately!  Also notice when your mouse cursor passes over a color or image tag that a thumbnail pops up.  Very smooth...

Try clicking on the Edit button (next to the Inspect button).  You can edit the HTML and see the results.  Feel free to add a completely different tag like the image below reading "Modify HTML on-the-fly!!".

By the way, when you click the refresh button, all changes go away.  The author of this tool, Joe Hewitt, mentions in his talk about the advanced features of Firebug (http://yuiblog.com/blog/2007/01/26/video-hewitt-firebug/) that this version of Firebug is not intended to be an editor, but more of an exploring and auditioning tool. 

Speaking of auditioning new settings, what about style layout settings?  The Layout tab shows the offset, margin, border and padding for each element you select.  In the browser you will see rules and other visual metric devices overlaying the web page.  Now try clicking one of the settings, say top padding for an image as shown below.  You don't have to enter a number off the keyboard.  Instead try the arrow keys to raise and lower values.  That way you can keep your eye on the layout until it's just right.

Firebugs profiling features show you the JavaScript and XHR requests going over the wire.  The example below is a demo using a set of telerik date controls using a RadAjaxManager to AJAX enable the whole process (thanks to John Waters for letting me steal the example).  In the Net tab we can select to see all or only certain traffic.  The image below shows all the JavaScript traffic; when it loads and how big each piece is.  For the web resources that contain images you can pass the mouse over to see thumbnails.  Click the plus sign to get the details like HTTP headers, requests and responses.

If we click the XHR tab we see only traffic initiated by the XMLHttpRequest object.  XMLHttpRequest is a major component of AJAX, so this feature is very important for evaluating web site performance with and without AJAX, tweaking AJAX performance, and even checking XHR traffic for security vulnerabilities. 

Firebug is after all a debugger.  All the capabilities you expect like step over, step into, run to line, step out, conditional breakpoints, watches, and automatic local variable display are there.  The conditional breakpoint window is a nice piece of UI programming in itself (see below).

Note: Thanks to Ramesh Theivendran for letting me steal the code for this XMLHttpRequest demo (I see a pattern forming here). 

This has been the briefest look at a tool that is sure to set the bar for all web debuggers.  In coming blogs I'll show Firebug in more depth, but until then I hope you try it yourself.

 |  |  | 
posted on April 17, 2007  #    by Noel Rice  Comments [1]
 Thursday, April 12, 2007

Ever need to show something in a databound gridview that isn't in your datasource? Don't worry, relax, forget about that datasource. Just create that extra row dynamically.

Lets assume I have a GridView with 2 columns. The first column shows the items on an order,  the second column shows the price of that item and the footer shows the order total.  How would I inject a row that shows the tax?

Something like this in the RowDataBound EventHandler would do the trick:

decimal orderTotal = 0.0m;
decimal tax = 0.0m;
protected void gvOrderDetail_RowDataBound(object sender, GridViewRowEventArgs e)
{
    //TODO: Calculate the orderTotal and the tax when RowType = DataRow
    if (e.Row.RowType == DataControlRowType.Footer)
    {
        //Create the Row
        GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
        //Add the two Columns
        row.Cells.AddRange(CreateCells());
        //get a reference to the table that holds this row
        Table tbl = (e.Row.Parent as Table);
        //Add the row at the end of the list, but before the footer.
        tbl.Rows.AddAt(gvOrderDetail.Rows.Count + 1, row);

        //Don't forget to account for any changes in the footer. Since we added a row to show the tax,
        //that tax must also be accounted for in our footer. Calculating the orderTotal and the tax
        //is an exercise for the reader.
        Label lbl;
        lbl = (Label)e.Row.FindControl("lblTotal");
        lbl.Text = String.Format("{0:C}", (orderTotal + tax));
    }
}

private TableCell[] CreateCells()
{

    TableCell[] cells = new TableCell[2];
    TableCell cell;
    Label lbl;

    //The order item column
    cell = new TableCell();
    lbl = new Label();
    lbl.Text = "Sales Tax";
    cell.Controls.Add(lbl);
    cells[0] = cell;

    //The price column
    cell = new TableCell();
    lbl = new Label();
    lbl.Font.Bold = true;
    lbl.Text = tax.ToString("C");
    cell.HorizontalAlign = HorizontalAlign.Right;
    cell.Controls.Add(lbl);
    cells[1] = cell;

    return cells;
}

posted on April 12, 2007  #    by Mike Dugan  Comments [1]
 Wednesday, March 21, 2007

I am guessing a lot of people out there are like me and have projects that they started working on in ASP.Net 1.1, and later migrated to 2.0. This blog is about how to move your old files into the brave new world...

One of the neat features with web forms created from scratch in 2.0 is the separation of the Code Behind files into two partial classes: one partial class in a file called formname.aspx.designer.cs, and one in formname.aspx.cs. The designer file is autogenerated and contains declarations of all the form level variables, for instance if you drop a TextBox tbMyTextBox onto your form, it will add a line

System.Web.UI.WebControls.TextBox tbMyTextBox

to your designer file.

The other Code Behind file is the one where you write your code, event handlers, etc. The two partial class files are then combined at compile time into one class.

So, how do I take an old 1.1 Code Behind file and separate it into the two files I would have had if I had created it in 2.0? Well, follow these steps:

1. Go to the aspx (same applies for asxc files) file, and change the Page directive to say CodeFile="formname.aspx.cs" instead of Codebehind="formname.aspx.cs"

2. Go to your Code Behind file and delete all the member control declarations that should be in the designer file, for instance the tbMyTextBox in my example (be careful not to delete any other private member variables you may have interspersed with the generated code).

3. Still in the old Code Behind file, add partial in front of the class name of the form, for instance

public partial class formname : System.Web.UI.Page

These three steps are sometimes enough for the IDE to kick in and generate your Code Behind file, but if not, you can prod it on its way a little:

4. Create a file called formname.aspx.designer.cs in the same directory as your formnam.aspx.cs, and copy the basic partial class skeleton structure from your code behind (dont include the : System.Web.UI.Page, and use the same namespace as your partial class):

namespace YourNameSpace {

public partial class formname {

   }
}

5. Add this new file to the project (Project, Add Existing Item). It should line up nicely with your Code Behind file under the aspx node in the Solution Explorer.

6. Go back to the aspx file and change the ID of some arbitrary form level control, then hit Save.... change it back and save again. Now look at your empty stub of a partial class again from step 4...TADA! It now contains declarations for all of your form controls (not just the one you changed!).

By the way, if you for some reason want to declare a member control differently from the way the designer autogenerates it, you can just move it from the generated file back into your file and change for instance the visibility of the variable. The generator checks for existing declarations before it adds them to the generated file (hence step 2 above).

I know this is a tad tedious, I wish there was a wizard, but at least you now know how to make the conversion manually.

posted on March 21, 2007  #    by John Waters  Comments [2]
 Monday, January 29, 2007

A couple of days ago I tried to uninstall Telerik's r.a.d.controls 2006 SP3, and the uninstall ran forever before finally failing with an error code. I logged a support ticket and was told that the uninstaller wasn't yet compatible with Vista, but was given a workaround that you might want to know about...

Apparently there is a Microsoft Utility called the Windows Installer Cleanup Utility. You can download it here. It doesn't uninstall programs, but it cleans up their footprint in the installer database and registry. You can then delete the installed files manually and the offending software at least looks like it's gone. Of course, using this brute force method, some things don't get uninstalled, but at least it cleans up somewhat.

If you use this utility, run it before you delete the physical files. It seems that you cant do it the other way round.

posted on January 29, 2007  #    by John Waters  Comments [1]

I have been developing ASP.net Web Applications with Visual Studio 2005 on Windows Vista for a month or so now, and it kind of works. But I have been looking forward to the Visual Studio 2005 SP1, so I was excited to see that Windows Update had tried to install it last night. The install failed, but I set out to figure out what it would take to get it to work on Vista...

The Service Pack can be downloaded manually here. I fetched it and ran it to see what the problem was. It ended up showing me an error box, saying that if I had installed support for Web Application Projects, then I needed to uninstall it before installing the Service Pack, as Web Application Projects are now an integral part of VS 2005 development. I had indeed done that, so I went to the control panel, uninstalled Web Application Projects, and then tried again. Bingo! This time it installed.

Next, I fired up Visual Studio to see if my Web Application Projects would still work. However, I didn't get far - Visual Studio immediately informed me that I needed to get the Visual Studio 2005 Vista SP1. Here is how it is described on the page where you download the regular SP:

"For developers using Visual Studio 2005 on Windows Vista, Microsoft is in current development on an update to Service Pack 1 called the ‘Visual Studio 2005 SP1 Vista Refresh Beta’. This update builds on the improvements made in SP1 and delivers a first class experience for developers wanting to take advantages of the new features in Windows Vista. The Visual Studio 2005 SP1 Update for Windows Vista is expected to ship after the consumer availability of Windows Vista in Q1 of 2007 and is now available in beta."

Wel, I dont have the patience to wait for this to RTM, so I figured I would install the beta. You can get it here.

I went ahead and downloaded the beta. The installation instructions state "On Vista, ensure UAC is turned on". I have turned UAC off, it is the most annoying thing Microsoft created since the Office Paper Clip. But I didnt want to mess up the install, so I turned it back on (which requires a reboot), and then installed the beta (you need to run it as Administrator). That went smoothly, so I turned UAC off again, rebooted, and then started Visual Studio. Cool! No warning messages this time!

Now it was time to see if I could still load my Web Application Projects, so I selected a solution to open and.... it didnt work! Visual Studio told me that I had to install something called "IIS 6 Metabase and IIS 6 Configuration Compatibility". I googled that phrase and ended up on this page. It is a good resource that tells you all the steps needed to run Web Application Projects with IIS (not the built in Development Web Server). One of the steps is to turn on the above mentioned compatibility setting, which you do from the Control Panel, the procedure is well described in the page mentioned above. So, I turned on the compatibilty and tried again!

Lo and behold, this time it worked! As of now, I am back to developing, running and debugging Web Application Projects in Visual Studio against my local IIS, but now with SP1 and the Vista SP1 beta...

posted on January 29, 2007  #    by John Waters  Comments [0]
 Wednesday, December 27, 2006
One way you might want to customize your Sharepoint home page is to add your company logo to an "Image" web part displayed on the page - in fact, the team site template comes with a "site image" preconfigured on the page. You can change the image presented here by putting the page into edit mode, then edit the "Site Logo" web part, and select the logo. It can be any logo, accessible from anywhere, of any recognized graphic type. Very flexible.
 
And then they turn right around and bite you in the butt, because if you have a logo on your local machine, and you want to use it as the site logo, how the heck do you load it up onto the server? I poked around for a while looking for something that would let me transfer a file up to the server and specify where I wanted it to end up, but had to finally connect to the server by mapping a network drive, and copy the file into the default file location. And oh yeah, you'd better know where the file goes and/or where you placed it, because when you click on the button with the ellipses (...), don't think you're going to find a file open dialog - nope. All you get is a bigger text box into which you can type the logo's path.
 
Our company logo is a JPG file about 450 kb in size, and in its natural state, the image is something like 2109 x 1398 pixels. Too big to fit onto a normal screen, much less squeeze down into a reasonable-sized corner of the screen like you might want for a company logo on a home page. So - when you put in the path to the JPG, there are two possibilities for resizing the logo, both of which sound promising. The options presented for the question "Should the WebPart have a fixed height" are "Yes" (with an option for entering the size in pixels, picas, points, inches, etc), and the second is "No. Adjust height to fit zone". There are corresponding entries for the width. If you pick yes, and enter a reasonable size in pixels (120 x 80), what you get is a logo-sized area with scrollbars which permit you to scroll across the entire 2109 x 1398 pixels. Not very useful. OK, let's choose "No", and let the image be adjusted to fit the zone. Or not - all this choice does is adjust the zone size to fit the image. In other words, the "Site Logo" web part becomes huge, so instead of getting a shrunken logo displayed in a reasonable-sized area, the area baloons up, the logo is displayed full size, and you can now scroll the entire web page using the sdcroll bars on the browser if you want to see the whole thing.
 
Aargh. All I found to do was to edit and re-save the JPG as a smaller size, then use that logo.
posted on December 27, 2006  #    by Rick Miller  Comments [1]
 Saturday, September 16, 2006

If you have a BoundField in a GridView that displays a datetime, but you only want to display the date, how would you go about doing that?

Set the DataFormatString to "{0:d}" ?

That is what I thought too. Turns out, this doesn't always work.
That is because by default the value is extracted from the data store, HtmlEncoded, and then the format string is applied. After HtmlEncoding,  the format string won't do anything. The fix in most cases, is usually pretty simple. Just turn off HtmlEncoding for that field by setting HtmlEncode="false".
If you can't turn off HtmlEncoding, it looks like there is some custom formating in your future.

posted on September 16, 2006  #    by Mike Dugan  Comments [0]
 Wednesday, August 16, 2006

If you add an item using the indexer, like this:

Cache["TestItem"] = value;

The item is added to the cache with no expiration policy and a normal priority. As a result, the item will stick around indefinitely.
We can help the cache decide which items to toss out of memory by specifying an expiration policy and/or a priority:

Cache.Insert("TestItem", value, null, Cache.NoAbsoluteExpiration,
  TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null)

Above, I gave the item a 20 minute sliding expiration. This means each time the item is accessed, its 20 minute lease on life is renewed.
I could have told it to expire after exactly 20 mins, no matter how many times it is accessed by setting an absolute expiration instead:

Cache.Insert("TestItem", value, null, DateTime.Now.AddMinutes(20),
  Cache.NoSlidingExpiration, CacheItemPriority.Normal, null)

And to really take control of the scavenging mechanism, you can change the priority of items added to the cache. Lower priority, means it is removed first when system resources are running low. The values range from "Low" to "NotRemovable". See the CacheItemPriority type's documentation for all of the values.

You will also notice that the Cache has an "Add" method. If you choose to use the Add method, adding a key that already exists in the cache will result in an exception, while doing the same with the Insert method will overwrite it. Setting a value using the indexer is equivalent to this call:

Cache.Insert("TestItem", value, null, Cache.NoAbsoluteExpiration,
  Cache.NoSlidingExpiration, CacheItemPriority.Normal, null)

posted on August 16, 2006  #    by Mike Dugan  Comments [1]
 Wednesday, May 31, 2006

There is a cool new feature in ASP.NET 2.0 that allows you to embed resources into your server side assemblies and have your web controls request these resources automatically. This is especially handy when you want to deploy a new control. No longer do you have to find just the right spot to place the JavaScript and image files that your control depends on. 

Microsoft already uses this technique with its validators. The JavaScript needed for client side validation is embedded in one of the .NET assemblies on the server. If you were to view the source of any web page that uses a validator in ASP.NET 2.0, you might see something like this:

<script src="/MyWebSite/WebResource.axd?d=68d8KT0ikvX6J4c8Z8zwvfZXzPdyyYYY8TuccizWlCePFWz&t=632847500868593750" type="text/javascript"></script>

This is a request to a new HttpHandler, WebResources.axd, for the necessary JavaScript. The first parameter, ‘d’ is an encrypted identifier telling the handler which resource it needs. The ‘t’ parameter is an encrypted timestamp, used to determine if the resource has changed.

Looks pretty simple right?

Well, lets see how easy it is for you to use this technique. Lets try to create a control that has its JavaScript embedded as a resource. For this example, I am going to use a useful script that buffers key presses and matches an entire word in a dropdownlist instead of just the first character. (Thanks to Jonathan Cogley at ASP Alliance for the original script: http://authors.aspalliance.com/thycotic/articles/view.aspx?id=3)

First, lets open up or create a new web site in Visual Studio 2005 and then add a new Web Control Library project to it. After adding the project, remember to add a reference to it from our web site.  This new assembly will contain all of the elements of our control and our web site has to know about it to use it.

Next, lets add a new class that inherits from DropDownList:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;


 

namespace WebControlLibrary1
{
    public class KeyedDropDownList : DropDownList
{
        private bool _caseSensitive = false;

        public KeyedDropDownList(){}

    
     public bool CaseSensitive
     {
     get
     {
     return _caseSensitive;
     }
     set
     {
     _caseSensitive = value;
     }
     }
    }
}

I have also added a property “CaseSensitive” which will be passed to the script to allow us to turn on and off case sensitivity when matching strings in our list.

Now add a new a JScript file and examine the properties. To embed this file as a resource the Build Action must be set to 'Embedded Resource'.  After setting the build action,  feel free to copy this code into the file or substitute JavaScript of your own:

function KeyedDropDownList_onkeypress(dropdownlist,caseSensitive) 
{
// check the keypressBuffer attribute is defined on the dropdownlist
var undefined;
if (dropdownlist.keypressBuffer == undefined)
   {
dropdownlist.keypressBuffer = '';
}
   // get the key that was pressed
var key = String.fromCharCode(window.event.keyCode);
dropdownlist.keypressBuffer += key;
  if (!caseSensitive)
   {
// convert buffer to lowercase
dropdownlist.keypressBuffer = dropdownlist.keypressBuffer.toLowerCase();
}
  // find if it is the start of any of the options
var optionsLength = dropdownlist.options.length;
for (var n=0; n < optionsLength; n++)
{
var optionText = dropdownlist.options[n].text;
if (!caseSensitive)
     {
optionText = optionText.toLowerCase();
  }
if (optionText.indexOf(dropdownlist.keypressBuffer,0) == 0)
     {
dropdownlist.selectedIndex = n;
return false; // cancel the default behavior since
// we have selected our own value
     }
}
// reset initial key to be inline with default behavior
dropdownlist.keypressBuffer = key;
return true; // give default behavior
}

Next,  you must add an attribute to the assemblyinfo.cs file to reference the embedded resource:

[assembly: System.Web.UI.WebResource("WebControlLibrary1.JScript1.js", 
"text/javascript")]

You will notice that the reference to the JScript file is fully qualified. You must do this using the project's default namespace, not just any old namespace in the assembly. You can see this  by right clicking on the project and viewing the properties. I should also mention that we intentionally left out an optional boolean parameter named 'PerformSubstitution'. By default 'PerformSubstitution' is off, and you should turn it on if the referenced resource accesses other embedded resources. An embedded style sheet that defines some style using an embedded image is a good example of when to set PerformSubstitution to true.

Now, instead of registering the script block with the necessary JavaScript ourselves, we will register a request to get the script block from our  assembly.  Thanks to the new ClientScriptManager in ASP.NET 2.0, this is  very easy.  We will first override the OnInit method of our KeyedDropDownList class and then  get a reference to this manager to do most of our work.

protected override void OnInit(EventArgs e)    
{
base.OnInit(e);
ClientScriptManager cs = Page.ClientScript;
Type rsType = this.GetType();
cs.RegisterClientScriptInclude("MyScript",
cs.GetWebResourceUrl(rsType,"WebControlLibrary1.JScript1.js"));
}

The last piece of coding is very simple.  Just attach  the onkeypress event of our control to our custom JavaScript function.  Although in this example we have not used the ViewState to track our lone property,  we might want to do that or add more properties that can be passed to the JavaScript function.  So here I overrode the OnLoad method to add the attribute to our webcontrol. By the time the OnLoad event is fired, the ViewState will have been  loaded.

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.Attributes.Add("onkeypress",
"return KeyedDropDownList_onkeypress(this," +
_caseSensitive.ToString().ToLower() + ")");
}

If all goes well, we should be able to now use this control on any form in our web app and the necessary JavaScript will automatically accompany it wherever it goes. I should also point out that when debugging, the JavaScript is not cached, it is downloaded each time. When debugging is off, the JavaScript is cached on the client automatically. 

I have  included the markup for the test page that registers and uses this new control below.

<%@ Page Language="VB" AutoEventWireup="false"
CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="WebControlLibrary1"
Namespace="WebControlLibrary1" TagPrefix="wcl" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Test Page</title>
</head>
<body>
<form id="form1" runat="server">
<wcl:KeyedDropDownList id="ddlTest" runat="server">
<asp:ListItem Value="1">Calendar</asp:ListItem>
<asp:ListItem Value="2">Can</asp:ListItem>
<asp:ListItem Value="3">Candle</asp:ListItem>
<asp:ListItem Value="4">Canary</asp:ListItem>
<asp:ListItem Value="5">Card</asp:ListItem>
<asp:ListItem Value="6">Cat</asp:ListItem>
<asp:ListItem Value="7">Cow</asp:ListItem>
</wcl:KeyedDropDownList>
</form>
</body>
</html>
posted on May 31, 2006  #    by Mike Dugan  Comments [1]
 Friday, March 31, 2006

In .NET 1.1 we always had a problem using the built in Mail class in the System.Net namespace whenever the mail server was on a different server than the authenticating web server because it lacked the authentication feature to the SMTP that allows for this to be transfered correctly.  So we always ended up using a 3rd party component like ASPNETEMAIL which worked pretty well for us.
With the release of .NET 2.0 obviously Microsoft worked on that feature and added the authentication feature to the Mail class. 
This is simple code to show how easy now it is to make this work in .NET 2.0

1 System.Net.Mail.MailMessage Email = new System.Net.Mail.MailMessage ("spamMe@falafel.com", "SpamThis@falafel.com");
2 Email.Subject = "test subject";
3 Email.Body = "this is a test";
4 System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient();
5 //This object stores the authentication values
6 System.Net.NetworkCredential basicAuthenticationInfo = new System.Net.NetworkCredential ("username", "password");
7 mailClient.Host = "mail.falafel.com";
8 mailClient.UseDefaultCredentials = false;
9 mailClient.Credentials = basicAuthenticationInfo;
10 mailClient.Send(Email);
posted on March 31, 2006  #    by Lino Tadros  Comments [0]

When paging just won't cut it, scrollbars come in handy. Fortunately, it is quite easy to add scrolling support to just about anything. All you need to do is wrap any of your controls in an HTML DIV tag.

The key to the code below is to set the DIV style to "OVERFLOW: auto;" and specify a size. When overflow is set to auto, scrollbars will automatically appear if  the control size exceeds the DIV's dimensions. The code below binds a datagird to the Order table in the Northwind database. This would normally produces a pretty large datagrid, but thanks to our DIV, we will only see a subsection of the data.

<DIV style="OVERFLOW: auto; WIDTH: 550px; HEIGHT: 200px">
<asp:datagrid id=DataGrid1 runat="server" DataSource="<%# dataView1 %>"
AutoGenerateColumns="False" ShowHeader="False">
<Columns>
<asp:BoundColumn DataField="OrderID"></asp:BoundColumn>
<asp:BoundColumn DataField="ShippedDate"></asp:BoundColumn>
<asp:BoundColumn DataField="ShipName"></asp:BoundColumn>
<asp:BoundColumn DataField="ShipCity"></asp:BoundColumn>
</Columns>
</asp:datagrid>
</DIV>
posted on March 31, 2006  #    by Mike Dugan  Comments [1]
 Wednesday, March 29, 2006

Given an array of bytes containing the file data, a MIME type, and a file name:

public void DownloadBytes( byte[] bytes, string mimeType, string fileName )
{
  Response.ContentType = mimeType;
  Response.AppendHeader( "Content-Disposition", "attachment;filename=" + fileName );
  Response.BinaryWrite( bytes );
  Response.Flush();
  Response.End();
}

posted on March 29, 2006  #    by Adam Anderson  Comments [1]
 Friday, January 27, 2006

The MSDN Library says this about the DataGrid.Items property:

"Only items bound to the data source are contained in the Items collection. The header, footer, and separator are not included in the collection."

So how do we get to these other items? Most people handle the ItemCommandEvent for the grid, but there is a way to access them directly.

If these items are not in the DataGrid.Items collection, then where are they? To find out, turn on tracing for your ASP.NET webpage. You will see that the grid is rendered something like this:

DataGrid
   DataGridTable
      DataGridItem
         TableCell
         TableCell
      DataGridItem
         TableCell
         LiteralControl
         Label
      DataGridItem
      ...

What we are seeing is that the first object in the DataGrid's Control hierarchy is a DataGridTable. That DataGridTable contains ALL of the DataGridItems, including the header and footer. To get these DataGridItems we just need to grab the first or last control out of the DataGridTable's control collection.

So to get a DataGrid's footer, this code will do this trick:

//First get the DataGridTable (the first control in DataGrid's control collection.)
//Then grab the last control in the DataTable's Collection
DataGridItem footer = 
    DataGrid1.Controls[0].Controls[DataGrid1.Controls[0].Controls.Count -1] as DataGridItem;
posted on January 27, 2006  #    by Mike Dugan  Comments [1]